博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Android Activity与Service数据交互:Binder、bindService(系列2)
阅读量:5881 次
发布时间:2019-06-19

本文共 5837 字,大约阅读时间需要 19 分钟。



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)》(文章链接: )的基础上增加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类:

package zhangphil.service;import android.app.Service;import android.content.Intent;import android.os.Binder;import android.os.IBinder;import android.util.Log;public class MyAppService extends Service {	private int a = 0, b = 0;	private int result = 0;	@Override	public void onCreate() {		Log.d(this.getClass().getName(), "onCreate");	}	// 需要Service处理的操作在此	@Override	public int onStartCommand(Intent intent, int flags, int startId) {		result = a + b;		Log.d(this.getClass().getName(), "onStartCommand:" + result);		return super.onStartCommand(intent, flags, startId);	}	public int getServiceValue() {		return result;	}	public void setServiceValue(int a, int b) {		this.a = a;		this.b = b;		Log.d(this.getClass().getName(), "setServiceValue:a=" + a + " b=" + b);	}	@Override	public IBinder onBind(Intent intent) {		return new MyBinder();	}	public class MyBinder extends Binder {		public MyAppService getService() {			return MyAppService.this;		}	}		@Override	public boolean onUnbind(Intent intent) {		Log.d(this.getClass().getName(), "onUnbind");		return super.onUnbind(intent);	}	@Override	public void onDestroy() {		Log.d(this.getClass().getName(), "onDestroy");	}}

测试的Activity MainActivity:

package zhangphil.service;import java.util.Random;import android.app.Activity;import android.app.Service;import android.content.ComponentName;import android.content.Intent;import android.content.ServiceConnection;import android.os.Bundle;import android.os.IBinder;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;import zhangphil.service.MyAppService.MyBinder;public class MainActivity extends Activity {	private ServiceConnection sc = null;	private MyAppService myAppService;	@Override	protected void onCreate(Bundle savedInstanceState) {		super.onCreate(savedInstanceState);		setContentView(R.layout.activity_main);		Button start = (Button) findViewById(R.id.start);		start.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				startMyAppService();			}		});		Button bind = (Button) findViewById(R.id.bind);		bind.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				bindMyAppService();			}		});		Button unbind = (Button) findViewById(R.id.unbind);		unbind.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				unbindMyAppService();			}		});		Button set = (Button) findViewById(R.id.set);		set.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				Random rand = new Random();				int a = rand.nextInt(10);				int b = rand.nextInt(10);				myAppService.setServiceValue(a, b);			}		});		Button result = (Button) findViewById(R.id.result);		result.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				Toast.makeText(getApplicationContext(), myAppService.getServiceValue() + "", Toast.LENGTH_SHORT).show();			}		});		Button stop = (Button) findViewById(R.id.stop);		stop.setOnClickListener(new View.OnClickListener() {			@Override			public void onClick(View v) {				stopMyAppService();			}		});	}	@Override	protected void onDestroy() {		super.onDestroy();		unbindMyAppService();		Log.d(this.getClass().getName(), "onDestroy");	}	private void startMyAppService() {		Intent intent = new Intent(this, MyAppService.class);		this.startService(intent);	}	private void bindMyAppService() {		sc = new ServiceConnection() {			@Override			public void onServiceConnected(ComponentName name, IBinder service) {				Log.d(this.getClass().getName(), "onServiceConnected");				MyBinder mBinder = (MyBinder) service;				myAppService = mBinder.getService();			}			@Override			public void onServiceDisconnected(ComponentName name) {				Log.d(this.getClass().getName(), "onServiceDisconnected");			}		};		Intent intent = new Intent(this, MyAppService.class);		this.bindService(intent, sc, Service.BIND_AUTO_CREATE);	}	private void stopMyAppService() {		Intent intent = new Intent(this, MyAppService.class);		boolean bool = this.stopService(intent);	}	private void unbindMyAppService() {		if (sc != null)			this.unbindService(sc);	}}

注意记到!在Activity退出时候,请unbindService,或者stopService。

转载地址:http://pjvix.baihongyu.com/

你可能感兴趣的文章
SCCM 2016 配置管理系列(Part8)
查看>>
struts中的xwork源码下载地址
查看>>
ABP理论学习之仓储
查看>>
我的友情链接
查看>>
Tengine新增nginx upstream模块的使用
查看>>
CentOS图形界面和命令行切换
查看>>
HTML5通信机制与html5地理信息定位(gps)
查看>>
汽车常识全面介绍 - 悬挂系统
查看>>
加快ALTER TABLE 操作速度
查看>>
学习笔记之软考数据库系统工程师教程(第一版)
查看>>
PHP 程序员的技术成长规划
查看>>
memcached 分布式聚类算法
查看>>
jquery css3问卷答题卡翻页动画效果
查看>>
$digest already in progress 解决办法——续
查看>>
虚拟机 centos设置代理上网
查看>>
Struts2中Date日期转换的问题
查看>>
mysql 数据类型
查看>>
Ubuntu 设置当前用户sudo免密码
查看>>
设置tomcat远程debug
查看>>
android 电池(一):锂电池基本原理篇【转】
查看>>