Activity与 Service通信:
1.通过BroadCastReceiver:这种方式是最简单的,只能用来交换简单的数据;
2.通过Messager:这种方式是通过一个传递一个Messager给对方,通过这个它来发送Message对象。这种方式只能单向传递数据。可以是Service到Activity,也可以是从Activity发送数据给Service。一个Messeger不能同时双向发送;
3.通过Binder来实现远程调用(IPC):这种方式是Android的最大特色之一,让你调用远程Service的接口,就像调用本地对象一样,实现非常灵活,写起来也相对复杂。
怎样在启动一个Service时向它传递数据,关键点:Intent传值,onStartCommand()接收。
binder流程如下:
1、在Service子类创建 binder子类,返回当前服务的this对象。让前端能够通过 binder 类实现对 service 的调用。
2、service 中的 onbinder方法返回 binder 实例。
3、在前端中的 onserviceconnected 中接收返回的 binder 实例。通过binder 实例获得服务的this对,通过对象调用公共方法,实现通信。
Service:
package com.example.chengwenbo.myservce;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
public class MyService extends Service {
private static final String TAG = "MyService";
/**
* 一般开发的时候 都会在你自己写的方法里面或者自己叫不准的位置加一句Log,以备在跑程序的时候能准确找到错误点,
一般的格式是 Log.v(TAG,"你想备注的名字");
Log.e或Log.v或Log.d或Log.i
这时候就要补这一句,MainActivity是该文件名
*/
private LocalBinder mbinder = new LocalBinder();
/**
* //在服务里面新建一个内部类LocalBinder
//LocalBinder新增了两个自己的方法binderFun1(),binderFun2()
//LocalBinder的getService()返回当前服务的this对象
/**
*在onBinder方法中返回LocalBinder对象,回LocalBinder对象包含了service的句柄,
*客户端通过句柄就可以调用servcie的公共方法funLocalService()了.
*/
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
//throw new UnsupportedOperationException("Not yet implemented");
return mbinder;//只有绑定时才返回binder对象
}
public class LocalBinder extends Binder{
public MyService getservices(){//返回当前服务的this对象
return MyService.this;
}
public String fun1(){
return "fun1";
}
public String fun2(){
return "fun2";
}
}
@Override
public void onCreate(){
super.onCreate();
/*
serviceRunning = true;
new Thread() {
@Override
public void run() {
int n = 0;
while (serviceRunning) {
n++;
String str = n + data;
System.out.println(str);
if (dataCallback != null) {
dataCallback.dataChanged(str);
}
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}.start();
*/
}
// 每次启动Servcie时都会调用该方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//System.out.println("--onStartCommand()--");
//data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}
// 解绑Servcie调用该方法
@Override
public boolean onUnbind(Intent intent) {
//System.out.println("--onUnbind()--");
return super.onUnbind(intent);
}
// 退出或者销毁时调用该方法
@Override
public void onDestroy() {
//serviceRunning = false;
//System.out.println("--onDestroy()--");
super.onDestroy();
}
//公共方法,通过getservices()返回的服务建立的对象调用,实现通信
public String myway(){
return "hello world";
}
}
Activity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private MyService mMyService;
private ServiceConnection mConnection;
private MyService.LocalBinder binder;
private Button bt1,bt2,bt3,bt4;
private static final String TAG = "MainActivity";
private String st1 = "1";
private String st2 = "2";
private String st3 = "3";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt1 = findViewById(R.id.btn_start);
bt2 = findViewById(R.id.btn_stop);
bt3 = findViewById(R.id.btn_bind);
bt4 = findViewById(R.id.btn_unbind);
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
bt3.setOnClickListener(this);
bt4.setOnClickListener(this);
//绑定开启的时候调用。
mConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
//调用LocalBinder自己的方法
binder = (MyService.LocalBinder) iBinder;
st2 = binder.fun1();
st3 = binder.fun2();
//client得到服务LocalService的句柄,便可以调用服务里面声明的public方法funLocalService()
mMyService = binder.getservices();
st1 = mMyService.myway();
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
mMyService = null;
Log.e(TAG, "onServiceDisconnected:");
}
};
}
/**
* 里面主要是为了实现一个可以从service的回调接口
*/
@Override
public void onClick(View v){
switch (v.getId()){
case R.id.btn_start:
Intent start = new Intent(this,MyService.class);
startService(start);
Toast.makeText(this,"s-"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
break;
case R.id.btn_stop:
Intent stop = new Intent(this,MyService.class);
stopService(stop);
Toast.makeText(this,"st"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
break;
case R.id.btn_bind:
Intent bind = new Intent(this,MyService.class);
bindService(bind,mConnection, Service.BIND_AUTO_CREATE);
/**
* bindService是异步调用和Service进行绑定, 如果绑定成功,
* 则会调用ServiceConnection的onServiceConnected
* 当调用bindService方法后就会回调Activity的onServiceConnected,
* 在这个方法中会向Activity中传递一个IBinder的实例,Acitity需要保存这个实例
*/
Toast.makeText(this,"b"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
break;
case R.id.btn_unbind:
//Intent unbind = new Intent(this,MyService.class);
unbindService(mConnection);
Toast.makeText(this,"ub"+st1+"-"+st2 + "-"+st3,Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}