在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個程序互相發消息可以參考這個