Android Activity与Service数据交互:Binder、bindService(系列2)

来源:互联网 发布:淘宝靠什么盈利模式 编辑:程序博客网 时间:2024/04/30 10:21


Android Activity与Service数据交互:Binder、bindService(系列2)

在实际的开发中,往往通过Android的Service把后台任务完成后,需要将结果传递给上层代码,比如一个Activity启动了Service,当Service在后台完成处理操作后,此时Service需要将结果传递给Activity,该怎么办呢?办法很多,其中一个就是使用和Android Service密切相关的Android Binder。
假设一个场景,前台Activity需要做一个计算任务,计算任务很简单,计算两个数值的和a+b=?(在实际开发中,这是不存在的,举这个a+b的场景只是为了举一反三用简单例子说没问题)。我将这个计算过程放到Service里面做,首先需要给Service传递过去a与b的值,然后启动Service的服务计算a+b,接下来Service计算完毕得到结果后,Activity再从Service里面获得计算结果,整个Activity与Service交互至此结束。
但是这个看似简单却在Activity与Service中如果不用bind的模型传递数据将会变得复杂,原因在于当Activity启动Service后,从此Activity与Service天地相隔,不存在太大关系,不能像普通的类一样操作Service及里面的方法体。
下面就用Service的bind解决。
 这篇文章是在上一篇文章《Android Service简介(系列1)》(文章链接:http://blog.csdn.net/zhangphil/article/details/49373939 )的基础上增加bind机制。

大致上Activity与Service通过bind交互的编程模型是:
(第1步)老规矩,还是先继承Service。完成里面的onBind,返回一个自己重写的Binder,在本例中是MyBinder。MyBinder里面一个public get方法返回Service的类实例。
毫无疑问,同时需要在Service里面写好public set/get方法,为后面的Activity访问做好基本set/get操作。
(第2步)在Activity里面bindService。bindService是为了将Activity和Service绑定在一起,大有不求同年同月生,但求同年同月死的味道。
在bindService的时候,需要传递一个ServiceConnection,ServiceConnection像一个桥梁,建立了Activity和Service之间的桥接。事实上也就是为了从ServiceConnection的回调方法onServiceConnected中的获得后台的Service句柄。只要获得Service的句柄,那么什么都好办了。
(第3步)在Activity中拿到Service的句柄后,就可以像操作一个普通的Java类一样传参、取值了。

以上步骤完成后,需要明确一个基本的Activity使用Service的顺序流程,以计算a+b=?为例:
(A)首先需要在Activity里面bindService。bindService时候需要传递过去ServiceConnection,在ServiceConnection的回调方法onServiceConnected中获得Service句柄。
(B)拿到Service句柄后,在Activity中设置Service里面的a与b的值。
(C)startService。startService将跳过onCreate直接进入onStartCommand方法体内,在Service里面的后台操作,也可以简单理解为就是在Service的onStartCommand中的操作。在onStartCommand中计算a+b的和。
(D)上层Activity再次通过之前获得的Service句柄从Service里面get a+b的和。

以上模型和流程的代码实现:
Service类:

[java] view plain copy
  1. package zhangphil.service;  
  2.   
  3. import android.app.Service;  
  4. import android.content.Intent;  
  5. import android.os.Binder;  
  6. import android.os.IBinder;  
  7. import android.util.Log;  
  8.   
  9. public class MyAppService extends Service {  
  10.   
  11.     private int a = 0, b = 0;  
  12.     private int result = 0;  
  13.   
  14.     @Override  
  15.     public void onCreate() {  
  16.         Log.d(this.getClass().getName(), "onCreate");  
  17.     }  
  18.   
  19.     // 需要Service处理的操作在此  
  20.     @Override  
  21.     public int onStartCommand(Intent intent, int flags, int startId) {  
  22.   
  23.         result = a + b;  
  24.   
  25.         Log.d(this.getClass().getName(), "onStartCommand:" + result);  
  26.   
  27.         return super.onStartCommand(intent, flags, startId);  
  28.     }  
  29.   
  30.     public int getServiceValue() {  
  31.         return result;  
  32.     }  
  33.   
  34.     public void setServiceValue(int a, int b) {  
  35.         this.a = a;  
  36.         this.b = b;  
  37.         Log.d(this.getClass().getName(), "setServiceValue:a=" + a + " b=" + b);  
  38.     }  
  39.   
  40.     @Override  
  41.     public IBinder onBind(Intent intent) {  
  42.         return new MyBinder();  
  43.     }  
  44.   
  45.     public class MyBinder extends Binder {  
  46.         public MyAppService getService() {  
  47.             return MyAppService.this;  
  48.         }  
  49.     }  
  50.       
  51.     @Override  
  52.     public boolean onUnbind(Intent intent) {  
  53.         Log.d(this.getClass().getName(), "onUnbind");  
  54.         return super.onUnbind(intent);  
  55.     }  
  56.   
  57.     @Override  
  58.     public void onDestroy() {  
  59.         Log.d(this.getClass().getName(), "onDestroy");  
  60.     }  
  61. }  



测试的Activity MainActivity:

[java] view plain copy
  1. package zhangphil.service;  
  2.   
  3. import java.util.Random;  
  4.   
  5. import android.app.Activity;  
  6. import android.app.Service;  
  7. import android.content.ComponentName;  
  8. import android.content.Intent;  
  9. import android.content.ServiceConnection;  
  10. import android.os.Bundle;  
  11. import android.os.IBinder;  
  12. import android.util.Log;  
  13. import android.view.View;  
  14. import android.widget.Button;  
  15. import android.widget.Toast;  
  16. import zhangphil.service.MyAppService.MyBinder;  
  17.   
  18. public class MainActivity extends Activity {  
  19.   
  20.     private ServiceConnection sc = null;  
  21.     private MyAppService myAppService;  
  22.   
  23.     @Override  
  24.     protected void onCreate(Bundle savedInstanceState) {  
  25.         super.onCreate(savedInstanceState);  
  26.         setContentView(R.layout.activity_main);  
  27.   
  28.         Button start = (Button) findViewById(R.id.start);  
  29.         start.setOnClickListener(new View.OnClickListener() {  
  30.   
  31.             @Override  
  32.             public void onClick(View v) {  
  33.                 startMyAppService();  
  34.             }  
  35.         });  
  36.   
  37.         Button bind = (Button) findViewById(R.id.bind);  
  38.         bind.setOnClickListener(new View.OnClickListener() {  
  39.   
  40.             @Override  
  41.             public void onClick(View v) {  
  42.                 bindMyAppService();  
  43.             }  
  44.         });  
  45.   
  46.         Button unbind = (Button) findViewById(R.id.unbind);  
  47.         unbind.setOnClickListener(new View.OnClickListener() {  
  48.   
  49.             @Override  
  50.             public void onClick(View v) {  
  51.                 unbindMyAppService();  
  52.             }  
  53.         });  
  54.   
  55.         Button set = (Button) findViewById(R.id.set);  
  56.         set.setOnClickListener(new View.OnClickListener() {  
  57.   
  58.             @Override  
  59.             public void onClick(View v) {  
  60.                 Random rand = new Random();  
  61.                 int a = rand.nextInt(10);  
  62.                 int b = rand.nextInt(10);  
  63.                 myAppService.setServiceValue(a, b);  
  64.             }  
  65.         });  
  66.   
  67.         Button result = (Button) findViewById(R.id.result);  
  68.         result.setOnClickListener(new View.OnClickListener() {  
  69.   
  70.             @Override  
  71.             public void onClick(View v) {  
  72.                 Toast.makeText(getApplicationContext(), myAppService.getServiceValue() + "", Toast.LENGTH_SHORT).show();  
  73.             }  
  74.         });  
  75.   
  76.         Button stop = (Button) findViewById(R.id.stop);  
  77.         stop.setOnClickListener(new View.OnClickListener() {  
  78.   
  79.             @Override  
  80.             public void onClick(View v) {  
  81.                 stopMyAppService();  
  82.             }  
  83.         });  
  84.     }  
  85.   
  86.     @Override  
  87.     protected void onDestroy() {  
  88.         super.onDestroy();  
  89.         unbindMyAppService();  
  90.         Log.d(this.getClass().getName(), "onDestroy");  
  91.     }  
  92.   
  93.     private void startMyAppService() {  
  94.         Intent intent = new Intent(this, MyAppService.class);  
  95.         this.startService(intent);  
  96.     }  
  97.   
  98.     private void bindMyAppService() {  
  99.         sc = new ServiceConnection() {  
  100.   
  101.             @Override  
  102.             public void onServiceConnected(ComponentName name, IBinder service) {  
  103.                 Log.d(this.getClass().getName(), "onServiceConnected");  
  104.   
  105.                 MyBinder mBinder = (MyBinder) service;  
  106.                 myAppService = mBinder.getService();  
  107.             }  
  108.   
  109.             @Override  
  110.             public void onServiceDisconnected(ComponentName name) {  
  111.                 Log.d(this.getClass().getName(), "onServiceDisconnected");  
  112.             }  
  113.         };  
  114.   
  115.         Intent intent = new Intent(this, MyAppService.class);  
  116.         this.bindService(intent, sc, Service.BIND_AUTO_CREATE);  
  117.     }  
  118.   
  119.     private void stopMyAppService() {  
  120.         Intent intent = new Intent(this, MyAppService.class);  
  121.         boolean bool = this.stopService(intent);  
  122.     }  
  123.   
  124.     private void unbindMyAppService() {  
  125.         if (sc != null)  
  126.             this.unbindService(sc);  
  127.     }  
  128. }  
0 0
原创粉丝点击