Android Service组件在新进程绑定(bindService)过程
1、首先看两个例子
(1)进程内
Client端
public class CounterService extends Service implements ICounterService { ...... public class CounterBinder extends Binder { public CounterService getService() { return CounterService.this; } } ...... }
Server端
public class MainActivity extends Activity implements OnClickListener { ...... private ServiceConnection serviceConnection = new ServiceConnection() { public void onServiceConnected(ComponentName className, IBinder service) { counterService = ((CounterService.CounterBinder)service).getService(); Log.i(LOG_TAG, "Counter Service Connected"); } ...... }; ...... }
Client端
public class RemoteService extends Service { private final static String TAG = "RemoteService"; @Override public IBinder onBind(Intent intent) { Log.i(TAG, "执行了OnBind"); return new MyBinder(); } private class MyBinder extends RemoteWebPage.Stub{ @Override public String getCurrentPageUrl() throws RemoteException{ return "http://www.cnblogs.com/hibraincol/"; } } }
Server端
private class MyServiceConnection implements ServiceConnection{ @Override public void onServiceConnected(ComponentName name, IBinder service) { Log.i(TAG, "建立连接..."); remoteWebPage = RemoteWebPage.Stub.asInterface(service); try { Log.d(TAG, remoteWebPage.getCurrentPageUrl()); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { Log.i(TAG, "onServiceDisconnected..."); } }
为什么一个是
counterService = ((CounterService.CounterBinder)service).getService();另一个是
remoteWebPage = RemoteWebPage.Stub.asInterface(service);原因在于第一个service是CounterService对象,第二个Service是BinderProxy对象,指向MyBinder对象。
为什么进程内和进程间会有差别呢?请看下图:
就在于第6步,要传递的参数是BinderProxy对象。
进程内会执行如下代码:
case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); ........... if (ref->node->proc == target_proc) {//相同进程 if (fp->type == BINDER_TYPE_HANDLE) fp->type = BINDER_TYPE_BINDER; else fp->type = BINDER_TYPE_WEAK_BINDER; fp->binder = ref->node->ptr; fp->cookie = ref->node->cookie; binder_inc_node(ref->node, fp->type == BINDER_TYPE_BINDER, 0, NULL); if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) printk(KERN_INFO " ref %d desc %d -> node %d u%p\n", ref->debug_id, ref->desc, ref->node->debug_id, ref->node->ptr); } else { ...... } }为转换成CounterService对象做准备。
进程间会执行如下代码:
case BINDER_TYPE_HANDLE: case BINDER_TYPE_WEAK_HANDLE: { struct binder_ref *ref = binder_get_ref(proc, fp->handle); ......... if (ref->node->proc == target_proc) { ..... } else {//不同进程 struct binder_ref *new_ref; new_ref = binder_get_ref_for_node(target_proc, ref->node); if (new_ref == NULL) { return_error = BR_FAILED_REPLY; goto err_binder_get_ref_for_node_failed; } fp->handle = new_ref->desc; binder_inc_ref(new_ref, fp->type == BINDER_TYPE_HANDLE, NULL); if (binder_debug_mask & BINDER_DEBUG_TRANSACTION) printk(KERN_INFO " ref %d desc %d -> ref %d desc %d (node %d)\n", ref->debug_id, ref->desc, new_ref->debug_id, new_ref->desc, ref->node->debug_id); } }为转换成BinderProxy对象做准备。此时BinderProxy对象是Counter进程的,MyBinder对象是CounterService进程的。它们通过进程间通信的方式传递数据。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。