Activity与Service通信

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

继承Binder类

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

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

1. 来看Service的写法:

Java代码  
  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. return mGenerator.nextInt(100);
  22. }
  23. }

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

2. 再看相应Activity的代码:

Java代码  
  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的代码:

Java代码  
  1. public class MessengerService extends Service {
  2. /** 用于Handler里的消息类型 */
  3. static final int MSG_SAY_HELLO = 1;
  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的代码:

Java代码  
  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. Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
  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

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

转载于:https://www.cnblogs.com/qcjd/archive/2012/11/09/9325041.html

Activity与Service通信相关推荐

  1. Activity和Service通信 使用BroadcastReceiver

    本文由PurpleSword(jzj1993)原创,转载请注明 原文网址 http://blog.csdn.net/jzj1993 Activity中编写     /**      * 广播接收器   ...

  2. Activity和Service通信 Bind方式

    本文由PurpleSword(jzj1993)原创,转载请注明 原文网址 http://blog.csdn.net/jzj1993 在Service中自定义Binder类,实现方法getService ...

  3. android activity 通知 service,android activity和service通信问题

    首先,题主有个理解错误的地方, startService 只是开启 service ,service运行在后台,还是有可能因内存不足而被杀死. 第二点, service 可以以混合启动的形式启动,也就 ...

  4. linux 和服务通讯,Android 的Activity和Service之间的通信

    在Android中Activity负责前台界面展示,service负责后台的需要长期运行的任务.Activity和Service之间的通信主要由IBinder负责.在需要和Service通信的Acti ...

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

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

  6. android service交互,Android Activity与Service的交互方式

    参考: http://blog.csdn.net/gebitan505/article/details/18151203 实现更新下载进度的功能 1. 通过广播交互 Server端将目前的下载进度,通 ...

  7. Service通信详解

    2019独角兽企业重金招聘Python工程师标准>>> 1.使用Intent进行异步通讯 在Service任务一旦完成后,就发送广播.开发者只需要实现一个BroadcastRecei ...

  8. 安卓基础巩固(二):四大组件:Activity、Service、Broadcast、Content Provider

    文章目录 Activity 生命周期 onCreate和onStart的区别 onPause和onStop的区别 生命周期的变化 Activity的启动 Intent Bundle Activity携 ...

  9. Android基础再回首——四大组件之Activity、Service俩兄弟

    Android基础再回首--四大组件之Activity.Service俩兄弟 偶尔的回首过去,总是有不一样的收获.今天就来回顾下Activity和service吧,不用嫌弃太基础了,打好基础是取得成功 ...

最新文章

  1. JSP页面中实现使用taglib导入库时自动提示(JSTL 库安装)
  2. linux——grep、sed、awk整理及其比较
  3. laravel修改storage目录和bootstrap目录
  4. substring not found什么意思_英文写作中,除了not,你还会其他否定表达吗?
  5. 现在写程序要像蚊子一样WZ132
  6. php用正则匹配远程图片,php中通过正则表达式下载内容中的远程图片的函数代码...
  7. WF工作流设计器(WPF版)
  8. 更加简洁且通用的ViewHolder写法
  9. 添加的oracle语句,Oracle中Insert语句的总结
  10. linux centos history 查看命令历史 显示时间戳
  11. Redis 配置文件参数说明
  12. ubuntu linux 12.04 下载,Ubuntu12.04下载,Ubuntu12.04更新源下载(多种下载方式)
  13. Vue 事件处理 -- 事件修饰符(prevent、stop、capture、self、once)
  14. 阿里云视频点播服务SDK的使用,视频文件上传测试
  15. 维度表,实体表,事实表之间的关系
  16. Windows电脑关闭触摸键盘的方法
  17. Owndoor开门应用APP安卓苹果
  18. 视频号带货玩法拆解,无私分享给有需要的你「视频教程」
  19. SQL笔试题:某团数分岗笔试真题详解
  20. 201412-1 门禁系统

热门文章

  1. 机器学习知识点(三十六)分类器性能度量指标f1-score
  2. 在线实时大数据平台Storm输入源共享试验
  3. 安装MySQL示例   docker pull mysql
  4. JAVA的知识点4——字符型变量/常量 boolean类型变量/常量
  5. java修改JFrame默认字体
  6. Linux下MySQL数据库的备份与还原,mysql快速导入导出数据库实例演示,解决mysql大数据量数据库导出慢的问题
  7. oracle 数据库问题:“ORA-01922: 必须指定 CASCADE 以删除...“,原因及解决办法
  8. Python 空字符串转化问题:ValueError: invalid literal for int() with base 10: ' ',原因及解决方法。
  9. CTFshow 信息收集 web8
  10. 利用python下载网页到本地(python3)