Android ipc 相关知识点积累 笔记

查看一个应用中的进程信息:

adb shell ps  | grep com.tencent.name. 

多进程带来的问题:

Android为每一个进程分配了一个虚拟机,不同的虚拟机在内存分配上有不同的地址空间,这就导致了不同的虚拟机访问同一类的对象不同。
1.静态成员和单例模式失效
2.线程同步机制实效
3.SharedPreferences可靠性下降
4.Application多次创建

虽然不能直接通信,系统提供了跨进程通信方法。例如:

Intent传递,共享文件,SharedPreferences。基于Binder的Messenger和AIDL以及Socket。

binder


AIDL创建:  一个序列化的实体类book.java  一个book.aidl (里面就parecelable Book,Book在aidl中的声明), 一个封装了读取book方法的接口IBookManger.aidl。

**内部:遵守aidl的规则,系统自动生成IbookManger.java类,生成了内部类Stub, 首先一个判断,如果同一进程,直接返回Stub,不是同一个进程,走transact方法。逻辑由Stub.Proxy(内部实现了接口中的方法)实现。**

主要方法解析:

   onTransact(): 客户端发起跨进程请求,运行请求会通过系统底层封装后交由该方法处理。

 Proxy#getBooklist: 客户端调用该方法,会创建方法所需要的数据,以及输出,封装到Data中,调用transact方法发起远程过程调用(RPC)请求,同时当前线程刮挂起,服务端onTransact()会被调用。知道RPC结束。当前线程继续执行,返回当前数据。

asInterface : 将服务端的Binder对象转换为客户端需要的AIDL接口类型对象, 是判断时候是在统一进程。如果统一进程,直接返回Stub,否则Stub.proxy

Android 一般的IPC通信

  1. Bundle :
  2. 文件 Sp也会存储在文件中的一种,频繁的话会丢失数据。
  3. Messenger : bindService 中进行信息交互。数据放在Messenger中。

    Service:通过创建Handler创建Messenger, onBind返回Messenger对象底层的Binder。

    客户端:绑定服务,也创建一个Handler ,Messenger ,返回ServiceConnection中

  4. ContentProvider :内部线程同步
  5. Socket: 客户端while不断链接Service
  6. AIDL: 相比较于Messenger串行的发送,服务器一个个处理,Messenger更多的是传递信息,通过AIDL去处理;

    服务端:创建一个Service监听客户端的链接请求,创建一个Aidl文件,并暴露给客户端的接口在这个AIDL文件中声明,Service中实现这个接口。

    客户端:先绑定Service,获取Binder对象装还为Aidl接口所属的类型,调用AIDL中的方法。

服务器端具体操作:

  1. IBookManger.adidl, 如果引用的自定义Parcelable(book.java),必须创建一个同名的AIDL文件(book.aidl )并声明它为Parcelable类型(Parcelable book)
    1. 拷贝aidl接口所相关的包,并且包名一致到客户端,因为需要反序列化保持一致。
    2. 创建Service 实现这个接口。
public class BookManagerService extends Servie{
	//CopyOnWriterArrayList支持并发读写
   private CopyOnWriteArrayList<Book> mBook =new ... 
   @Override
   public IBinder onBind(Intent intent){
	   return mBinder;
	}   
 
   private Binder mBinder=new IBookManger.Stub(){
		@Override
		public List<Book> getBooklist() throws RemoteExcetion{
			//具体操作
		}
	}
}

客户端的实现:

public class BookManagerActivty extends Activity{
	......onCreate(){
		..bindService(intent,conn,Context.BIND_AUTO_CREATE);
	}
	private ServiceConnection conn=new ServiceConnection(){
		public void onServiceConnected(ComponentName className,IBinder servive){
       IBookManager bookManger=IBookManger.Stub.asInterface(service);
		 bookManger.getBookList();
		}
	}
}

服务器主动给你发送消息:

特殊的AIDL接口。

interface IOnNextBookArrivedListenter{
	void onNextBookArrived(in Book newBook)	
}

在IBookManger.aidl 中添加两个方法,注册和反注册

。。。

反注册问题:

每次客户端传递多来的是一个新的对象。所以无法进行反注册,

RemoteCallbackList 专门为了删除跨进程的接口。

注意线程的问题:

服务器端被调用的方法运行在Binder线程池中。同时客户端挂起。耗时操作所以调用该方法的时候不能在主线程中。

服务器端本来就是在线程池中,避免再次开启线程执行异步任务。

AIDL权限控制:

  1. 在onBind()中判断 权限。没有直接返回null 链接失败。

  1. onTransact() 中判断UID。PID 包名等。

Advertisements
Android ipc 相关知识点积累 笔记

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s