Android AIDL 进程间通信
来源:互联网 发布:域名访问升级中 编辑:程序博客网 时间:2024/06/09 14:48
最近温习了AIDL的相关知识,写在这里,记录下来.
首先,先说下跨进程通信的方式有哪些。进程间的通信我们可以使用Messenger,可以在Intent中附加extras来传递信息,或者通过共享文件的方式来共享数据,还可以使用Binder方式来跨进程通信,也可以使用ContentProvider来进行跨进程的数据传递,通过网络的话使用socket也可以实现跨进程通信。
本章博客主要使用AIDL这种方式来进行进程间的通信,AIDL可以处理大量的并发请求,这是通过Messenger不能实现的。Messenger主要是为了传递信息的,如果调用服务端的方法的话,它也是不能做到的。但是可以使用AIDL来调用服务端的方法。
步骤:
1.服务端:
建立一个Service来监听客户端的连接请求,然后创建一个AIDL文件,将暴露给客户端的接口在这个AIDL文件中声明,最后在Service中实现这个AIDL接口即可。
2.客户端:
通过bindService()绑定客户端,将服务端返回的Binder对象转化成AIDL接口所属的类型,就可以在客户端调用AIDL中的方法了。
3.创建AIDL文件:
AIDL文件支持的数据类型:
基本数据类型、
String和CharSequence、
List:只支持ArrayList、
Map:只支持HashMap
parcelable:所有实现了parcelable接口的对象、
AIDL:所有AIDL接口本身也可以在AIDL文件中使用
注:如果AIDL文件中用到了自定义的parcelable对象,那么,必须新建一个和它同名的AIDL文件,并在其中声明它为parcelable类型
具体实现:
创建bean类
package org.superzhao.aidltest;import android.os.Parcel;import android.os.Parcelable;public class User implements Parcelable { private int userid; private String username; public User(int userid, String username) { this.userid = userid; this.username = username; } protected User(Parcel in) { userid = in.readInt(); username = in.readString(); } public static final Creator<User> CREATOR = new Creator<User>() { @Override public User createFromParcel(Parcel in) { return new User(in); } @Override public User[] newArray(int size) { return new User[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(userid); dest.writeString(username); } @Override public String toString() { return "userid:" + userid + ", username:" + username; }}
创建AIDL文件:
IUserManager.aidl
// IUserManager.aidlpackage org.superzhao.aidltest;// Declare any non-default types here with import statementsimport org.superzhao.aidltest.User;interface IUserManager { List<User> getUserList(); void addUser(in User user);}
user.aidl
// User.aidlpackage org.superzhao.aidltest; parcelable User;
注:在创建完成aidl文件后,记得点击同步按钮或者clean project,否则在service端不能调用aidl中的方法,因为找不到。
Service端的实现:
package org.superzhao.aidltest;public class UserManagerService extends Service { private static final String TAG = "UMS"; //在这个boolean值变化期间,不允许任何的插入操作,保持操作的原子性 private AtomicBoolean mIsServiceDestoryed = new AtomicBoolean(false); //CopyOnWriteArrayList是支持并发读写的List,自动进行线程同步 private CopyOnWriteArrayList<User> mUserList = new CopyOnWriteArrayList(); private CopyOnWriteArrayList<IOnNewUserArrivedListener> mListenerList = new CopyOnWriteArrayList(); @Override public void onCreate() { super.onCreate(); mUserList.add(new User(1,"jobs")); mUserList.add(new User(2,"Mike")); }//实现Stub中的抽象方法 private Binder mBinder = new IUserManager.Stub(){ //返回所有的用户 @Override public List<User> getUserList() throws RemoteException { return mUserList; } //添加用户 @Override public void addUser(User user) throws RemoteException { mUserList.add(user); } @Override public IBinder onBind(Intent intent) { return mBinder; }}
注:AIDL方法实在服务端的Binder线程池中执行的,因此当多个客户端同时连接的时候,会存在多个线程同时访问的情形,所以要在AIDL方法中处理线程同步,CopyOnWriteArrayList可以进行自动的线程同步。
客户端的实现:
package org.superzhao.aidltest;public class UserManagerActivity extends Activity { private static final String TAG = "UMA"; private ServiceConnection mConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { IUserManager userManager = IUserManager.Stub.asInterface(service); try { mRemoteUserManager = userManager; List<User> list = userManager.getUserList(); Log.i(TAG,"query list" + list.getClass().getCanonicalName()); Log.i(TAG,"query User list" + list.toString()); User user = new User(3,"Tom"); userManager.addUser(user); List<User> newList = userManager.getUserList(); Log.i(TAG,"query User newList" + newList.toString()); } catch (RemoteException e) { e.printStackTrace(); } } @Override public void onServiceDisconnected(ComponentName name) { } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Intent intent = new Intent(this,UserManagerService.class); bindService(intent,mConnection,BIND_AUTO_CREATE); } @Override protected void onDestroy() { unbindService(mConnection); super.onDestroy(); }}
总结一下:
使用AIDL的大致流程:
首先创建一个Service和一个AIDL接口,接着创建一个类继承自AIDL接口中的Stub类并实现Stub中的抽象方法,在Service的onBind方法中返回这个类的对象,然后客户端就可以绑定服务端的Service,建立连接后就可以访问远程服务端的方法了。
- android AIDL 进程间通信
- android aidl进程间通信
- Android 进程间通信AIDL
- Android进程间通信--AIDL
- Android进程间通信--AIDL
- android 进程间通信(aidl)
- android AIDL进程间通信
- android进程间通信:AIDL
- Android AIDL 进程间通信
- Android进程间通信AIDL
- Android进程间通信---AIDL
- Android 进程间通信AIDL
- Android进程间通信-AIDL
- android 进程通信aidl
- android 进程通信--aidl
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- android进程间通信:使用AIDL
- shell 脚本hello world
- 网络、互联网、因特网的基本概念与组成
- mybatis的分页插件:mybatis-paginator、mybatis-pageHelper
- python对list中的每个元素进行某种操作
- 不同应用程序提供的数据的获取显示—自定义ContentProvider
- Android AIDL 进程间通信
- 前端,财务数据的正则表达式(一篇专门写给自己的博客)
- 【C语言】单链表相关面试题(二)
- ContextLoaderListener与DispatcherServlet
- 指针与引用的区别
- Android平台对H264视频硬解码
- 再谈线程等待函数WaitForSingleObject和CloseHandle
- oracle 10g for linux
- Weblogic服务器启动异常:unable to validate weblogic domain