一、同进程
1、通过bindService获取Service实例
栗子:AActivity与AService
AActivity
private AService aService;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
aService = ((AService.AServiceBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
aService = null;
}
};
AService
private AServiceBinder binder = new AServiceBinder();
@Override
public IBinder onBind(Intent intent) {
return binder;
}
public class AServiceBinder extends Binder {
public AService getService() {
return AService.this;
}
}
得到Service实例,就可以为所欲为。
2、事件总线(比如EventBus)
3、本地广播
二、不同进程
1、Messenger
栗子:BActivity与BService
BActivity
private Messenger remoteMessenger;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
remoteMessenger = new Messenger(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
remoteMessenger = null;
}
};
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case xx: {
//比如更新UI
}
break;
case xx: {
}
break;
}
}
};
private Messenger messenger = new Messenger(handler);
//比如onClick里
if (remoteMessenger != null) {
Message msg = Message.obtain();
msg.what = xx;
msg.replyTo = messenger;
try {
remoteMessenger.send(msg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
BService
@Override
public IBinder onBind(Intent intent) {
return messenger.getBinder();
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case xx: {
Message newMsg = Message.obtain();
newMsg.what = xx;
Bundle bundle = new Bundle();
bundle.putString("xx", "xx");
bundle.putString("xx", "xx");
newMsg.setData(bundle);
try {
msg.replyTo.send(newMsg);
} catch (RemoteException e) {
e.printStackTrace();
}
}
break;
case xx: {
}
break;
}
}
};
private Messenger messenger = new Messenger(handler);
主要就是Activity给Service发message的时候,msg.replyTo设置为自己的messenger。还有,不能传输msg.obj,因为Object没有实现Parcelable,所以都用Bundle来传输。
2、全局广播
3、Binder
CActivity
private INumberManager numberManager;
private ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
numberManager = INumberManager.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
numberManager = null;
}
};
CService
private int num = 0;
private INumberManager.Stub numberManager = new INumberManager.Stub() {
@Override
public int getNum() throws RemoteException {
return num;
}
@Override
public void setNum(int num) throws RemoteException {
CService.this.num = num;
}
};
@Override
public IBinder onBind(Intent intent) {
return numberManager;
}
INumberManager
public interface INumberManager {
int getNum() throws RemoteException;
void setNum(int num) throws RemoteException;
int GET_NUM_TRANSACTION = 1;
int SET_NUM_TRANSACTION = 2;
String DESCRIPTOR = "org.icegeneral.activityservice.INumberManager";
abstract class Stub extends Binder implements INumberManager {
public static INumberManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
INumberManager in = (INumberManager) obj.queryLocalInterface(DESCRIPTOR);
if (in != null) {
return in;
}
return new Proxy(obj);
}
public IBinder asBinder() {
return this;
}
@Override
protected boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
switch (code) {
case GET_NUM_TRANSACTION: {
int result = getNum();
reply.writeInt(result);
return true;
}
case SET_NUM_TRANSACTION: {
int num = data.readInt();
setNum(num);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
}
class Proxy implements INumberManager {
private IBinder remote;
public Proxy(IBinder remote) {
this.remote = remote;
}
@Override
public int getNum() throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
remote.transact(GET_NUM_TRANSACTION, data, reply, 0);
int result = reply.readInt();
data.recycle();
reply.recycle();
return result;
}
@Override
public void setNum(int num) throws RemoteException {
Parcel data = Parcel.obtain();
data.writeInt(num);
data.recycle();
remote.transact(SET_NUM_TRANSACTION, data, null, 0);
}
}
}
Messenger是队列形式,如果有多个客户端连接Service,希望Service更高效运行,那就使用Binder形式(注意同步安全问题)
代码:https://github.com/iceGeneral/ActivityService