关于Service中bindService注意的几个问题

最近有用到Activity需要不断的从Service中获取数据,第一个想法肯定就是通过bind回调机制了,有几点概念模糊特此记录下:

单独使用bindService(),unbindService()会经历:->onCreate()->onBind()->Service running->onUnbind() ->onDestroy() 。

单独使用startService(),stopService()会经历:->onCreate()->onStartCommand()->Service running->onDestroy() 。

先调用startService(),再调用bindService()方法:

如果结束只调用unbindService(),那么只会执行到onUnbind(),将不会执行onDestroy():->onCreate()->onStartCommand()->onBind()->Service running-> onUnbind()。如果在unbindService后,在调用stopService(),那么:->onCreate()->onStartCommand()->onBind()->Service running-> onUnbind()->onDestroy() 。

1、绑定的Service只有当应用组件绑定后才能运行,多个组件可以绑定一个Service,当调用unbind()方法时,这个service就会被销毁了。

3、图形理解Service:

通过这个图可以看到,两种启动Service的方式以及他们的生命周期,bindService的不同之处在于当绑定的组件销毁后,对应的Service也就被kill了。Service的声明周期相比与Activity的简单了许多,只要好好理解两种启动service方式的异同就行。

4、关于停止Service,如果service是非绑定的,最终当任务完成时,为了节省系统资源,一定要停止service,可以通过stopSelf()来停止,也可以在其他组件中通过stopService()来停止,,绑定的service可以通过onUnBind()来停止service。

关于Activity与Service数据的互相传递,写了个demo:

public class MainActivity extends Activity implements View.OnClickListener {private TextView mTextView;private EditText mEditText;private MyService.LocalBinder binder=null;MyService myService;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mEditText = (EditText) findViewById(R.id.edt_content);Button mBtnStart = (Button) findViewById(R.id.btn_start);Button mBtnClose = (Button) findViewById(R.id.btn_close);Button mBtnSubmit = (Button) findViewById(R.id.btn_submit);mTextView = (TextView) findViewById(R.id.tv_show);mBtnStart.setOnClickListener(this);mBtnClose.setOnClickListener(this);mBtnSubmit.setOnClickListener(this);}public ServiceConnection mServiceConnection = new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {binder = (MyService.LocalBinder) service;//得到LocalBinder实例myService = binder.getService();//得到Service实例//设置接口回调获取Service中的数据myService.setOnDataCallback(new MyService.OnDataCallback() {@Overridepublic void onDataChange( final String message) {runOnUiThread(new Runnable() {@Overridepublic void run() {mTextView.setText(message);}});}});}@Overridepublic void onServiceDisconnected(ComponentName name) {myService = null;}};@Overridepublic void onClick(View v) {Intent intent = new Intent(this,MyService.class);switch (v.getId()){case R.id.btn_start://startService(intent);bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);//为Activity绑定服务break;case R.id.btn_close:unbindService(mServiceConnection);//解除绑定//stopService(intent);break;case R.id.btn_submit:if(binder!=null){//把数据传给Service,相比用Bundle效率更高binder.setData(mEditText.getText().toString());}break;}}@Overrideprotected void onDestroy() {super.onDestroy();unbindService(mServiceConnection);//解除绑定}}MyService:

public class MyService extends Service {private String message ;private boolean isRunning = true;private IBinder binder = new LocalBinder();public class LocalBinder extends Binder {public void setData(String message) {//从Activity传入message值MyService.this.message = message;}public MyService getService() {//返回当前MyService对象return MyService.this;}}private OnDataCallback mOnDataCallback=null;public void setOnDataCallback(OnDataCallback mOnDataCallback) {this.mOnDataCallback = mOnDataCallback;}public interface OnDataCallback{void onDataChange(String message);}@Overridepublic IBinder onBind(Intent intent) {//返回这个LocalBinder对象,其实这个对象可以在Activity中onServiceConnected()方法中接收到,这个bind就是Activity和Service通信的桥梁//因为在Activity通过这个bind对象可以得到Service的实例引用。一旦Service对象找到,就能得到它的公共方法和属性。return binder;}@Overridepublic void onCreate() {super.onCreate();new Thread() {@Overridepublic void run() {int i=1;while (isRunning) {if(mOnDataCallback!=null){mOnDataCallback.onDataChange(message + i);}i++;try {sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}}.start();}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {return super.onStartCommand(intent, flags, startId);}@Overridepublic boolean onUnbind(Intent intent) {return super.onUnbind(intent);}@Overridepublic void onDestroy() {super.onDestroy();isRunning = false;}}一旦连接建立,你就能通但这种方式,只能在同一个进程和同一个Application里。跨进程跨应用通信IPC需要建立aidl文件(注:Android5.0以后跨应用只能通过显示Intent来启动Service,即包名、类名)。

版权声明:本文为博主原创文章,未经博主允许不得转载。

却还是,会愚蠢的选择相互敌视的方式。即使背脊相抵,

关于Service中bindService注意的几个问题

相关文章:

你感兴趣的文章:

标签云: