Android中Activity与Service的双向通讯
2015-11-11 23:48
447 查看
1. Activity与本地Service的双向通讯
Activity和本地的Service都是在主线程中,是两个组件(对象)。所以本质上来讲,Activity和本地Service之间其实是同一个进程(主线程)内对象之间的通讯,而不涉及任何跨进程的东西。对象之间的通讯,抽象出来就是对象A与对象B之间通讯,通讯方式是A持有B的实例即可。Activity和本地service之间的通讯即是Activity在绑定的时候获得被绑定Service的实例,然后即可在Activity中对Service进行调用。
那Service如何主动向Activity进行消息传递呢?由于Activity与Service同属与主线程,主线程只有一个消息队列MessageQueue,那么只要通过Handler即可。具体来讲:
Activity中定义Handler activityHandler,绑定Service后将activityHandler传递到Service;Service中定义Handler serviceHandler,Activity持有了Service的实例,自然可以获得该serviceHandler。原理图即:
图1,主线程中的Activity持有Service实例,共享主线程的消息队列
通讯方式:
Activity→Servic:通过serviceHandler发送Message,service中定义的serviceHandler会处理该消息;
Service→Activiy:通过activityHandler发送消息,Activity中固定翼的activity会处理该消息。
2. Activity与Service的跨进程双向通讯
在AndroidManifest.xml中配置Service时:<service android:name="RemoteService" android:process=":remote">
这样,该Service就属于新的进程。跨进程通讯采用Binder机制,比较复杂。抽象来讲就是,进程A与进程B在内存空间中属于不连续的区域,需要操作系统作为中介获得彼此的相对地址。这时候进程A与进程B通讯采用Messenger。
具体来讲,Activity中定义Messenger activityMessenger,Messenger在定义的时候封装该进程的一个Handler acitivityHandler,acitivityHandler中包括了消息处理的回调函数。Service中也定义Messenger serviceMessenger,初始化时也封装了该进程的一个Handler serviceHandler,serviceHandler中包括了消息处理的回调函数。原理图:
图2,两个进程交换Messenger(封装了各自的Handler)
通讯方式:
Activity→Servic:通过serviceMessenger发送Message,service中定义的serviceHandler会处理该消息;
Service→Activiy:通过activityMessenger发送消息,Activity中定义的activity会处理该消息。
附件是我写了个ThreadTest来测试了以上的内容。MainActivity定义了绑定了本地的Service和远程的Service。
下面是函数部分:
/** * Activity绑定了两个Service: * <p>主线程的LocalService:持有其实例,并将handler句柄传递过去</p> * <p>新进程的RemoteService:持有定义在RremoteService中的mRemoteMessenger,其中包含了定义在RremoteService的Handler。 * 通过mRemoteMessenger可以将主线程的消息发送到新进程.将主线程中的mLocalMessenger封装为一个消息通过mRemoteMessenger发送到新进程,这样新进程就可以通过mLocalMessenger向主线程发消息了</p> * */ public class MainActivity extends AppCompatActivity { private Handler activityHandler,serviceHandler;//handler实现同一个线程中的Activity与Service的双向消息处理 private LocalService localService;//Activity通过binder持有localService的实例 private ServiceConnection mLocalConnection,mRemotecConnection ; private boolean mLocalBound,mRemoteBound; private Message message; private Messenger mRemoteMessenger ,mLocalMessenger;//Messenger实现不同进程的Activity与Service的双向消息处理 public static final int LOCAL_MESSENGER=0X000; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initHandler(); initService(); initThread(); } public void initThread() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(5000*2); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message=serviceHandler.obtainMessage(); message.what=0x101; message.sendToTarget(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message=activityHandler.obtainMessage(); message.what=0x102; message.sendToTarget(); try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message=new Message(); message.what=0x103; try { mRemoteMessenger.send(message); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Intent localintent = new Intent(this, LocalService.class); bindService(localintent, mLocalConnection, Context.BIND_AUTO_CREATE); Intent remoteIntent=new Intent(this,RemoteService.class); bindService(remoteIntent, mRemotecConnection, Context.BIND_AUTO_CREATE); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); if (mLocalBound) { unbindService(mLocalConnection); mLocalBound=false; } if (mRemoteBound) { unbindService(mRemotecConnection); mRemoteBound=false; } } private void initService(){ mLocalConnection=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub LocalService.LocalBinder localBinder=(LocalService.LocalBinder)service; localService=localBinder.getService(); localService.setHandler(activityHandler);//将本地的handler传给service serviceHandler=localBinder.getHandler();//从service中获得其中的handler mLocalBound=true; } @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mLocalBound=false; } }; mRemotecConnection=new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub mRemoteMessenger=null; mRemoteBound=false; } @Override public void onServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub mRemoteMessenger=new Messenger(service); Message message=new Message(); message.what=LOCAL_MESSENGER; message.obj=mLocalMessenger; try { mRemoteMessenger.send(message); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } mRemoteBound=true; } }; } private void initHandler(){ activityHandler = new Handler() { @SuppressLint("HandlerLeak") @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0x100: Toast.makeText(MainActivity.this, "来自LocalService:0x100,本地处理", Toast.LENGTH_SHORT).show(); break; case 0x102: Toast.makeText(MainActivity.this, "本地:0x103", Toast.LENGTH_SHORT).show(); break; case 0x104: Toast.makeText(MainActivity.this, "来自remoteService:0x104,本地处理", Toast.LENGTH_SHORT).show(); break; } } }; mLocalMessenger=new Messenger(activityHandler);//Messenger的初始化封装了本进程的Handler } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }
/** * 主线程中的service; * <p>Activity→Service:将LocalService和Service中的Handler封装到IBinder,通过binder机制与Activity进行通信,Activity持有LocalService及其Handler的实例.</p> * <p>Service→Activity:Activity持有了LocalService的实例,就将Activity中定义的Handler交给Service.</p> * */ public class LocalService extends Service{ private final IBinder mBinder = new LocalBinder(); private Handler serviceHandler,activityHandler;//主线程的Handler在service中的句柄 private Message message;//Service中的所有消息 /** * 将LocalService封装到IBinder中 * */ public class LocalBinder extends Binder{ LocalService getService(){ return LocalService.this; } Handler getHandler(){ return serviceHandler; } } /** * 接收来自Activity的Handler * */ public void setHandler(Handler handler){ activityHandler=handler; } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); initHandler(); initThread(); } private void initHandler(){ serviceHandler = new Handler() { @SuppressLint("HandlerLeak") @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case 0x101: Toast.makeText(LocalService.this, "消息来自Activity:0x101。在LocalService中处理!", Toast.LENGTH_SHORT).show(); break; } } }; } /** *将IBinder返回 * */ @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return mBinder; } public void initThread() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message=activityHandler.obtainMessage(); message.what=0x100; message.sendToTarget(); } }).start(); } }
/** * Activity绑定了两个Service: * <p>主线程的LocalService:持有其实例,并将handler句柄传递过去</p> * <p>新进程的RemoteService:持有定义在RremoteService中的mRemoteMessenger,其中包含了定义在RremoteService的Handler。 * 通过mRemoteMessenger可以将主线程的消息发送到新进程.将主线程中的mLocalMessenger封装为一个消息通过mRemoteMessenger发送到新进程,这样新进程就可以通过mLocalMessenger向主线程发消息了</p> * */ public class RemoteService extends Service{ private Handler remoteHandler; private Messenger mRemoteMessenger ,mLocalMessenger; private Message message; @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return mRemoteMessenger.getBinder(); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); initHandler(); mRemoteMessenger=new Messenger(remoteHandler); //Messenger的初始化封装了本进程的Handler message=new Message(); initThread(); } @SuppressLint("HandlerLeak") private void initHandler(){ remoteHandler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); switch (msg.what) { case MainActivity.LOCAL_MESSENGER: mLocalMessenger=(Messenger) msg.obj; break; case 0x103: Toast.makeText(RemoteService.this, "来自Activity:0x103,remoteService处理!", Toast.LENGTH_SHORT).show(); break; } } }; } public void initThread() { new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub try { Thread.sleep(5000*4); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message.what=0x104; try { mLocalMessenger.send(message); } catch (RemoteException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } message.what=0x106; try { mLocalMessenger.send(message); } catch (RemoteException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } }).start(); } }
相关文章推荐
- Android之倍数提高工作效率的 Android Studio 奇技
- 【转载常见问题】如何构建项目范围在IntelliJ IDEA UML图吗?
- Android Volley框架使用详解
- Android学习之碎片与活动之间的通信
- Android AsynTask 与Thread 或线程池 使用分析
- Android各个版本API的区别
- Android LayoutAnimation
- 34.Android MVC框架 - Robotlegs4Androird
- android 源码文件结构
- Android中Canvas绘图基础详解(附源码下载)
- Android打包的那些事
- Android Resource Types之Animation简介
- Android内存缓存LruCache
- android 生成 QR_CODE 码 PFD_417码 CODE_36码
- Android环境搭建的那些奇葩问题
- android学习笔记Fragment的使用
- Android 用命令行安装应用到手机
- Android IPC之Messenger和AIDL(android开发艺术探索随笔)
- Android 6.0 运行时权限处理
- TextView中英文排版混乱