本篇是要介绍activity和service的通信的使用,通过一个小例子实现了activity获取service的数据并展示。
我们知道activity和service(默认)都是在一个进程和主线程里面,这篇主要是介绍同一进程的activity和service的通信。聪明的你肯定知道了不同进程的activity和service的通信实现会有差别。
【转载请注明出处:最简单的Activity、Service使用、通信指南一(进程内通信)(附github源码) CSDN 王智博】
github:https://github.com/samwangzhibo/LoveStudy (不会使用github导入代码的同学,戳这)
先点击按钮,开启并让activity连接service,然后service开启一个线程,它的一个成员变量每秒增加1,然后点击按钮获取service的数据并展示到activity。
1.实现一个service,并且在service里面开启一个线程,里面有num变量一秒递增一次。
2.service定义binder对象,通过binder对象,返回num变量
3.activity先开启service并且获取service返回的集成Ibinder的binder对象,取出binder对象中的num值,展示在页面上
4.activity销毁的时候,关闭service线程并解绑service
class SendThread extends Thread {
int num = 0;
boolean isEnd = false;
private final int DURATION_SLEEP = 1000;
/**
* 关闭线程
* @param end
*/
void setEnd(boolean end) {
isEnd = end;
}
public int getNum(){
return num;
}
@Override
public void run() {
super.run();
while (!isEnd) {
num++;
try {
//不释放资源 休眠
Thread.sleep(DURATION_SLEEP);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class MathService extends Service {
...
@Override
public IBinder onBind(Intent intent) {
return new MathBinder();
}
public class MathBinder extends Binder{
//返回service
public MathService getService(){
return MathService.this;
}
}
//获取线程的num
public int getNum(){
return thread.getNum();
}
...
}
定义一个Sercive,onbind方法返回MathBinder对象,MathBinder对象可以获取Service,Service中有个getNum()方法,可以获取线程的num值
3.1绑定service
Intent intent = new Intent(MainActivity.this, MathService.class);
bindService(intent, this, BIND_AUTO_CREATE);
3.2获取binder
上步中有个boolean bindService(Intent service, ServiceConnection conn, int flags) 方法,其中第二个参数是一个ServiceConnection回调,我们实现它的void onServiceConnected(ComponentName name, IBinder service)方法,其中service参数就是我们在service中onBind()方法设置的MathBinder对象
public void onServiceConnected(ComponentName name, IBinder service) {
mathService = ((MathService.MathBinder) service).getService();
}
获取num的值并展示
commuteWithServiceBtn.setText("获取service数据 : " + mathService.getNum());
protected void onDestroy() {
super.onDestroy();
unbindService(this);
mathService.release();
}
activity通过bindService方式启动Service,通过onServiceConnection回调可以获取IBinder对象。这个对象是Service的onbind()方法返回的,所以我们只需要定义一个返回num对象的binder对象,在service的onbind()方法中返回即可。
github:https://github.com/samwangzhibo/LoveStudy (不会使用github导入代码的同学,戳这)
我们在AndroidManifest.xml中添加process属性,设置service在:MathService进程
然后可以看到报错说不能把BinderProxy转成MathBinder ,我们找一下代码
也就是在多进程的环境下,这个 service对象不再是 我们onbind()里面返回的MathBinder
请看 最简单的Activity、Service使用指南二(进程间通信)(附github源码)
从源码角度分析Activity的生命周期怎么触发的(onCreate onStart onResume onPause onStop onDestroy)(附测试代码)
基于AIDL的 Activity、Service跨进程观察者模式实现与源码解读
走进源码,Android面试最常见Handler、Looper、Message问题总结与解答
Android面试---ListView原理及fling分析
5分钟告诉你,Activity的视图绘制流程(onMeasure、onLayout、onDraw的调用和参数解释)
public class MainActivity extends Activity implements View.OnClickListener, ServiceConnection{
MathService mathService;
Button commuteWithServiceBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.btn_goto_handler_act).setOnClickListener(this);
commuteWithServiceBtn = findViewById(R.id.btn_commute_with_service);
commuteWithServiceBtn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_goto_handler_act:
startActivity(new Intent(MainActivity.this, HandlerActivity.class));
break;
case R.id.btn_commute_with_service:
if (mathService == null) {
//开启service
Intent intent = new Intent(MainActivity.this, MathService.class);
bindService(intent, this, BIND_AUTO_CREATE);
commuteWithServiceBtn.setText("连接成功,点击获取service数据");
}else {
commuteWithServiceBtn.setText("获取service数据 : " + mathService.getNum());
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(this);
mathService.release();
}
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mathService = ((MathService.MathBinder) service).getService();
}
@Override
public void onServiceDisconnected(ComponentName name) {
mathService = null;
}
}
public class MathService extends Service {
SendThread thread;
public MathService() {
}
@Override
public void onCreate() {
thread = new SendThread();
thread.start();
}
@Override
public IBinder onBind(Intent intent) {
return new MathBinder();
}
public class MathBinder extends Binder{
//返回service
public MathService getService(){
return MathService.this;
}
}
//获取线程的num
public int getNum(){
return thread.getNum();
}
public void release() {
thread.setEnd(true);
}
class SendThread extends Thread {
int num = 0;
boolean isEnd = false;
private final int DURATION_SLEEP = 1000;
/**
* 关闭线程
* @param end
*/
void setEnd(boolean end) {
isEnd = end;
}
public int getNum(){
return num;
}
@Override
public void run() {
super.run();
while (!isEnd) {
num++;
try {
//不释放资源 休眠
Thread.sleep(DURATION_SLEEP);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}