用途说明:
比如一些耗资源的操作,如下载等,我们可以单独开一个进程去下载,然后只需要获取到他的下载状态就好。
第一步:创建数据类
package com.example.test.service;
import android.os.Parcel;
import android.os.Parcelable;
public class Person implements Parcelable {
int age;
String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
protected Person(Parcel parcel) {
this.age = parcel.readInt();
this.name = parcel.readString();
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel in) {
return new Person(in);
}
@Override
public Person[] newArray(int size) {
return new Person[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(age);
parcel.writeString(name);
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
第二步:创建aidl文件
IPersonManager.aidl
package com.example.test.service;
import com.example.test.service.PersonListener;
import com.example.test.service.Person;
interface IPersonManager {
void sendPerson(in Person person);
void register(PersonListener per);
void unRegister(PersonListener per);
}
Person.aidl
package com.example.test.service;
parcelable Person;
PersonListener.aidl
package com.example.test.service;
import com.example.test.service.Person;
interface PersonListener {
void onReceive(in Person person);
}
创建好后需要make一下,然后开始编写service文件。
aidl文件的作用是提供一个数据传输的功能,具体的业务逻辑还是得在service中。
第三步:创建PersonService
package com.example.test.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.util.Log;
public class PersonService extends Service {
private RemoteCallbackList<PersonListener> personListenerRemoteCallbackList = new RemoteCallbackList<>();
public PersonService() {
}
@Override
public IBinder onBind(Intent intent) {
Log.d("pjw","onbind");
return new binder();
}
public class binder extends IPersonManager.Stub {
@Override
public void sendPerson(Person person) throws RemoteException {
//通知Callback循环开始,返回N为实现mReceiveListener回调的个数
final int N = personListenerRemoteCallbackList.beginBroadcast();
person.name = "lilei";
for (int i = 0; i < N; i++){
PersonListener listener = personListenerRemoteCallbackList.getBroadcastItem(i);
if (listener != null){
try {
listener.onReceive(person);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
//通知通知Callback循环结束
personListenerRemoteCallbackList.finishBroadcast();
}
@Override
public void register(PersonListener per) throws RemoteException {
personListenerRemoteCallbackList.register(per);
}
@Override
public void unRegister(PersonListener per) throws RemoteException {
personListenerRemoteCallbackList.unregister(per);
}
}
}
第四步:将service弄到另外的进程去
<service
android:name=".service.PersonService"
android:enabled="true"
android:process=":remote"
android:exported="true">
</service>
第五步:在activity中启动service并获取回调的数据
package com.example.test;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.util.Log;
import android.widget.TextView;
import com.example.test.UIUtils.CharUtils;
import com.example.test.service.IPersonManager;
import com.example.test.service.Person;
import com.example.test.service.PersonListener;
import com.example.test.service.PersonService;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private TextView textView;
ServiceConnection mConnection;
PersonService.binder binder = null;
private List<Person> mMsgs = new ArrayList<>();
private IPersonManager mIMsgManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = findViewById(R.id.tvtip);
textView.setText(CharUtils.formatBoldChar("aaa","qwe"));
init();
//这就是开始aidl传数据的地方
findViewById(R.id.btnAidl).setOnClickListener(view -> {
try {
mIMsgManager.sendPerson(new Person(10,"xiaoming"));
} catch (RemoteException e) {
e.printStackTrace();
}
});
}
private void init(){
mConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
mIMsgManager = IPersonManager.Stub.asInterface(iBinder);
try {
mIMsgManager.asBinder().linkToDeath(mDeathRecipient, 0);
mIMsgManager.register(personListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
Intent intent = new Intent();
ComponentName componentName = new ComponentName("com.example.test","com.example.test.service.PersonService");
intent.setComponent(componentName);
bindService(intent, mConnection, BIND_AUTO_CREATE);//开启服务
}
private final PersonListener personListener = new PersonListener.Stub() {
@Override
public void onReceive(Person msg) throws RemoteException {
Log.d("pjw",msg.toString());
}
};
private final IBinder.DeathRecipient mDeathRecipient = new IBinder.DeathRecipient() {
//当承载IBinder的进程消失时接收回调的接口
@Override
public void binderDied() {
if (null == mIMsgManager) {
return;
}
mIMsgManager.asBinder().unlinkToDeath(mDeathRecipient, 0);
mIMsgManager = null;
}
};
@Override
protected void onDestroy() {
//解除注册
if (null != mIMsgManager && mIMsgManager.asBinder().isBinderAlive()) {
try {
mIMsgManager.unRegister(personListener);
} catch (RemoteException e) {
e.printStackTrace();
}
}
//解除绑定服务
unbindService(mConnection);
super.onDestroy();
}
}
最后看一下项目的目录结构。
同一个包名不同进程的aidl就算完成啦。