Activity与Service通信的方式有三种:

继承Binder类

这个方式只有当你的Acitivity和Service处于同一个Application和进程时,才可以用,比如你后台有一个播放背景音乐的Service,这时就可以用这种方式来进行通信。

用例子来说明其使用方法:

1. 来看Service的写法:

  1. public class LocalService extends Service {
  2. // 实例化自定义的Binder类
  3. private final IBinder mBinder = new LocalBinder();
  4. // 随机数的生成器
  5. private final Random mGenerator = new Random();
  6. /**
  7. * 自定义的Binder类,这个是一个内部类,所以可以知道其外围类的对象,通过这个类,让Activity知道其Service的对象
  8. */
  9. public class LocalBinder extends Binder {
  10. LocalService getService() {
  11. // 返回Activity所关联的Service对象,这样在Activity里,就可调用Service里的一些公用方法和公用属性
  12. return LocalService.this;
  13. }
  14. }
  15. @Override
  16. public IBinder onBind(Intent intent) {
  17. return mBinder;
  18. }
  19. /** public方法,Activity可以进行调用 */
  20. public int getRandomNumber() {
  21. );
  22. }
  23. }

在Service里定义一个内部类,Binder的子类,通过这个类,把Service的对象传给Activity,这样Activity就可以调用Service里的公用方法和公用属性了,但这种方式,一定要在同一个进程和同一个Application里。

2. 再看相应Activity的代码:

  1. public class BindingActivity extends Activity {
  2. LocalService mService;
  3. boolean mBound = false;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. setContentView(R.layout.main);
  8. }
  9. @Override
  10. protected void onStart() {
  11. super.onStart();
  12. // 绑定Service,绑定后就会调用mConnetion里的onServiceConnected方法
  13. Intent intent = new Intent(this, LocalService.class);
  14. bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
  15. }
  16. @Override
  17. protected void onStop() {
  18. super.onStop();
  19. // 解绑Service,这样可以节约内存
  20. if (mBound) {
  21. unbindService(mConnection);
  22. mBound = false;
  23. }
  24. }
  25. /** 用户点击button,就读取Service里的随机数 */
  26. public void onButtonClick(View v) {
  27. if (mBound) {
  28. // 用Service的对象,去读取随机数
  29. int num = mService.getRandomNumber();
  30. Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
  31. }
  32. }
  33. /** 定交ServiceConnection,用于绑定Service的*/
  34. private ServiceConnection mConnection = new ServiceConnection() {
  35. @Override
  36. public void onServiceConnected(ComponentName className,
  37. IBinder service) {
  38. // 已经绑定了LocalService,强转IBinder对象,调用方法得到LocalService对象
  39. LocalBinder binder = (LocalBinder) service;
  40. mService = binder.getService();
  41. mBound = true;
  42. }
  43. @Override
  44. public void onServiceDisconnected(ComponentName arg0) {
  45. mBound = false;
  46. }
  47. };
  48. }

这里就是通过IBinder来得到LocalService对象,再去调用其Public方法。

使用Messenger

上面的方法只能在同一个进程里才能用,如果要与另外一个进程的Service进行通信,则可以用Messenger。

其实实现IPC的方式,还有AIDL,但推荐使用Messenger,有两点好处:

1. 使用Messenger方式比使用AIDL的方式,实现起来要简单很多

2. 使用Messenger时,所有从Activity传过来的消息都会排在一个队列里,不会同时请求Service,所以是线程安全的。如果你的程序就是要多线程去访问Service,就可以用AIDL,不然最好使用Messenger的方式。

不过,其实Messenger底层用的就是AIDL实现的,看一下实现方式,先看Service的代码:

  1. public class MessengerService extends Service {
  2. /** 用于Handler里的消息类型 */
  3. ;
  4. /**
  5. * 在Service处理Activity传过来消息的Handler
  6. */
  7. class IncomingHandler extends Handler {
  8. @Override
  9. public void handleMessage(Message msg) {
  10. switch (msg.what) {
  11. case MSG_SAY_HELLO:
  12. Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
  13. break;
  14. default:
  15. super.handleMessage(msg);
  16. }
  17. }
  18. }
  19. /**
  20. * 这个Messenger可以关联到Service里的Handler,Activity用这个对象发送Message给Service,Service通过Handler进行处理。
  21. */
  22. final Messenger mMessenger = new Messenger(new IncomingHandler());
  23. /**
  24. * 当Activity绑定Service的时候,通过这个方法返回一个IBinder,Activity用这个IBinder创建出的Messenger,就可以与Service的Handler进行通信了
  25. */
  26. @Override
  27. public IBinder onBind(Intent intent) {
  28. Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
  29. return mMessenger.getBinder();
  30. }
  31. }

再看一下Activity的代码:

  1. public class ActivityMessenger extends Activity {
  2. /** 向Service发送Message的Messenger对象 */
  3. Messenger mService = null;
  4. /** 判断有没有绑定Service */
  5. boolean mBound;
  6. private ServiceConnection mConnection = new ServiceConnection() {
  7. public void onServiceConnected(ComponentName className, IBinder service) {
  8. // Activity已经绑定了Service
  9. // 通过参数service来创建Messenger对象,这个对象可以向Service发送Message,与Service进行通信
  10. mService = new Messenger(service);
  11. mBound = true;
  12. }
  13. public void onServiceDisconnected(ComponentName className) {
  14. mService = null;
  15. mBound = false;
  16. }
  17. };
  18. public void sayHello(View v) {
  19. if (!mBound) return;
  20. // 向Service发送一个Message
  21. );
  22. try {
  23. mService.send(msg);
  24. } catch (RemoteException e) {
  25. e.printStackTrace();
  26. }
  27. }
  28. @Override
  29. protected void onCreate(Bundle savedInstanceState) {
  30. super.onCreate(savedInstanceState);
  31. setContentView(R.layout.main);
  32. }
  33. @Override
  34. protected void onStart() {
  35. super.onStart();
  36. // 绑定Service
  37. bindService(new Intent(this, MessengerService.class), mConnection,
  38. Context.BIND_AUTO_CREATE);
  39. }
  40. @Override
  41. protected void onStop() {
  42. super.onStop();
  43. // 解绑
  44. if (mBound) {
  45. unbindService(mConnection);
  46. mBound = false;
  47. }
  48. }
  49. }

