使用android studio 编译aidl跟eclipse还是有一定的区别的。之前写过一篇eclipse 版本aidl博客Android aidl通信详解。那么这里主要是把那个demo转换成android studio的版本,以及一些注意事项或者配置。
本篇博客源码下载:http://download.csdn.net/detail/qq_16064871/9779991
1 实现的图片
主要是两个程序i,一个客户端(输入两个数),服务端(是加法计算这两个值)。客户端显示计算结果来的。所以是调用了服务端的服务实现加法计算。
2 部分代码
aidl的接口
package com.example.server; import android.os.Bundle; /*** * System private API for talking with the caculate service. * * {@hide} */ interface IBoardADDInterface { int add(int nValue1,int nValue2); }
package com.example.clientdemo; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.os.IBinder; import com.example.server.IBoardADDInterface; import java.util.List; /** * 客户端的服务计算管理类 * @author mmsx * */ public class CaculateManager { //加法计算的服务 final String CACULATE_ADD = "COM.CACULATE.ADD"; //aidi接口服务 IBoardADDInterface mService = null; /*** * 服务绑定 */ public void bindService(Context context) { mContext = context; if(mContext != null && isAppInstalled(mContext,"com.example.serverdemo")){ Intent intent = new Intent("com.example.serverdemo"); intent.setAction(CACULATE_ADD);//Service能够匹配的Action intent.setPackage("com.example.serverdemo");//应用的包名 context.bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE); // context.bindService(getExplicitIntent(mContext,new Intent(CACULATE_ADD)), // serviceConnection, Context.BIND_AUTO_CREATE); } } //判断应用是否安装 public boolean isAppInstalled(Context context, String packageName) { final PackageManager packageManager = context.getPackageManager(); List<PackageInfo> pinfo = packageManager.getInstalledPackages(0); if (pinfo != null) { for (int i = 0; i < pinfo.size(); i++) { if (pinfo.get(i).packageName.contains(packageName)) { return true; } } } return false; } //将隐式启动转换为显式启动,兼容编译sdk5.0以后版本 public Intent getExplicitIntent(Context context,Intent implicitIntent){ PackageManager pm = context.getPackageManager(); List<ResolveInfo> resolveInfos = pm.queryIntentServices(implicitIntent, 0); if (resolveInfos == null || resolveInfos.size()!= 1) { return null; } Intent explicitIntent = null; ResolveInfo info = resolveInfos.get(0); String packageName = info.serviceInfo.packageName; String className = info.serviceInfo.name; ComponentName component = new ComponentName(packageName,className); explicitIntent = new Intent(implicitIntent); explicitIntent.setComponent(component); return explicitIntent; } Context mContext = null; /*** * 解除服务绑定 */ public void unbindService() { if (mContext != null) { mContext.unbindService(serviceConnection); } } /** * 加法计算 * @param nValue1 * @param nValue2 * @return 结果 */ public int caculateAdd(int nValue1,int nValue2) { if (mService == null) return 0; try { return mService.add(nValue1, nValue2); } catch (Exception e) { return 0; } } //服务和aidl接口绑定 private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceDisconnected(ComponentName name) { mService = null; } @Override public void onServiceConnected(ComponentName name, IBinder service) { mService = IBoardADDInterface.Stub.asInterface(service); } }; }
在这上面的代码可以看到注释,需要注意的android 5.0以上不能隐式启动服务。解决办法:
1,以把隐式转为显示启动;
2,使用包名和服务名称来启动:
Intent intent = new Intent("com.example.serverdemo"); intent.setAction(CACULATE_ADD);//Service能够匹配的Action intent.setPackage("com.example.serverdemo");//应用的包名 context.bindService(intent,serviceConnection, Context.BIND_AUTO_CREATE);
服务端的服务怎么写
服务端的计算加法实现类
package com.example.server; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.os.RemoteException; import android.util.Log; /** * 服务端的计算加法实现类 * @author mmsx * */ public class CaculateAddService extends Service { //加法计算的服务 final String CACULATE_ADD = "COM.CACULATE.ADD"; //找到自定义服务 @Override public IBinder onBind(Intent intent) { if(intent.getAction().equals(CACULATE_ADD)) { return mIBinder_CACULATE_ADD; } return null; } @Override public boolean onUnbind(Intent intent) { return super.onUnbind(intent); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onCreate() { super.onCreate(); } //aidl的接口实现 private final IBinder mIBinder_CACULATE_ADD = new IBoardADDInterface.Stub() { @Override public int add(int nValue1, int nValue2) throws RemoteException { Log.i("Show", String.valueOf(nValue1) + ",,," +String.valueOf(nValue2)); return nValue1 + nValue2; } }; }
就是这样啦。
记得注册服务
<service android:name="com.example.server.CaculateAddService" > <intent-filter> <action android:name="COM.CACULATE.ADD" > </action> </intent-filter> </service>
3 注意事项或者配置
服务端和客户端的aidl文件都是一样的。
还有需要在build.gradle加上下面内容
sourceSets.main { manifest.srcFile 'src/main/AndroidManifest.xml' java.srcDirs = ['src/main/java', 'src/main/aidl'] resources.srcDirs = ['src/main/java', 'src/main/aidl'] aidl.srcDirs = ['src/main/aidl'] res.srcDirs = ['src/main/res'] }
客户端和服务端aidl包名一定是一样的。如下图:
本篇博客源码下载:http://download.csdn.net/detail/qq_16064871/9779991
作者:qq_16064871 发表于2017/3/14 22:54:00 原文链接
阅读:272 评论:0 查看评论