AIDL 进程间通信
2016-05-19 17:41
417 查看
介绍:
AIDL是用于进程之间的通信。比如应用程序A拥有一套复杂的计算方法,我新的应用程序B也想使用这个计算方法。这时候就能使用AIDL。说白了就是从应用程序B里拿出参数,扔到应用程序A里面,让A来计算,最后返回计算结果给应用程序B。
用法:
使用AIDL要创建 .aidl文件.应用程序A相当于服务端,提供方法。
应用程序B相当于客户端,提供参数并得到结果。
应用程序A和应用程序B的 .aidl文件所在的包名和自身名字必须相同!
在构建好 .aidl文件后IDE会自动在gen目录下生成对应的java文件,我们不需要改动!
CalculateInterface.aidl
package com.example.aidl; interface CalculateInterface { double doCalculate(double a, double b); }
CalculateInterface.aidl (xxx.aidl)这个文件在应用程序A和应用程序B都要创建,并且它们的包名以及自身名字必须相等!
应用程序A(相当于服务端)
CalculateServicepackage com.example.testaidl; import com.example.aidl.CalculateInterface; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; public class CalculateService extends Service { @Override public int onStartCommand(Intent intent, int flags, int startId) { return super.onStartCommand(intent, flags, startId); } @Override public IBinder onBind(Intent intent) { return new CalculateInterface.Stub() { @Override public double doCalculate(double a, double b) throws RemoteException { // 实际上在这里可以调用应用程序A中非常多的类,做非常复杂的算法! // 这里地方就是aidl的意义所在! return a + b; } }; } }
应用程序B(相当于客户端)
MainActivitypackage com.example.testaidlclient; import com.example.aidl.CalculateInterface; import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; public class MainActivity extends Activity { private CalculateInterface mService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = CalculateInterface.Stub.asInterface(service); mHandler.obtainMessage().sendToTarget(); } }; private Handler mHandler = new Handler(){ public void handleMessage(android.os.Message msg) { try { double c = mService.doCalculate(1.0, 2.0); Log.v("TAG", "c = " + c); } catch (RemoteException e) { e.printStackTrace(); } }; }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // bind Intent intent = new Intent("com.action.aidl"); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); // 这里有一个深坑!!! // 在bindService后,mService不是立刻被赋值的! // mService赋值实际是在一个回调函数! // 所在如下的写法会程序奔溃!因为在bindService后,mService还是等于null!! // 这个教训要切记啊!!! // try { // double c = mService.doCalculate(1.0, 2.0); // Log.v("TAG", "c = " + c); // } catch (RemoteException e) { // e.printStackTrace(); // } // } @Override protected void onDestroy() { super.onDestroy(); unbindService(mServiceConnection); } }
为应用程序A(相当于服务端)配置ANDROIDMANIFEST
<service android:name="com.example.testaidl.CalculateService" > <intent-filter> <action android:name="com.action.aidl"/> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </service>
小结:因为service的bind这块没怎么使用过,不了解bindservice的过程。导致学习aidl过程好费了大量的时间~TvT
转载于:
/article/4950162.html
2016/5/23日更新
权限认证功能应用程序A修改onBind()方法
@Override public IBinder onBind(Intent intent) { // 权限验证 int check = checkCallingOrSelfPermission("com.example.testaidlclient.permission.CHECK"); if (check == PackageManager.PERMISSION_DENIED) { return null; } return new CalculateInterface.Stub() { @Override public double doCalculate(double a, double b) throws RemoteException { // 实际上在这里可以调用应用程序A中非常多的类,做非常复杂的算法! // 这里地方就是aidl的意义所在! return a + b; } }; }
应用程序B AndroidManifest.xml声明自定义权限
<uses-permission android:name="com.example.testaidlclient.permission.CHECK"/>
应用程序A AndroidManifest.xml 声明自定义权限
注意: 应用程序B和应用程序A声明权限的方式不同!
<permission android:name="com.example.testaidlclient.permission.CHECK" android:protectionLevel="normal"/>
这样代表应用程序A有权限访问应用程序B
资料转载于:
/article/7485879.html
相关文章推荐
- Principles of training multi-layer neural network using backpropagation
- main函数参数的用法
- 使用AIDL实现进程间的通信之复杂类型传递
- 使用AIDL实现进程间的通信
- JetBrains重大安全升级!
- 70. Climbing Stairs
- 127_AIDL的使用
- c 语言模块接口函数在main之前注册
- Given a binary tree containing digits from0-9only, each root-to-leaf path could represent a number. An example is the root-to-leaf path1->2->3which represents the number123. Find the total sum of a
- xcode7 解决NSURLConnection/CFURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9843)
- maven打好的jar包如何在运行时指定main-class
- 【leetcode】11. Container With Most Water
- [Ogre][地形][原创]基于OgreTerrain的地形实现
- 人工智能基础01--绪论
- LeetCode 11. Container With Most Water(容器装水)
- RAD Studio 10 安装失败 提示错误 License status check failure解决办法
- leetcode 11. Container With Most Water
- 使用 SDL 过程中遇到的两个问题: 找不到main函数 和 链接错误
- ansible 报错 FAILED | rc=0 >> MODULE FAILURE 解决方法
- codeforces 675E E. Trains and Statistic(线段树+dp)