注意:以上写的代码只能实现从Activity向Service发送消息,如果想从Service向Activity发送消息,只要把代码反过来写就可以了。

使用AIDL

这个方法略,如果知道上面两种方法,这个方法基本很少会用到。

Activity与Service通信的更多相关文章

  1. Activity与Service通信(不同进程之间)

    使用Messenger 上面的方法只能在同一个进程里才能用,如果要与另外一个进程的Service进行通信,则可以用Messenger. 其实实现IPC(Inter-Process Communicat ...

  2. Activity与Service通信的方式有三种:

    在博客园看到的,看着挺不错的,借来分享下 继承Binder类 这个方式仅仅有当你的Acitivity和Service处于同一个Application和进程时,才干够用,比方你后台有一个播放背景音乐的S ...

  3. Android之Activity与Service通信

    一.当Acitivity和Service处于同一个Application和进程时,通过继承Binder类来实现. 当一个Activity绑定到一个Service上时,它负责维护Service实例的引用 ...

  4. android学习-IPC机制之ACtivity绑定Service通信

    bindService获得Service的binder对象对服务进行操作 Binder通信过程类似于TCP/IP服务连接过程binder四大架构Server(服务器),Client(客户端),Serv ...

  5. 201709012工作日记--activity与service的通信机制

    service生命周期 Service主要包含本地类和远程类. Service不是Thread,Service 是android的一种机制,当它运行的时候如果是Local Service,那么对应的 ...

  6. activity 与 service 之间的通信

    activity和service通信:通过binder 举个我实际项目中的例子:在service中下载更新应用 首先是下载更新apk的service: public class UpdateVersi ...

  7. Android四大组件应用系列——Activity与Service交互实现APK下载

    Servic与Activity相比它没有界面,主要是在后台执行一些任务,Service有两种启动方法startService()和bindService(),startService方式Service ...

  8. Android中Activity、Service和线程之间的通信

    Activity.Service和线程应该是Android编程中最常见的几种类了,几乎大多数应用程序都会涉及到这几个类的编程,自然而然的,也就会涉及到三者之间的相互通信,本文就试图简单地介绍一下这三者 ...

  9. activity与service进程内通信

    package com.example.binbin.testbinder; import android.app.Service; import android.content.Intent; im ...

随机推荐

  1. python 进程间通信(下)

    利用 Value,Array   先说明这个方法并不常用,因为有更灵活的方法 from multiprocessing import Process,Value,Array def f(n,a,not ...

  2. 【UOJ #104】【APIO 2014】Split the sequence

    http://uoj.ac/problem/104 此题的重点是答案只与切割的最终形态有关,与切割顺序无关. 设\(f(i,j)\)表示前\(i\)个元素切成\(j\)个能产生的最大贡献. \(f(i ...

  3. PHP函数usort是咋回事?还能当后门?

    开始 详情看这:https://www.leavesongs.com/PHP/bypass-eval-length-restrict.html 原谅我见识短,没用过usort函数 上面连接的文章中,发 ...

  4. redis的原子性

    什么是原子性操作 在多进程(线程)访问共享资源时,能够确保所有其他的进程(线程)都不在同一时间内访问相同的资源,(要么完全执行,要么完全不执行) 简单描述 有个变量X=0,要进行+1操作,步骤如下: ...

  5. CountDownLatch源码分析

    CountDownLatch.Semaphore(信号量)和ReentrantReadWriteLock.ReadLock(读锁)都采用AbstractOwnableSynchronizer共享排队的 ...

  6. Apache -- 利用.htaccess防盗链

    在Apache服务器的前提下利用.htaccess文件来防盗链的原理是通过检查图片或文件请求头信息中的Referer属性(也就是请求的来源),判断它是否属于你所规定的合法的请求来源,从而实现让合法来源 ...

  7. git fetch, git pull 以及 FETCH_HEAD

    git push. 这个很简单, 其实和后面的差不多, 这里就不讲了. 唯一需要注意的地方是: git push origin :branch2, 表示将一个内容为空的同名分支推送到远程的分支.(说白 ...

  8. MySQL单表恢复方法

    正休息的时候一个电话将我的睡意完全打散,“开发童鞋写update SQL的时候忘了加where条件了”,相信每一个DBA同学听到这个消息的时候都有骂街的冲动吧.万幸只是单表写花了,而不是哪位大神在DB ...

  9. Java实现-2016百度秋招(颜色反转、相似字符串)

    1.颜色反转 题目描述: 在 Web 开发中,通常使用 16 进制 RGB 表示一个颜色.例 如 #0000FF 表示蓝色,#FF7F50 表示珊瑚红.在这道题中,我们要求把给定的一种颜色取反,方法是 ...

  10. Read UNIQUE ID and flash size method for stm32

    /* 读取stm32的unique id 与 flash size */ /* func: unsigned int Read_UniqueID_Byte(unsigned char offset) ...