Service(二):通信
课程:http://www.jikexueyuan.com/course/715_3.html?ss=1
在activity和service之间通信。
首先使用的是启动服务来通信。注意是如何使用Intent取得EditText的数据并传递给service的,在service是又是如何取出数据的。
在MainActivity中
private EditText etData; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); etData = (EditText)findViewById(R.id.etData); findViewById(R.id.btnStartService).setOnClickListener(this); findViewById(R.id.btnStopService).setOnClickListener(this); } public void onClick(View v) { switch (v.getId()){ case R.id.btnStartService: Intent i = new Intent(this,MyService.class); i.putExtra("data",etData.getText().toString()); startService(i); break; case R.id.btnStopService: stopService(new Intent(this,MyService.class)); break; } }
在MyService中,通过启动服务的onCommand来取得数据
public int onStartCommand(Intent intent, int flags, int startId) { data = intent.getStringExtra("data"); return super.onStartCommand(intent, flags, startId); }
接下来用绑定服务来完成通信。
增加两个绑定按钮和一个数据同步按钮
case R.id.btnBindService: bindService(new Intent(this,MyService.class),this, Context.BIND_AUTO_CREATE); break; case R.id.btnUnbindService: unbindService(this); break; case R.id.btnSyncData: if(binder!=null){ binder.setData(etData.getText().toString());
在绑定服务中需完成两个函数
@Override public void onServiceConnected(ComponentName name, IBinder service) { binder = (MyService.Binder)service; } @Override public void onServiceDisconnected(ComponentName name) { }
其中的binder悄悄完成了activiy和service之间的通信(这里面的过程很微妙,好好体会)
public IBinder onBind(Intent intent) { return new Binder(); } public class Binder extends android.os.Binder{ public void setData(String data){ MyService.this.data = data; } }
总结下启动服务和绑定服务与活动通信的不同:
启动服务是通过Intent对象来取得数据,通过startService启动onStartCommand来过多成Intent对象的传递。
绑定服务是通过binder对象中的函数来完成通信。
前面讲的是从activity中获取数据到MyService,即从UI线程(主线程)从获取数据到子线程中,那么如何总子线程中获取数据到主线程中呢?
示例中在子线程中完成数据的变化,要求将其显示在UI的TextView上。
这里用到了回调的方式。首先定交一个接口CallBack用于向UI中传递变化的数据,在activity中实现接口中的函数,取得数据,并以message的方式传递给Handler,再将其传递给TextView进行显示。
这个过程还是挺复杂的,需要细心体会。