android创建aidl小实例
16lz
2021-01-23
AIDL(Android Interface Defination Language)android接口定义语言,满足了进程间的通讯。
android每个应用程序都运行在自己的进程中,所以有关进程间通讯可以理解为两个app之间的通讯。
参考:https://www.cnblogs.com/BeyondAnyTime/p/3204119.html 对aidl的创建进行了一个小练习,并总结一下创建过程。
假设现在有一个app需要使用另一个app的加法计算类的实现方法,则有下面过程:
一、创建文件
两个app目录aidlcalculatecomeserver表示向外界提供计算方法的app,下文将都表示为server。
adilcalculatedemoclient表示调用aidlcalculatecomeserver方法的app,下文将都表示为client。
二、创建aidl文件
aidl文件创建目录展示在server和client中相同的包名下分别创建aidl文件,两者需要相同。
// CalculateInterface.aidlpackage com.fx.aidl.calculate;// Declare any non-default types here with import statementsinterface CalculateInterface { double doCalculate(double a,double b);}
定义完成后如下:
创建完成后效果
编写aidl文件注意点:
- 接口名和aidl文件名相同。
- 接口方法前不用加访问权限修饰符public等,也不能加static,final。
- 参数或返回值支持类型
- Java中的八种基本数据类型,包括 byte,short,int,long,float,double,boolean,char。
- String 类型。
- CharSequence类型。
- List类型:List中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。List可以使用泛型。
- Map类型:Map中的所有元素必须是AIDL支持的类型之一,或者是一个其他AIDL生成的接口,或者是定义的parcelable。Map是不支持泛型的。
- 在aidl文件中所有非Java基本类型参数必须加上in,out,inout标记,以指明参数是出入参数、输出参数还是输入输出参数。Java原始类型默认的标记是in。
三、创建service实现类
service实现类CalculateService.java文件
public class CalculateService extends Service { private static final String TAG = "CalculateService"; @Nullable @Override public IBinder onBind(Intent intent) { LogE("onBind()"); return mBinder; } @Override public void onCreate() { LogE("onCreate()"); super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { LogE("onStartCommand()"); return super.onStartCommand(intent, flags, startId); } @Override public boolean onUnbind(Intent intent) { LogE("onUnbind()"); return super.onUnbind(intent); } @Override public void onDestroy() { LogE("onDestroy()"); super.onDestroy(); } public void LogE(String str) { Log.e(TAG, "-------------------" + str + "---------------------"); } private final CalculateInterface.Stub mBinder=new CalculateInterface.Stub() { @Override public double doCalculate(double a, double b) throws RemoteException { LogE("远程计算中"); Calculate calculate=new Calculate(); double answer=calculate.calculateSum(a,b); return answer; } };}
Calculate.java文件
public class Calculate { public double calculateSum(double a,double b){ return a+b; }}
并且最后在AndroidManifest.xml文件中生命service:
四、client app中实现调用
- 创建一个ServiceConnectConnection类实例,来初始化aidl接口实例。
private CalculateInterface mService;private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { logE("connect service"); mService = CalculateInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { logE("disconnect service"); mService = null; }};
- 利用Intent来bindService
Intent intent = new Intent(); intent.setAction("com.fx.aidl.calculate.CalculateService"); intent.setPackage("com.fx.aidl"); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE);
- 调用接口方法
String an = "计算结果:" + mService.doCalculate(n1, n2);
整个的MainActivity.java的代码如下:
public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private EditText num1, num2; private Button button; private TextView answer; private CalculateInterface mService; private ServiceConnection mServiceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { logE("connect service"); mService = CalculateInterface.Stub.asInterface(service); } @Override public void onServiceDisconnected(ComponentName name) { logE("disconnect service"); mService = null; } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); num1 = findViewById(R.id.num1); num2 = findViewById(R.id.num2); button = findViewById(R.id.button); answer = findViewById(R.id.answer); Intent intent = new Intent(); intent.setAction("com.fx.aidl.calculate.CalculateService"); intent.setPackage("com.fx.aidl");// bindService(new Intent(createExplicitFromImplicitIntent(this,intent)), mServiceConnection, Context.BIND_AUTO_CREATE); bindService(intent, mServiceConnection, Context.BIND_AUTO_CREATE); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { double n1 = Double.parseDouble(num1.getText().toString().trim()); double n2 = Double.parseDouble(num2.getText().toString().trim()); try { String an = "计算结果:" + mService.doCalculate(n1, n2); answer.setTextColor(Color.BLUE); answer.setText(an); } catch (RemoteException e) { e.printStackTrace(); } } }); } private void logE(String str) { Log.e(TAG, "--------" + str + "--------"); } public static Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) { // Retrieve all services that can match the given intent PackageManager pm = context.getPackageManager(); List resolveInfo = pm.queryIntentServices(implicitIntent, 0); // Make sure only one match was found if (resolveInfo == null || resolveInfo.size() != 1) { return null; } // Get component info and create ComponentName ResolveInfo serviceInfo = resolveInfo.get(0); String packageName = serviceInfo.serviceInfo.packageName; String className = serviceInfo.serviceInfo.name; ComponentName component = new ComponentName(packageName, className); // Create a new intent. Use the old one for extras and such reuse Intent explicitIntent = new Intent(implicitIntent); // Set the component to be explicit explicitIntent.setComponent(component); return explicitIntent; }}
五、运行
得到结果:
运行效果
代码已上传到github:https://github.com/fengxue1221/aidl
更多相关文章
- Android 需要使用不同实例的情况
- ionic3文件目录介绍
- android从未安装的apk文件里获取信息(包信息,资源信息)
- Android唤醒、解锁屏幕代码实例
- 提高开发效率-使用Android Studio Template快速生成模板文件
- Android API开发之OpenGL开发之Android OpenGL显示STL模型文件
- Android的animation由四种类型组成
- android studio R文件找不到
- 解决IE apk变成zip:Android 手机应用程序文件下载服务器 配置解决