Activity和Service通信
2016-01-21 22:25
537 查看
一.概述
Service是一个应用程序组件,它能够在后台执行一些耗时较长的操作,并且不提供用户界面。服务能被其它应用程序的组件启动,即使用户切换到另外的应用时还能保持后台运行。此外,应用程序组件还能与服务绑定,并与服务进行交互,甚至能进行进程间通信(IPC)。 比如,服务可以处理网络传输、音乐播放、执行文件I/O、或者与content provider进行交互,所有这些都是后台进行的。在Activity中,启动服务有两种方式,startService和bindService,首先让我们看看这两种方式下服务的生命周期图:
二.Activity向Service传值
(1)当我们通过startService启动服务的时候,从生命周期图我们可以看到会调用Service的startCommand方法我们启动服务是通过intent启动的,可以把参数放到intent里面
[code]Intent service = new Intent(this,ProgressService.class); service.putExtra("name","main"); startService(service);
然后
[code]@Override public int onStartCommand(Intent intent, int flags, int startId) { String name = intent.getStringExtra("name"); return super.onStartCommand(intent, flags, startId); }
(2)通过bindService方式启动服务,通过生命周期图我们可以看到会调用
Service的unBind方法,同理
[code]@Override public IBinder onBind(Intent intent) { String name = intent.getStringExtra("name"); Toast.makeText(this,"name"+name,Toast.LENGTH_SHORT).show(); return new ProgressBinder(); }
三.Service向Activity通信
(1)通过Binder对象当我们通过bindService启动一个Service的时候,会传入一个ServiceConnection对象,当服务连接成功后,回传回来一个IBinder类型的对象,通过这个对象,Service就可以和Activity通信。
举一个例子:
[code]public class MainActivity extends Activity { private ProgressBar progressBar; private ProgressService progressService; private int progress = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressBar); Intent service = new Intent(this,ProgressService.class); //绑定服务 bindService(service, connection, Context.BIND_AUTO_CREATE); } public void bindService(View view){ //开始下载 progressService.startDownload(); //更新进度 changeProgress(); } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //当服务连接成功后,获得返回的Binder对象 ProgressBinder binder = (ProgressBinder) service; //通过binder获得服务对象,这样我们就可以调用服务里面的方法了 progressService = binder.getService(); } }; /** * 每隔1秒去检查进度 */ public void changeProgress(){ new Thread(){ @Override public void run() { super.run(); while (progress<=ProgressService.MAX_PROGRESS){ //获取服务中更新后的进度 progress = progressService.getProgress(); progressBar.setProgress(progress); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } @Override protected void onDestroy() { super.onDestroy(); unbindService(connection); } }
[code]/** * 更新进度的服务 */ public class ProgressService extends Service{ public static final int MAX_PROGRESS = 100; public int progress; @Override public IBinder onBind(Intent intent) { return new ProgressBinder(); } class ProgressBinder extends Binder{ //给外部提供一个方法,获得当前服务的对象 public ProgressService getService(){ return ProgressService.this; } } public int getProgress(){ return progress; } /** * 模拟下载操作 */ public void startDownload(){ new Thread(){ @Override public void run() { super.run(); while (progress<=MAX_PROGRESS) { progress+=10; try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } }
效果图如下:
在上面的代码中,我们每次都要主动调用getProgress方法来获取最新的进度,有没有感觉有点被动呢,那么有没有主动一点的方法,这个时候可以利用回调。直接上代码
[code]public class MainActivity extends Activity { private ProgressBar progressBar; private ProgressService progressService; private int progress = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressBar); Intent service = new Intent(this,ProgressService.class); //绑定服务 bindService(service, connection, Context.BIND_AUTO_CREATE); } public void bindService(View view){ progressService.startDownload(); progressService.setOnProgressChangedListener(new ProgressService.OnProgressChangedListener() { @Override public void onProgressChanged(int progress) { progressBar.setProgress(progress); } }); } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //当服务连接成功后,获得返回的Binder对象 ProgressBinder binder = (ProgressBinder) service; //通过binder获得服务对象,这样我们就可以调用服务里面的方法了 progressService = binder.getService(); } }; @Override protected void onDestroy() { super.onDestroy(); unbindService(connection); } }
[code]public class ProgressService extends Service{ public static final int MAX_PROGRESS = 100; public int progress; OnProgressChangedListener listener; interface OnProgressChangedListener{ void onProgressChanged(int progress); } public void setOnProgressChangedListener(OnProgressChangedListener listener){ this.listener = listener; } @Override public IBinder onBind(Intent intent) { return new ProgressBinder(); } class ProgressBinder extends Binder{ //给外部提供一个方法,获得当前服务的对象 public ProgressService getService(){ return ProgressService.this; } } /** * 模拟下载操作 */ public void startDownload(){ new Thread(){ @Override public void run() { super.run(); while (progress<=MAX_PROGRESS) { progress+=10; try { listener.onProgressChanged(progress); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } }
(2)利用广播
[code]public class MainActivity extends Activity { private ProgressBar progressBar; private ProgressService progressService; private int progress = 0; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); progressBar = (ProgressBar) findViewById(R.id.progressBar); Intent service = new Intent(this,ProgressService.class); //绑定服务 bindService(service, connection, Context.BIND_AUTO_CREATE); //添加过滤器,用于过滤发送过来广播 IntentFilter filter = new IntentFilter("intent.action.update"); //注册广播 registerReceiver(new ProgressReceiver(),filter); } public void bindService(View view){ //开始下载 progressService.startDownload(); } ServiceConnection connection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { } @Override public void onServiceConnected(ComponentName name, IBinder service) { //当服务连接成功后,获得返回的Binder对象 ProgressBinder binder = (ProgressBinder) service; //通过binder获得服务对象,这样我们就可以调用服务里面的方法了 progressService = binder.getService(); } }; class ProgressReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //获取发送过来的进度信息 int progress = intent.getIntExtra("progress", 0); progressBar.setProgress(progress); } } @Override protected void onDestroy() { super.onDestroy(); unbindService(connection); } }
[code]public class ProgressService extends Service{ public static final int MAX_PROGRESS = 100; public int progress; @Override public IBinder onBind(Intent intent) { return new ProgressBinder(); } class ProgressBinder extends Binder{ //给外部提供一个方法,获得当前服务的对象 public ProgressService getService(){ return ProgressService.this; } } /** * 模拟下载操作 */ public void startDownload(){ new Thread(){ @Override public void run() { super.run(); while (progress<=MAX_PROGRESS) { progress+=10; try { Intent intent = new Intent("intent.action.update"); intent.putExtra("progress",progress); sendBroadcast(intent); Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }.start(); } }
最后总结一下:
Activity调用bindService (Intent service, ServiceConnection conn, int flags)方法,得到Service对象的一个引用,这样Activity可以直接调用到Service中的方法,如果要主动通知Activity,我们可以利用回调方法
Service向Activity发送消息,可以使用广播,当然Activity要注册相应的***。比如Service要向多个Activity发送同样的消息的话,用这种方法就更好
相关文章推荐
- python_轻量级爬虫开发4
- struts2简单好用的自定义日期转换
- 每天一个linux 命令:which
- POJ1860(ford判环)
- SHELL 脚本学习 day _1 test 指令
- MogileFS 介绍
- UIButton基础以及使用block+UIButton处理点击事件
- listview捕获点击item事件
- 如何锁定Xcode的API头文件
- NGinx负载均衡策略
- 【python运维】python执行shell命令的4种方法
- android一键锁屏代码
- 十进制转二进制
- 《深入浅出Nodejs》—— 读后总结
- 判断apk是否运行在调试状态的方法Debug. isDebuggerConnected之原理
- 计算后缀数组的LCP(Longest Common Prefix)
- 乌龟棋
- ubuntu_socket通信传送文件_g++编译
- Nancy之基于Nancy.Hosting.Self的小Demo
- C/C++ 学习日记第一棒(数据类型)