Activty与Service通信的所有情况(相同进程、不同进程)
来源:互联网 发布:封面制作软件下载 编辑:程序博客网 时间:2024/06/08 13:43
一、相同进程
当Acitivity和Service处于同一个Application和进程时,通过继承Binder类来实现。
当一个Activity绑定到一个Service上时,它负责维护Service实例的引用,允许你对正在运行的Service进行一些方法调用。比如你后台有一个播放背景音乐的Service,这时就可以用这种方式来进行通信。
代码如下:
/*************************Service代码****************************************/public class LocalService extends Service { private final IBinder binder = new LocalBinder(); public class LocalBinder extends Binder { LocalService getService() { return LocalService.this; } } public IBinder onBind(Intent intent) { return binder; }
public int getRandomNumber() {
return 0;
}} /*****************************Activity代码*************************************/public class BindingActivity extends Activity { LocalService localService; private ServiceConnection mConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className,IBinder localBinder) { localService = (LocalBinder) localBinder.getService(); } public void onServiceDisconnected(ComponentName arg0) { localService = null; } }; protected void onStart() { super.onStart(); Intent intent = new Intent(this, LocalService.class); bindService(intent, mConnection, Context.BIND_AUTO_CREATE); } protected void onStop() { super.onStop(); unbindService(mConnection); } public void printRandomNumber{ int num = localService.getRandomNumber(); //直接调用Service你的方法即可 System.out.println(num); }}
代码解释:
使用使用context.bindService()启动Service会经历:
context.bindService()->onCreate()->onBind()->Service running
onUnbind() -> onDestroy() ->Service stop
Activity能进行绑定得益于Service的接口onBind()。Service和Activity的连接可以用ServiceConnection来实现,需要实现一个新的ServiceConnection,重写onServiceConnected和onServiceDisconnected方法。执行绑定,调用bindService方法,传入一个选择了要绑定的Service的Intent(显式或隐式)和一个你实现了的ServiceConnection实例。一旦连接建立,你就能通Service的接口onBind()得到serviceBinder实例进而得到Service的实例引用。一旦Service对象找到,就能得到它的公共方法和属性。但这种方式,一定要在同一个进程和同一个Application里,虽然也是在Activity里通过Binder得到Service对象的。
二、不同进程之间
1、使用Messenger
上面的方法只能在同一个进程里才能用(),如果要与另外一个进程的Service进行通信,则可以用Messenger。
其实实现IPC(Inter-Process Communication,进程间通信)的方式,还有AIDL,但推荐使用Messenger,有两点好处:
1. 使用Messenger方式比使用AIDL的方式,实现起来要简单很多
2. 使用Messenger时,所有从Activity传过来的消息都会排在一个队列里,不会同时请求Service,所以是线程安全的。如果你的程序就是要多线程去访问Service,就可以用AIDL,不然最好使用Messenger的方式。
不过,其实Messenger底层用的就是AIDL实现的,看一下实现方式,先看Service的代码:
- public class MessengerService extends Service {
- /** 用于Handler里的消息类型 */
- static final int MSG_SAY_HELLO = 1;
- /**
- * 在Service处理Activity传过来消息的Handler
- */
- class IncomingHandler extends Handler {
- @Override
- public void handleMessage(Message msg) {
- switch (msg.what) {
- case MSG_SAY_HELLO:
- Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
- break;
- default:
- super.handleMessage(msg);
- }
- }
- }
- /**
- * 这个Messenger可以关联到Service里的Handler,Activity用这个对象发送Message给Service,Service通过Handler进行处理。
- */
- final Messenger mMessenger = new Messenger(new IncomingHandler());
- /**
- * 当Activity绑定Service的时候,通过这个方法返回一个IBinder,Activity用这个IBinder创建出的Messenger,就可以与Service的Handler进行通信了
- */
- @Override
- public IBinder onBind(Intent intent) {
- Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
- return mMessenger.getBinder(); //这里返回Messenger
- }
- }
再看一下Activity的代码:
- public class ActivityMessenger extends Activity {
- /** 向Service发送Message的Messenger对象 */
- Messenger mService = null; //是Messenger而不是Service
- /** 判断有没有绑定Service */
- boolean mBound;
- private ServiceConnection mConnection = new ServiceConnection() {
- public void onServiceConnected(ComponentName className, IBinder service) {
- // Activity已经绑定了Service
- // 通过参数service来创建Messenger对象,这个对象可以向Service发送Message,与Service进行通信
- mService = new Messenger(service);
- mBound = true;
- }
- public void onServiceDisconnected(ComponentName className) {
- mService = null;
- mBound = false;
- }
- };
- public void sayHello(View v) {
- if (!mBound) return;
- // 向Service发送一个Message
- Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
- try {
- mService.send(msg);
- } catch (RemoteException e) {
- e.printStackTrace();
- }
- }
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- @Override
- protected void onStart() {
- super.onStart();
- // 绑定Service
- bindService(new Intent(this, MessengerService.class), mConnection,
- Context.BIND_AUTO_CREATE);
- }
- @Override
- protected void onStop() {
- super.onStop();
- // 解绑
- if (mBound) {
- unbindService(mConnection);
- mBound = false;
- }
- }
- }
注意:以上写的代码只能实现从Activity向Service发送消息,如果想从Service向Activity发送消息,只要把代码反过来写就可以了。
2、使用AIDL
AIDL,Android Interface Definition Language。建立AIDL服务要比建立普通的服务复杂一些,具体步骤如下:
- Activty与Service通信的所有情况(相同进程、不同进程)
- Activity与Service通信(不同进程之间)
- Activity与Service通信(不同进程之间)
- Activity与Service通信(不同进程之间)
- Activity与Service通信(不同进程之间)
- Activity与Service通信(不同进程之间)
- aidl详解:同一APK内,不同apk间的activty与service通信
- Service与Activity之间的通信(同一进程)binder
- 关于service 与 activty 之间通信
- Activity与Service通信(同进程之间)
- Android中的Service与进程间通信(IPC)详解
- Android中的Service与进程间通信(IPC)详解
- activty与service交互
- 进程与进程通信
- android service的调用、进程内与进程间的通信
- 不同的进程之间的通信方式
- 主进程与子进程的通信(handler)
- 应用进程与系统进程的通信(IActivityManager & IApplicationThread)
- c++类模版和运算符重载的运用
- Linux下C++的的开发和调试运行工具
- HBase总结(十八)Hbase rowkey设计一
- ExtJs开发-入门篇
- 用bootstrap实现表格隔行变色,hover 变色并在需要时出现滚动条
- Activty与Service通信的所有情况(相同进程、不同进程)
- MySQL数据库引擎介绍、区别、创建和性能测试的深入分析
- WP_Query的使用方法
- rhel中定时任务cron解析
- Python生成文件md5校验值函数
- VelocityTracker简介
- 【最小割】【poj 3469】 Language
- 线程模型
- linux驱动——并发控制