Activity和Service双向通信

一、同进程

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

你可能感兴趣的:(Activity和Service双向通信)