Messenger实现Activity与Service的双向通信

Activity与Service间的单向通信,相信大家都知道,常用的有下面3种方式:
1. 通过bindService(service, conn, BIND_AUTO_CREATE)开启Service,然后在ServiceConnection的onServiceConnected回调方法中获取到Service引用,然后我们就可以访问Service中的方法了.
2. 通过broadcast(广播)的形式,当开启的Service接收到了对应的广播,就可以处理预设好的逻辑了.
3. 通过调用类名直接调用Service中定义的静态方法.


今天要将的是解决Activity与Service的双向通信的问题,即Activity可以调用Service中暴露的方法,同时Service也可以调用Activity中暴露的方法.
实现的方式:
Messenger+Handler.
原理:
分别将Activity和Service的引用发送给对方,通过Handler对象来发送引用,在Activity与Service中都定义一个Handler.
关键问题,如何拿到对方的Handler来发送引用?
通过Messenger类,他可以把一个Handler转换成IBinder,也可以把IBinder转换成Messenger.

下面将通过一个Demo来展示Messenger的使用.

目标Activity
public class AudioPlayerActivity extends BaseActivity {

    private AudioPlayerService mAudioPlayerService;

    //Service拿到这个handler就可以与Activity通信了
    private Handler mActivityHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            LogUtils.i(AudioPlayerActivity.this, ">>>>>>>>>>>handleMessage...what=" + msg.what + " obj=" + msg.obj);

            switch (msg.what) {
                case AudioPlayerService.SERVICE_INTERFACE:
                    //获取AudioPlayerService的引用
                    mAudioPlayerService = (AudioPlayerService) msg.obj;
                    mAudioPlayerService.testCallService();
                    break;
            }
        }
    };

    private Messenger mActivityMessenger = new Messenger(mActivityHandler);

    @Override
    protected void setTitleBar(TitleBar titleBar) {
        titleBar.setTitleBarBgResource(R.drawable.base_titlebar_bg);
        titleBar.setLeftIcon(R.drawable.selector_btn_back, new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
        titleBar.setCenterTv("最炫民族风");
    }

    @Override
    protected boolean isHomePage() {
        return false;
    }

    @Override
    public Integer getLayoutResId() {
        return R.layout.activity_audio_player;
    }

    @Override
    public void initView() {

    }

    @Override
    public void initListener() {

    }

    @Override
    public void initData() {
        Intent intent = getIntent();
        if (null != intent) {
            Bundle bundle = intent.getExtras();
            if (null == bundle && bundle.size() < 0) {
                mLoadView.setExceptionViewVisible(true);
            } else {
                //直接把bundle通过参数传到服务中,然后在service中取出来
                Intent service = new Intent(this, AudioPlayerService.class);
                service.putExtras(bundle);
                //先通过start方式开启服务,保证服务能工作在后台
                startService(service);
                //再通过bind的方式开启服务,保证activity能够和service间交互
                bindService(service, conn, BIND_AUTO_CREATE);
            }
        }
    }

    /**
     * 服务连接器
     */
    private ServiceConnection conn = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName name, IBinder binder) {
            LogUtils.i(AudioPlayerActivity.this, ">>>>>>>>>>>onServiceConnected");
            //注意:这里的binder是由AudioPlayerService的mServiceMessenger.getBinder()返回的,因此这里使用binder创建Messenger的话,就可以公用AudioPlayerService的Handler发送消息了.
            Messenger messenger = new Messenger(binder);
            Message msg = Message.obtain();
            msg.what = AudioPlayerService.UI_INTERFACE;
            msg.obj = AudioPlayerActivity.this; //这里将AudioPlayerActivity的引用发送给AudioPlayerService
            msg.replyTo = mActivityMessenger;// 将Activity中的mActivityMessenger传递个Service
            LogUtils.i(AudioPlayerActivity.this, "replyTo>>>>>>>>>>>" + mActivityMessenger);
            try {
                messenger.send(msg);
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            LogUtils.i(AudioPlayerActivity.this, ">>>>>>>>>>>onServiceDisconnected");
        }
    };

    public void updateUI(Audio audio) {
        LogUtils.i(AudioPlayerActivity.this, ">>>>>>>>>>>updateUI");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        unbindService(conn);
    }

    @Override
    public void reLoadData() {

    }

    @Override
    public void onClick(View v) {

    }
}
目标Service
public class AudioPlayerService extends Service {
    public static final int UI_INTERFACE = 0; //获取AudioPlayerActivity引用的message what
    public static final int SERVICE_INTERFACE = 1; //获取AudioPlayerService引用的message what
    private int mPosition;
    private ArrayList<Parcelable> mAudioList;
    private static AudioPlayerActivity mAudioPlayerActivity;
    private static Messenger mActivityMessenger;

    //Activity拿到这个handler就可以与service通信了
    private Handler mServiceHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case UI_INTERFACE:
                    //拿到AudioPlayerActivity的引用
                    mAudioPlayerActivity = (AudioPlayerActivity) msg.obj;
                    mAudioPlayerActivity.updateUI(null);

                    //拿到AudioPlayerActivity的mActivityMessenger对象,来发送消息给mActivityHandler
                    mActivityMessenger = msg.replyTo;
                    Message message = Message.obtain();
                    message.what = SERVICE_INTERFACE;
                    message.obj = AudioPlayerService.this;
                    LogUtils.i(AudioPlayerService.this, "mActivityMessenger>>>>>>>>>>>" + mActivityMessenger);
                    try {
                        mActivityMessenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                    break;
            }
        }
    };
    //创建Messenger对象
    Messenger mServiceMessenger = new Messenger(mServiceHandler);

    @Override
    public void onCreate() {
        LogUtils.i(AudioPlayerService.this, ">>>>>>>>>>>onCreate");
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        LogUtils.i(AudioPlayerService.this, ">>>>onBind");
        return mServiceMessenger.getBinder();//返回一个Binder
    }
    public void testCallService() {
        LogUtils.i(AudioPlayerService.this, ">>>>>>>>>>>testCallService");
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        LogUtils.i(AudioPlayerService.this, ">>>>>>>>>>>onStartCommand");
//        //获取Activity传递过来的数据
        Bundle bundle = intent.getExtras();
        mPosition = bundle.getInt(Constant.KEY_POSITION);
        mAudioList = bundle.getParcelableArrayList(Constant.KEY_LIST);
        LogUtils.i(AudioPlayerService.this, "mPosition:" + mPosition + " mAudioList:" + mAudioList);
        return super.onStartCommand(intent, flags, startId);
    }
}
打印的日志

I/AudioPlayerService: >>>>>>>>>>>onCreate
I/AudioPlayerService: >>>>>>>>>>>onStartCommand
I/AudioPlayerService: >>>>onBind
I/AudioPlayerActivity: >>>>>>>>>>>onServiceConnected
I/AudioPlayerActivity: replyTo>>>>>>>>>>>android.os.Messenger@41a0d208
I/AudioPlayerActivity: >>>>>>>>>>>updateUI
I/AudioPlayerService: mActivityMessenger>>>>>>>>>>>android.os.Messenger@41a0d208
I/AudioPlayerActivity: >>>>>>>>>>>handleMessage…what=1 obj=mchenys.net.csdn.blog.myplayer.module.audio.service.AudioPlayerService@41b072a8
I/AudioPlayerService: >>>>>>>>>>>testCallService

通过上面的日志,可以发现AudioPlayerService成功的调用了AudioPlayerActivity的updateUI方法,同时AudioPlayerActivity也成功的调用了AudioPlayerService的testCallService方法.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值