跨进程通信AIDL的学习
来源:互联网 发布:雍熙北伐 知乎 编辑:程序博客网 时间:2024/06/05 11:15
一.AIDL服务(接口定义语言)
通过定义接口的方式实现两个应用的通信,两个应用,一个叫它Service端,另一个叫它Client端.
在使用前要先考虑下有没有必要,因为这种方式比较耗内存,没有必要就尽量不用他,避免可能出现的OOM。
AIDL、Binder IPC、Messenger 都可以实现IPC(进程间通信) 只是AIDL适合多线程,另外两种不支持多线程,即多个程序用到对应的aidl文件。所以不需要多线程的可以不用aidl这种IPC方式。
二、总的流程
**Service端需要做的:
1.创建接口
2.创建service 在service中实现接口方法,将接口返回的ibinder对象暴露给客户端使用
3.清单文件中注册并配置service
Client端需要做的:
1.创建和Service端相同的aidl文件,文件夹,包名也都要相同,copy过去即可。
2.bindService
3.通过bindService获得到的接口对象调用方法,最终获得结果(这样的方法也叫接口回调方法)**
三、具体实现步骤
1.生成个aidl文件、里面定义一个接口,Android studio中弄完接口后先编译一下,才能生成Java文件,这样在其他文件里面就有引用提示了(敲几个字母就提示整个接口名)
客户端跟服务端的接口必须一致,包名阿内容阿之类的,可以在服务端连同包一起拷贝aidl文件到客户端
就像上面两个module那样
aidl文件里定义接口:
package com.example.jim.demo_all.aidl;//定义一个接口interface My_AidlInterface { int add(int n1,int n2);//要被调用方法的声明}
2,写一个服务去实现接口(该方式的实现是通过该服务被另一个进程绑定时,返回一个iBinder对象给那个线程,那个对象可以通过ibinder对象调用Service里面的功能函数
public class aidl_Service extends Service{//当客服端绑定到这个服务时就会调用它public IBinder onBind(Intent intent) { return mBinder;}private final My_AidlInterface.Stub mBinder = new My_AidlInterface.Stub() { @Override public int add(int n1, int n2) throws RemoteException { return n1+n2; }};public void onCreate() { super.onCreate(); Log.d("aidl服务开始了", ": ");}
}
manifest里面声明服务
<serviceandroid:name=".aidl_Service"android:exported="true"android:process=":helloaidl">>
4.客户端要去绑定服务端定义的服务
Intent intent=new Intent();intent.setComponent(new ComponentName("com.example.jim.demo_all", "com.example.jim.demo_all.aidl_Service"));
//想要绑定服务的包名跟类名(类名要具体)
bindService(intent,conn, Context.BIND_AUTO_CREATE);//第二个参数是绑定服务时的回调,第三个参数是一个标志
5.拿到返回的ibinder对象
My_AidlInterface my_aidlinterface;private ServiceConnection conn=new ServiceConnection() {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) { my_aidlinterface=My_AidlInterface.Stub.asInterface(service);//拿到远程服务返回的ibinder对象service}@Overridepublic void onServiceDisconnected(ComponentName name) { my_aidlinterface=null;//回收资源}
};
拿到后就可以通过它调用服务里面实现的方法了,像下面这样直接调用
int sum=my_aidlinterface.add(num1,num2);
6,在服务解绑、活动销毁时记得回收资源
protected void onDestroy() {super.onDestroy();unbindService(conn);}
完整的Service代码:
package com.example.jim.demo_all;import...import com.example.jim.demo_all.aidl.My_AidlInterface;/** * Created by Jim斌 on 2017/7/11. */public class aidl_Service extends Service{@Nullable@Override//当客服端绑定到这个服务时就会调用它public IBinder onBind(Intent intent) { return mBinder;}private final My_AidlInterface.Stub mBinder = new My_AidlInterface.Stub() { @Override public int add(int n1, int n2) throws RemoteException { return n1+n2; }};private IBinder iBinder= new My_AidlInterface.Stub() { @Override public int add(int n1, int n2) throws RemoteException { return n1+n2; }};@Overridepublic void onCreate() { super.onCreate(); Log.d("aidl服务开始了", ": ");}
}
完整的绑定服务代码:
package com.example.jim.aidlclient;import ...import com.example.jim.demo_all.aidl.My_AidlInterface;public class aidlclient_Activity extends AppCompatActivity {private EditText n1,n2;private TextView num;private Button add;My_AidlInterface my_aidlinterface;private ServiceConnection conn=new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { my_aidlinterface=My_AidlInterface.Stub.asInterface(service);//拿到远程服务返回的ibinder对象service } @Override public void onServiceDisconnected(ComponentName name) { my_aidlinterface=null;//回收资源 }};@Overrideprotected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_aidlclient_); initview(); bindTheService();}private void initview() { n1= (EditText) findViewById(R.id.n1); n2= (EditText) findViewById(R.id.n2); num= (TextView) findViewById(R.id.num); add= (Button) findViewById(R.id.add); add.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { int num1= Integer.parseInt(n1.getText().toString()); int num2= Integer.parseInt(n2.getText().toString()); try { int sum=my_aidlinterface.add(num1,num2); Log.d("等于", "onClick: "+sum); } catch (RemoteException e) { e.printStackTrace(); } } });}private void bindTheService() { Log.d("lalala", "bindtherservice(): "); Intent intent=new Intent(); intent.setComponent(new ComponentName ("com.example.jim.demo_all", "com.example.jim.demo_all.aidl_Service")); //想要绑定服务的包名跟类名(类名要具体) bindService(intent,conn, Context.BIND_AUTO_CREATE);//第二个参数是绑定服务时的回调,第三个参数是一个标志}@Overrideprotected void onDestroy() { super.onDestroy(); unbindService(conn);}
}
四、遇到的坑:
1.一定要记得在服务端manifest里面声明服务啊
2.一直显示绑定不成功,调试的时候看到返回的ibinder对象一直为空,整个流程回想了一次,断点调试了下,范围缩小到绑定服务那里,看论坛博客里遇到的情况都跟我不一样,后来把客户端的那个Service从单独的一个包里提到外面来,然后就莫名绑定成功了…
一开始这样绑定,包名也确定有写对
intent.setComponent(newComponentName("com.example.jim.demo_all.aidl","com.example.jim.demo_all.aidl.aidl_Service"));
就绑定没成功,后来改了一下
intent.setComponent(new ComponentName("com.example.jim.demo_all", "com.example.jim.demo_all.aidl_Service"));
就成功了。。
- 跨进程通信AIDL的学习
- 学习AIDL 跨进程通信 上
- AIDL跨进程通信
- AIDL跨进程通信
- 关于AIDL的跨进程通信
- Android跨进程通信-AIDL的使用
- 【跨进程】跨进程通信---AIDL
- Android跨进程通信-AIDL
- Android跨进程通信-AIDL
- AIDL实现跨进程通信
- AIDL实现跨进程通信
- Android AIDL跨进程通信
- AIDL实现跨进程通信
- Android AIDL跨进程通信
- 使用AIDL跨进程通信
- 跨进程通信之AIDL
- Android 跨进程通信: AIDL
- Android:AIDL跨进程通信
- 集成springmvc和mybatis环境的Javaweb基础框架,省去新手搭建繁琐环境的苦恼
- 线程的创建和运行(未完待续)
- Thinking in BigData(八)大数据Hadoop核心架构HDFS+MapReduce+Hbase+Hive内部机理详解
- 代码处理iOS的横竖屏旋转
- Java多线程 -- JUC包源码分析2 -- Copy On Write/CopyOnWriteArrayList/CopyOnWriteArraySet
- 跨进程通信AIDL的学习
- HDUOJ 4282 A very hard mathematic problem
- BroadcastReceiver中使用startActivity报错
- 设计模式初步
- Android Fragment和Activity
- htm5手机端实现拖动图片
- JeeSite用户指导
- <安彦>主流浏览器缓存机制
- 浅谈SEO