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

          

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


           就在于第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
    ",
                                   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)
    ",
                                   ref->debug_id, ref->desc, new_ref->debug_id, new_ref->desc, ref->node->debug_id);
            }     
    }
            为转换成BinderProxy对象做准备。

    此时BinderProxy对象是Counter进程的。MyBinder对象是CounterService进程的。它们通过进程间通信的方式传递数据。

  • 相关阅读:
    gulp 安装时一直提示缺少模块( Cannot find module 'gulp-load-plugins')
    webpack4.0入门以及使用
    重装系统(Win)
    单个雪碧图多个图像资源你该如何解决它们的定位?
    手机加载优化
    怎么下载google商店的扩展程序?
    ajax请求后台交互json示例
    scss
    Koala
    webpack-安装
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/6714096.html
Copyright © 2020-2023  润新知