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. 什么是DQL、DML、DDL、DCL

    SQL(Structure Query Language)语言是数据库的核心语言. SQL的发展是从1974年开始的,其发展过程如下: 1974年-----由Boyce和Chamberlin提出,当时 ...

  2. LOJ#2471「九省联考 2018」一双木棋 MinMax博弈+记搜

    题面 戳这里 题解 因为每行取的数的个数是单调不增的,感觉状态数不会很多? 怒而记搜,结果过了... #include<bits/stdc++.h> #define For(i,x,y) ...

  3. 【主席树】BZOJ3932-[CQOI2015]任务查询系统

    [题目大意] 超级计算机中的任务用三元组(Si,Ei,Pi)描述,(Si,Ei,Pi)表示任务从第Si秒开始,在第Ei秒后结束(第Si秒和Ei秒任务也在运行),其优先级为Pi.询问,第Xi秒正在运行的 ...

  4. __declspec(dllexport) 和 __declspec(dllimport)的区别

    最近看MXNet的源码,其中c_api.h中发现遇到__declspec(dllexport) 和 __declspec(dllimport). __declspec(dllexport)用于导出符号 ...

  5. 基础知识(09) -- Spring 概述

    Spring概述-------------------------------------------------------------------------主要内容: 1.Spring是什么 2 ...

  6. Djangio笔记

    django图解 新创建一个项目后的目录层级

  7. Codeforces Round #301 (Div. 2) B. School Marks 构造/贪心

    B. School Marks Time Limit: 1 Sec  Memory Limit: 256 MB 题目连接 http://codeforces.com/contest/540/probl ...

  8. CentOS 6.9永久设置静态路由表以及路由表常用设置

    一.路由表常用设置: 1.使用route命令添加的路由,机器重启或者网卡重启后路由就失效了,方法: //添加到主机的路由 # route add –host 192.168.1.11 dev eth0 ...

  9. CentOS 6.9开启iptables的日志实现调试

    系统日志配置在CentOS 5上叫syslog,而在CentOS 6上叫rsyslog(增强版的syslog),CentOS 5上的配置文件在/etc/syslog.conf下,而CentOS 6在/ ...

  10. Redmine 邮件配置

    高版本号的Redmine是没有email.yml的.是和configuration.yml合并了.仅仅要配置configuration.yml即可了. 首先得说下Redmine的邮件,配置这个邮件,是 ...