1、远程服务:使用 AIDL(Android Interfice Definition Language) 安卓接口定义语言进行 IPC(Inter Process Communication)跨进程通信。
2、注意:
1.AIDL 支持数据类型:1.基本数据类型。2.String、CharSequence。3.ArrayList、HashMap。4.AIDL 接口。5.实现 Parcelable 接口的类。
3、具体应用
1、服务端
- 创建共享类
public class Person implements Parcelable {
private String name;
private int age;
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public int describeContents() {
// TODO Auto-generated method stub
return 0;
}
@Override
public void writeToParcel(Parcel arg0, int arg1) {
arg0.writeString(name);
arg0.writeInt(age);
}
public static final Creator<Person> CREATOR = new Creator<Person>() {
@Override
public Person createFromParcel(Parcel arg0) {
// TODO Auto-generated method stub
return new Person(arg0.readString(), arg0.readInt());
}
@Override
public Person[] newArray(int arg0) {
// TODO Auto-generated method stub
return new Person[arg0];
}
};
}
- 创建 AIDL 文件,并编译(Build->Make Project)
// Person.aidl
package com.strugglelin.demo.aidl;
parcelable Person;
// IPersion.aidl
package com.strugglelin.demo.aidl;
import com.strugglelin.demo.aidl.Person;
interface IPerson{
Person getPerson();
}
// ITest.aidl
package com.strugglelin.demo.aidl;
interface ITest{
int getNumber();
}
- 创建远程服务 Service
public class AidlService extends Service {
@Override
public void onCreate() {
Log.e("tag", "onCreate");
}
@Override
public boolean onUnbind(Intent intent) {
Log.e("tag", "onUnbind");
return true;
}
@Override
public void onDestroy() {
Log.e("tag", "onDestroy");
}
TestBinder bind = new TestBinder();
ComplexBinder cbind = new ComplexBinder();
private static final String PACKAGE_SAYHI = "com.strugglelin.client";
private static final int FLAG_TEST_BINDER = 0;
private static final int FLAG_COMPLEX_BINDER = 1;
@Override
public IBinder onBind(Intent arg0) {
Log.e("tag", "onBind");
Bundle bundle = arg0.getExtras();
if (bundle.getInt("flag") == FLAG_TEST_BINDER) {
return bind;
} else if (bundle.getInt("flag") == FLAG_COMPLEX_BINDER) {
return cbind;
}
return null;
}
public class TestBinder extends com.strugglelin.demo.aidl.ITest.Stub {
Random rnd = new Random();
@Override
public int getNumber() throws RemoteException {
return rnd.nextInt(100);
}
}
public class ComplexBinder extends com.strugglelin.demo.aidl.IPerson.Stub {
@Override
public Person getPerson() throws RemoteException {
return new Person("AAA", 123);
}
/**
* 在这里可以做权限认证,return false意味着客户端的调用就会失败,比如下面,只允许包名为com.strugglelin.client 的客户端通过,其他apk将无法完成调用过程
*/
@Override
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
throws RemoteException {
String packageName = null;
String[] packages = AidlService.this.getPackageManager().
getPackagesForUid(getCallingUid());
if (packages != null && packages.length > 0) {
packageName = packages[0];
}
Log.e("tag", "onTransact: " + packageName);
if (!PACKAGE_SAYHI.equals(packageName)) {
return false;
}
return super.onTransact(code, data, reply, flags);
}
}
}
- AndroidManifest.xml 注册服务
<service
android:name="com.strugglelin.demo.service.AidlService"
android:process=":remote"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="com.strugglelin.demo.service.AidlService"/>
</intent-filter>
</service>
2、客户端
- 将服务端的 AIDL 文件复制到客户端。
- 绑定远程服务通信。
public class MainActivity extends AppCompatActivity {
private Button mBindServiceBtn, mGetDataBtn, mUnbindServiceBtn;
private boolean isConnected = false;
public static final int FLAG = 1;
ITest binder;
IPerson pbind;
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceDisconnected(ComponentName arg0) {
Log.e("tag", "断开连接");
}
@SuppressWarnings("unused")
@Override
public void onServiceConnected(ComponentName arg0, IBinder arg1) {
// 服务器建立连接
Object obj = IPerson.Stub.asInterface(arg1);
if (FLAG == 0) {
binder = ITest.Stub.asInterface(arg1);
Log.e("tag", "ITest建立连接");
} else {
pbind = IPerson.Stub.asInterface(arg1);
Log.e("tag", "IPerson建立连接");
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBindServiceBtn = findViewById(R.id.mBindServiceBtn);
mGetDataBtn = findViewById(R.id.mGetDataBtn);
mUnbindServiceBtn = findViewById(R.id.mUnbindServiceBtn);
mBindServiceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// 方法一 1.通过action和包名设置
Intent intent = new Intent("com.strugglelin.demo.service.AidlService").setPackage("com.strugglelin.demo");
intent.putExtra("flag", FLAG);
// 方法二 2.通过包名和类名设置
// Intent service = new Intent();
// service.setComponent(new ComponentName("com.strugglelin.demo","com.strugglelin.demo.service.AidlService"));
isConnected = bindService(intent, conn, BIND_AUTO_CREATE);
Log.e("tag", "绑定成功");
}
});
mGetDataBtn.setOnClickListener(new OnClickListener() {
@SuppressWarnings("unused")
@Override
public void onClick(View arg0) {
try {
if (FLAG == 0) {
Log.e("tag", binder.getNumber() + "");
} else {
if (null != pbind) {
Person p = pbind.getPerson();
if (null != p) {
Log.e("tag", pbind.getPerson().getName());
} else {
Log.e("tag", "Person null");
}
} else {
Log.e("tag", "IPerson null");
}
}
} catch (RemoteException e) {
Log.e("tag", "异常");
e.printStackTrace();
}
}
});
mUnbindServiceBtn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
if (isConnected) {
unbindService(conn);
isConnected = false;
}
}
});
}
}