前言
該篇文件講述的是AIDL最基本的使用(創建、調用),關於對於AIDL更深的認識,在后續的隨筆中,會持續與大家分享並探討。
正文
- AIDL的定義(什么是AIDL?)
- AIDL的應用場景(AIDL可以做什么?)
- 如何寫一個AIDL的應用?(代碼)
AIDL概述(定義)
- AIDL:Android Interface Definition Language,即Android接口定義語言。也就是說:AIDL也是一種語言。
- 設計AIDL語言的目的:為了實現進程間通信。
本篇文章主要介紹的是AIDL的代碼實現。關於進程間通信的分析,小伙伴們可以參考:淺談應用進程間的通信(AIDL和IPC)
AIDL應用場景
- 如:某個應用調用支付寶的支付功能、微信的支付功能
寫一個AIDL的應用 AIDL模板代碼
*與你一步步掌握AIDL的應用*
需求
- 應用A:模擬一個商城應用(如:拼XX)
- 應用B:模擬一個支付應用(如:支付寶),應用中有一個支付服務在運行,服務中定義了一個帶返回值的支付方法。
- 要求:在應用A中,調用應用B支付服務中的支付方法,傳一個參數並獲取返回值。
代碼實現
應用B:被調用方
-
- 創建一個service:AliPayService,並在清單文件中配置信息
-
AndroidManifest.xml
<!--調用遠程服務,需要通過bind方式啟動服務,調用服務方法-->
<service android:name=".service.pay.AliPayService">
<intent-filter>
<action android:name="com.zero.notes.service.pay.xxx"/>
</intent-filter>
</service>
- AliPayService
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
/**
* 模擬:阿里支付服務
*/
public class AliPayService extends Service {
@Override
public IBinder onBind(Intent intent) {
return new MyBinder();
}
//模擬支付方法
public boolean aliPay(int money) {
Log.e("AIDL", "服務線程:" + Thread.currentThread().getName());
if (money > 100) {
handler.sendEmptyMessage(1);
return true;
} else {
handler.sendEmptyMessage(0);
return false;
}
}
// class MyBinder extends Binder implements IPayservice {
// @Override
// public boolean callAliPay(int money) throws RemoteException {
// return aliPay(money);
// }
// @Override
// public IBinder asBinder() {
// return null;
// }
// }
/**
* 創建中間人對象(中間幫助類)
*/
class MyBinder extends IPayservice.Stub {
@Override
public boolean callAliPay(int money) {
return aliPay(money);
}
}
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.what == 1) {
Toast.makeText(getApplicationContext(), "土豪,購買成功...", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getApplicationContext(), "錢太少啦,購買失敗...", Toast.LENGTH_SHORT).show();
}
}
};
}
- IPayservice.aidl
此處需要注意:創建的 IPayservice.aidl 文件是一個接口文件。Android Studio上可以直接創建一個AIDL文件。創建完成后,切記:把整個項目clean一下,讓代碼編輯器生成一些必要的文件信息。(Android Studio項目clean方式:Build -> Clean Project)
// IPayservice.aidl
package com.zero.notes.service.pay;
// Declare any non-default types here with import statements
interface IPayservice {
boolean callAliPay(int money);
}
- MainActivity
應用B啟動該服務(代碼書寫:kotlin語言)
class MainActivity : BaseActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initData()
}
private fun initData() {
val intent = Intent(this,AliPayService::class.java)
startService(intent)
}
}
應用A:調用方(書寫代碼:Kotlin語言)
- 拷貝:把應用B 中的 IPayservice.aidl 文件拷貝到應用A內
切記::拷貝的時候,IPayservice.aidl 的路徑位置必須與應用B中保持完全一致,包名、路徑名要完全一致!
如圖所示:圖1️⃣是以Android方式查看;圖2️⃣是以Project方式查看。
- 創建服務連接對象
//創建一個服務連接對象
class MyServiceConnection : ServiceConnection {
private lateinit var iPayService: IPayservice
override fun onServiceDisconnected(name: ComponentName?) {
}
override fun onServiceConnected(name: ComponentName?, service: IBinder?) {
//2. 獲取中間人對象(服務綁定成功后會返回一個中間人對象)
iPayService = IPayservice.Stub.asInterface(service)
}
//獲取中間人對象
fun getIPayService():IPayservice{
return iPayService
}
}
- 在應用A 的 Activity 中調用服務方法
class MainActivity : AppCompatActivity() {
private var connection: MyServiceConnection? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val intent = Intent()
intent.action = "com.zero.notes.service.pay.xxx"
intent.setPackage("com.zero.notes")
connection = MyServiceConnection()
bindService(intent, connection, Context.BIND_AUTO_CREATE)
tvJump.setOnClickListener {
val iPayService = connection?.getIPayService()
val pay = iPayService?.callAliPay(1000)!!
if (pay) {
//購買成功
} else {
//購買失敗
}
}
}
override fun onDestroy() {
super.onDestroy()
if (connection != null) {
unbindService(connection)
connection = null
}
}
}
- 應用A:Activity的xml文件
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:gravity="center_horizontal"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tvJump"
android:layout_width="wrap_content"
android:layout_marginTop="30dp"
android:text="AIDL調用方法"
android:textColor="#FF212121"
android:textSize="20sp"
android:padding="16dp"
android:background="#66000000"
android:textStyle="bold"
android:layout_height="wrap_content"/>
</LinearLayout>