Android Service组件在新进程绑定(bindService)过程

时间:2023-03-09 21:15:51
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");
}
......
}; ......
}

(1)进程间

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对象。

为什么进程内和进程间会有区别呢?请看下图:

Android Service组件在新进程绑定(bindService)过程

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamx0eGdjeQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">

就在于第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进程的。它们通过进程间通信的方式传递数据。