Android中Service和Activity之间的通信

时间:2023-03-08 17:27:08

启动Service并传递数据进去:

Android中通过Intent来启动服务会传递一个Intent过去。

可以在Intent中通过putExtra()携带数据

                Intent startIntent = new Intent(MainActivity.this, MyService.class);
startIntent.putExtra("data", etData.getText().toString());
startService(startIntent);

在Service的onStartCommand中得到的Intent中获取这个传递过去的数据

    @Override
public int onStartCommand(Intent intent, int flags, int startId) {
System.out.println("Service.onStartCommand()"); data = intent.getStringExtra("data");
return super.onStartCommand(intent, flags, startId);
}

绑定Sevice并传递数据进去:

当通过绑定启动服务的时候可以用另一种方式把Activity中的数据传递到Service中。

首先在Service中定义一个Binder类,继承自系统的Binder类,然后在onBind中返回这个类的一个实例。

    public class MyBinder extends android.os.Binder{

        public void setData(String data){
MyService.this.data = data;
} public MyService getService(){
return MyService.this;
} } @Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
System.out.println("Service.onBind()");
return new MyBinder();
}

这个类的实例就会在Activity中onServiceConnected中的第二个参数返回,因此也就可以在Activity中用一个实例变量保存它,并调用里面的函数。

private MyService.MyBinder myBinder;

    @Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
myBinder = (MyService.MyBinder)iBinder;
} @Override
public void onClick(View view) {
...
case R.id.btnSyncData:
if (myBinder != null)
myBinder.setData(etData.getText().toString());
}

通过这种方式就可以把Activity中的数据传递给Service,这种方法要比直接用Intent传递要高效。

把Service中的数据传递出来:

还是利用刚刚在Sercie中创建的Binder类,用它返回一个Service的实例:

    public class MyBinder extends android.os.Binder{

        public void setData(String data){
MyService.this.data = data;
} public MyService getService(){
return MyService.this;
} }

同时在Service中定义一个钩子函数,用来给Activity取得Service的内部数据:

private CallBack callBack;

    public CallBack getCallBack() {
return callBack;
} public void setCallBack(CallBack callBack) {
this.callBack = callBack;
} public interface CallBack{
void callBackFunc(String str);
}

通过这种方法Service就可以调用这个CallBack方法:

                    if(callBack != null)
callBack.callBackFunc(str);

在Activity中得到了这个Service的实例以后就可以给它设置一个CallBack实例,这样每次Service调用这个函数就可以把这个数据发送出来:

    @Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
myBinder = (MyService.MyBinder)iBinder; myBinder.getService().setCallBack(new MyService.CallBack() {
@Override
public void callBackFunc(String str) {
Message message = new Message();
Bundle b = new Bundle();
b.putString("data", str);
message.setData(b);
handler.sendMessage(message);
}
}); }

可以用它来更新UI:

private Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
tvOut.setText(msg.getData().getString("data"));
}
};