今天介紹下安卓跨進程同時AIDL基本使用和需要注意的地方,我以登錄爲例,
新建個項目MyAidl,新建一個IMyAidlInterface 的AIDL接口,
在interface Nmae輸入接口名稱
//再在aidl文件夾下新建一個Bean對象,(注意自定義bean對象,需要現在aidl新建編譯,再建Java類bean,要不你在aidl會報類名衝突)
Bean.adil代碼如下
// Bean.aidl
package cn.zdh.myaidl;
// Declare any non-default types here with import statements
//導入對應的Bean對象
parcelable Bean;
再在Java文件夾新建個Bean對象代碼如下(注意自定義bean類需要實現parcelable,如果aidl接口使用out 或者inout需要寫readFromParcel(Parcel reply)方法; 注意Java的bean類的包名必須和aidl的包名一致)
public class Bean implements Parcelable {
private String name;
private String password;
public Bean() {
}
public Bean(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(this.name);
dest.writeString(this.password);
}
protected Bean(Parcel in) {
this.name = in.readString();
this.password = in.readString();
}
public static final Parcelable.Creator<Bean> CREATOR = new Parcelable.Creator<Bean>() {
@Override
public Bean createFromParcel(Parcel source) {
return new Bean(source);
}
@Override
public Bean[] newArray(int size) {
return new Bean[size];
}
};
/**
* adil 使用out 或者inout 需要寫這個方法
*/
public void readFromParcel(Parcel reply) {
this.name = reply.readString();
this.password = reply.readString();
}
}
//下面寫aidl接口
//使用AIDL需要注意下面幾點
//1:同包也要導包
//2: 支持基礎類型數據傳遞,自定義類需要實現parcelable序列化
//3:自定義的類名和包名必須和 AIDL的類名包名一致
//4:in 服務端 不能修改客服端的入參數數據(bean),但是可以獲取參數數據
//5:out 服務端 能修改客服端的入參數據(bean),但是並不可以獲取參數數據
//6:inout 服務 能修改客服端的入參數據(bean),也可以獲取參數數據 ,但是消耗性能最大
//7:注意 使用out inout Java的bean對象需要寫 readFromParcel(Parcel reply){}方法,在方法裏面把字段讀取出來
import cn.zdh.myaidl.Bean;
interface IMyAidlInterface {
void login(in Bean bean);
}
//Java對應service代碼
/**
* 實現aidl接口方法
*/
public class AidlService extends Service {
@Override
public IBinder onBind(Intent intent) {
return iBinder;
}
private Handler handler = new Handler(Looper.getMainLooper()) {
@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();
}
}
};
/**
* 獲取aidl的binder對象
* 注意在子線程
*/
private IBinder iBinder = new IMyAidlInterface.Stub() {
@Override
public void login(Bean bean) throws RemoteException {
//判斷用戶賬戶是的正確
String name = bean.getName();
String password = bean.getPassword();
Message message = handler.obtainMessage();
if (name.equals("張三") && password.equals("123456")) {
message.what = 1;
handler.sendMessage(message);
} else {
Log.e("zdh", "------" + Thread.currentThread().getName());
message.what = 0;
handler.sendMessage(message);
}
}
};
}
//創建一個activity測試登錄,代碼如下,(注意 在mainfest添加process 新建個進程)
public class TextActivity extends AppCompatActivity {
private IMyAidlInterface iMyAidlInterface;
private ServiceConnection conn;
private EditText etName, etPassword;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_text);
etName = findViewById(R.id.et_name);
etPassword = findViewById(R.id.et_password);
//bindService啓動服務
Intent intent = new Intent();
intent.setComponent(new ComponentName("cn.zdh.myaidl", "cn.zdh.myaidl.AidlService"));
conn = new MyServiceConnection();
bindService(intent, conn, BIND_AUTO_CREATE);
}
@Override
protected void onDestroy() {
super.onDestroy();
//解除服務綁定
unbindService(conn);
}
//登錄
public void load(View view) {
Bean bean = new Bean();
bean.setName(etName.getText().toString());
bean.setPassword(etPassword.getText().toString());
try {
//添加數據
iMyAidlInterface.login(bean);
} catch (Exception e) {
e.printStackTrace();
}
}
private class MyServiceConnection implements ServiceConnection {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
//獲取aidl接口對象
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
}
}
//mainfest代碼
//注意 process 需要使用雙引號 :
<activity android:name=".TextActivity" android:process=":t"/>
//不要忘記註冊服務
<service android:name=".AidlService" />
代碼運行效果如下
總結:使用aidl需要注意的
//1:同包也要導包
//2: 支持基礎類型數據傳遞,自定義類需要實現parcelable序列化
//3:自定義的類名和包名必須和 AIDL的類名包名一致
//4:in 服務端 不能修改客服端的入參數數據(bean),但是可以獲取參數數據
//5:out 服務端 能修改客服端的入參數據(bean),但是並不可以獲取參數數據
//6:inout 服務 能修改客服端的入參數據(bean),也可以獲取參數數據 ,但是消耗性能最大
//7:注意 使用out inout Java的bean對象需要寫 readFromParcel(Parcel reply){}方法,在方法裏面把字段讀取出來
//8:Java是service 是在子線程
源碼地址 https://github.com/zhudaihao/MyAIDL