天天看點

aidl ( 三) 背景service通知前台activity

在aidl ( 一 ) activity擷取背景service資料文章中提到了,前台activity主動去擷取背景service裡的資料或者調用service裡的方法。那麼背景service是否可以主動通知前台activity呢?比如我背景在計時,我要把時間值顯示在前台界面上。

當然可以了,還是aidl,得再寫一個aidl,把回調設定到service内。

用到的module:aidlServer1,aidlClient1

要想背景service主動通知前台activity,至少要寫2個aidl,2端各寫一個stub,stub本質就是Binder,進一步可學習 http://blog.csdn.net/litefish/article/details/50557977

先寫server端代碼,主要是維護一個service,2個aidl

// IMyAidlInterface.aidl
package com.aidl.server;
import com.example.fish.aidlserver1.ICallback;
// Declare any non-default types here with import statements

interface IMyAidlInterface {
	int getCount();
	double complexCal(String str,int t);
	void setCallback(ICallback call);
}
           
// IAxx.aidl
package com.example.fish.aidlserver1;

// Declare any non-default types here with import statements
//service回調activity
interface ICallback {
   void showTime(int x);
}
           

service代碼如下

package com.example.fish.aidlserver1;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;

import com.aidl.server.IMyAidlInterface;
import com.fishlib.log.LogUtil;
import com.fishlib.util.system.SystemUtil;


public class MyService extends Service {
    private boolean quit;

    private Thread thread;
    private int count;

    @Override
    public void onCreate() {
        super.onCreate();
        LogUtil.thread("service main");
        String TAG="";
        LogUtil.d("onCreate process name " + SystemUtil.getCurProcessName(MyService.this));
        LogUtil.d( "Service is Created");
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // 每間隔100ms count加1 ,直到quit為true
                while (!quit) {
                    try {
                        Thread.sleep(2000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    count++;
                    if(mCallback!=null)
                    {
                        LogUtil.d("callback");
                        try {
                            mCallback.showTime(count);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }else
                    {
                        LogUtil.d("callback null");
                    }
                }
            }
        });
        thread.start();
    }

    @Override
    public void onDestroy() {
        LogUtil.d("onDestroy process name " + SystemUtil.getCurProcessName(MyService.this));
        quit=true;
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        LogUtil.d("onBind process name " + SystemUtil.getCurProcessName(MyService.this));
        return mBinder;
    }
    ICallback mCallback;
    IMyAidlInterface.Stub mBinder = new IMyAidlInterface.Stub() {

        @Override
        public int getCount() throws RemoteException {
            return count;
        }

        @Override
        public double complexCal(String str, int t) throws RemoteException {
            int  ret=str.hashCode()+t;
            return ret*0.3;
        }

        @Override
        public void setCallback(ICallback call) throws RemoteException {
            LogUtil.d("setcallback"+call);
            LogUtil.thread("set callback");
            mCallback=call;

        }
    };

}
           

用戶端代碼

package com.example.fish.aidlclient1;

import android.app.Activity;
import android.app.Service;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.os.RemoteException;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import com.aidl.server.IMyAidlInterface;
import com.example.fish.aidlserver1.ICallback;
import com.fishlib.log.LogUtil;
import com.fishlib.util.system.SystemUtil;

public class MainActivity extends Activity implements View.OnClickListener {


    private Button bindService;

    private Button unbindService;


    private IMyAidlInterface myAIDLInterface;
    private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            LogUtil.d("handleMessage");
            TextView tv = (TextView) findViewById(R.id.textView);
            tv.setText("" + msg.what);


        }
    };
    private ICallback callback = new ICallback.Stub() {
        @Override
        public void showTime(int x) throws RemoteException {
            LogUtil.d("callback" + x);
            LogUtil.process(getApplicationContext());
            LogUtil.thread("showTime");
            handler.sendEmptyMessage(x);
//
        }
    };

    private ServiceConnection connection = new ServiceConnection() {

        @Override
        public void onServiceDisconnected(ComponentName name) {
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            LogUtil.d("process name" + SystemUtil.getCurProcessName(MainActivity.this));
            myAIDLInterface = IMyAidlInterface.Stub.asInterface(service);
            LogUtil.thread("onServiceConnected");
            try {
                int cnt = myAIDLInterface.getCount();
                double db = myAIDLInterface.complexCal("hello world", 6);
                LogUtil.d("result is " + cnt);
                LogUtil.d("complexCal value " + db);

                myAIDLInterface.setCallback(callback);

//                myAIDLInterface.setCallback(new ICallback.Stub() {
//                    @Override
//                    public void showTime(int x) throws RemoteException {
//                        LogUtil.d("callback"+x);
                        TextView tv = (TextView) findViewById(R.id.textView);
                        tv.setText(""+x);
//                    }
//
//                    @Override
//                    public IBinder asBinder() {
//                        return null;
//                    }
//                });
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        LogUtil.thread("main");
        bindService = (Button) findViewById(R.id.bind_service);
        unbindService = (Button) findViewById(R.id.unbind_service);
        Button bv = (Button) findViewById(R.id.get_num);
        bv.setOnClickListener(this);
        bindService.setOnClickListener(this);
        unbindService.setOnClickListener(this);
        Intent intent = new Intent("com.example.servicetest.MyAIDLService");
        startService(intent);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bind_service:
                Intent intent = new Intent("com.example.servicetest.MyAIDLService");
                boolean b = bindService(intent, connection, Service.BIND_AUTO_CREATE);
                LogUtil.d("bind result " + b);
                break;
            case R.id.unbind_service:
                unbindService(connection);

                LogUtil.d("unbind ");
                break;
            default:
                break;
        }

    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        Intent intent = new Intent("com.example.servicetest.MyAIDLService");
        stopService(intent);
    }
}
           

這裡用了2個aidl,其實可以合并成一個,可以參考Project:AidllikeYX, 我們的項目就是這麼寫的,2個程序互相發消息可以參考這個