启动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"));
}
};