美文网首页移动开发程序员Android开发
使用Handler实现Activity和Service之间的交互

使用Handler实现Activity和Service之间的交互

作者: Sanisy | 来源:发表于2016-06-09 22:55 被阅读6306次

    在开发应用的时候,我们有时候需要Service来处理后台任务。同时需要两者之间的实时交互,比如说下载的时候我们需要实时地更新Notification的下载进度。我们可以通过BroadcastReceiver来实现Service和Activity的交互,但是今天我们来介绍另外一种实现方法。使用Handler实现Activity和Service之间的交互。

    实现的原理:

    1.在Service中的onCreate方法中创建Service端的Handler和Messenger对象,并且在handleMessage方法中获取Activity端的Messenger

    2.在Service的onBind方法中返回Messenger的Binder对象

    3.在Activity中创建一个Handler对象,用来处理消息

    4.在Activity中创建一个ServiceConnection对象,并且在onServiceConnected方法中,获取Service端的Messenger对象

    5.在Activity创建Messenger,并封装在Message中传递给Service端

    文字不理解可以看图并结合代码来思考

    原理图
    public class MessengerService extends Service{
    
        private Messenger mActivityMessenger;
    
        private Handler handler;
    
        private Messenger mServiceMessenger;
    
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i("TAG", "onCreate()");
    
            /**
             * HandlerThread是Android系统专门为Handler封装的一个线程类,
               通过HandlerThread创建的Hanlder便可以进行耗时操作了
             * HandlerThread是一个子线程,在调用handlerThread.getLooper()之前必须先执行
             * HandlerThread的start方法。
             */
            HandlerThread handlerThread = new HandlerThread("serviceCalculate");
            handlerThread.start();
    
            
            handler = new Handler(handlerThread.getLooper()){
                @Override
                public void handleMessage(Message msg) {
                    if(msg.what == 0x11){
    
                        if(mActivityMessenger == null) {
                            mActivityMessenger = msg.replyTo;
                        }
    
                        //模拟耗时任务
                        try {
                            Thread.sleep(10000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
    
    
                        //发送结果回Activity
                        Message message = this.obtainMessage();
                        message.what = 0x12;
                        message.arg1 = msg.arg1 + msg.arg2;
                        try {
                            mActivityMessenger.send(message);
                        } catch (RemoteException e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
    
            mServiceMessenger = new Messenger(handler);
        }
    
        @Override
        public IBinder onBind(Intent intent) {
            Log.i("TAG","onBind()");
            return mServiceMessenger.getBinder();
        }
    }
    
    public class ScrollingActivity extends AppCompatActivity {
        private Button sendToServiceBtn;
    
        //Service端的Messenger对象
        private Messenger mServiceMessenger;
    
        //Activity端的Messenger对象
        private Messenger mActivityMessenger;
    
        /**
         * Activity端的Handler处理Service中的消息
         */
        private Handler handler = new Handler(){
            @Override
            public void handleMessage(Message msg) {
                if(msg.what == 0x12){
                    Toast.makeText(ScrollingActivity.this, "Service发送过来的结果是......"
            + msg.arg1,Toast.LENGTH_SHORT).show();
                }
            }
        };
    
        /**
         * Service绑定状态的监听
         */
        private ServiceConnection connection = new ServiceConnection() {
            @Override
            public void onServiceConnected(ComponentName name, IBinder service) {
                //获取Service端的Messenger
                mServiceMessenger = new Messenger(service);
            }
    
    
            @Override
            public void onServiceDisconnected(ComponentName name) {
    
            }
        };
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_scrolling);
    
            sendToServiceBtn = (Button) findViewById(R.id.btn_sendToService);
            sendToServiceBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //Activity端的Messenger
                    if(mActivityMessenger == null) {
                        mActivityMessenger = new Messenger(handler);
                    }
    
    
                    //创建消息
                    Message message = Message.obtain();
                    message.what = 0x11;
                    message.arg1 = 2016;
                    message.arg2 = 1;
    
                    //设定消息要回应的Messenger
                    message.replyTo = mActivityMessenger;
    
                    try {
                        //通过ServiceMessenger将消息发送到Service中的Handler
                        mServiceMessenger.send(message);
                    } catch (RemoteException e) {
                        e.printStackTrace();
                    }
                }
            });
    
            //绑定Service
            Intent intent = new Intent(ScrollingActivity.this, MessengerService.class);
            bindService(intent, connection, Service.BIND_AUTO_CREATE);
    
        }
    
    }
    

    接下来几篇文章会介绍Message MessageQueue Looper Handler的流程和源代码

    相关文章

      网友评论

        本文标题:使用Handler实现Activity和Service之间的交互

        本文链接:https://www.haomeiwen.com/subject/whxsdttx.html