AIDL簡(jiǎn)介
AIDL是AndroidInterface definition language的縮寫(xiě),它是一種Android內(nèi)部進(jìn)程通信接口的描述語(yǔ)言。
AIDL使用場(chǎng)景
例如有兩個(gè)應(yīng)用應(yīng)用A和應(yīng)用K,我們?cè)趹?yīng)用A中綁定了一個(gè)Service限佩,并且給對(duì)應(yīng)的數(shù)據(jù)成員設(shè)置了一些值。而我們想要在應(yīng)用K中得到應(yīng)用A設(shè)置的值馋嗜,Android平臺(tái)是不允許不同進(jìn)程間進(jìn)行直接通訊的而且不同進(jìn)程之間也不能通過(guò)共享內(nèi)存的方式進(jìn)行數(shù)據(jù)通訊麸俘,為了使其他的應(yīng)用K可以訪問(wèn)應(yīng)用A提供的服務(wù)辩稽,AIDL就應(yīng)運(yùn)而生。
AIDL使用注意事項(xiàng)
AIDL只支持方法从媚,不能定義靜態(tài)成員逞泄,并且方法也不能有類似public等的修飾符;AIDL運(yùn)行方法有任何類型的參數(shù)和返回值拜效,AIDL支持的數(shù)據(jù)類型有Java基本數(shù)據(jù)類型喷众、String、Map紧憾、List到千。List中的所有元素必須是AIDL支持的類型之一,或者是一個(gè)其他AIDL生成的接口赴穗,或者是定義的Parcelable憔四,List可以使用泛型。Map中的所有元素必須是AIDL支持的類型之一般眉,或者是一個(gè)其他AIDL生成的接口了赵,或者是定義的Parcelable,Map是不支持泛型的甸赃。
應(yīng)用A創(chuàng)建AIDL的步驟
1.新建aidl文件夾柿汛,如下圖:
2.新建*.aidl文件络断,如下圖:
3.定義生成的aidl文件內(nèi)容妓羊,代碼定義如下:
interface IMyAidlInterface {
void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString);
int getanInt();
long getaLong();
boolean getaBoolean();
float getaFloat();
double getaDouble();
String getaString();
}
4.繼承AIDL文件生成的Java接口Stub,并添加相應(yīng)的代碼實(shí)現(xiàn):
public class BaseDataType extends IMyAidlInterface.Stub {
int anInt;
long aLong;
boolean aBoolean;
float aFloat;
double aDouble;
String aString;
@Override
public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {
this.anInt = anInt;
this.aLong = aLong;
this.aBoolean = aBoolean;
this.aFloat = aFloat;
this.aDouble = aDouble;
this.aString = aString;
}
@Override
public int getanInt() throws RemoteException {
return anInt;
}
@Override
public long getaLong() throws RemoteException {
return aLong;
}
@Override
public boolean getaBoolean() throws RemoteException {
return aBoolean;
}
@Override
public float getaFloat() throws RemoteException {
return aFloat;
}
@Override
public double getaDouble() throws RemoteException {
return aDouble;
}
@Override
public String getaString() throws RemoteException {
return aString;
}
}
PS:IMyAidlInterface.aidl與BaseDataType.java的包名應(yīng)當(dāng)是一樣的稍计。若想要不一樣躁绸,請(qǐng)按以下修改build.gradle文件,在 android{} 中間加上下面的內(nèi)容
sourceSets {
main { java.srcDirs = ['src/main/java', 'src/main/aidl']
}
}
5.定義一個(gè)Service,并將其注冊(cè)到AndroidManifest.xml文件中:
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class MyRemoteService extends Service {
IMyAidlInterface.Stub iStub = new BaseDataType();
public MyRemoteService() {
}
@Override
public IBinder onBind(Intent intent) {
return iStub;
}
}
<service android:name=".MyRemoteService"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="MyRemoteAIDL" > </action>
</intent-filter>
</service>
6.在應(yīng)用A內(nèi)設(shè)置值:
public class MyRemoteActivity extends AppCompatActivity {
IMyAidlInterface iMyAidlInterface;
View bind;
View unbind;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_remote);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG).setAction("Action", null).show();
}
});
bind = findViewById(R.id.bind);
unbind = findViewById(R.id.unbind);
bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MyRemoteActivity.this, MyRemoteService.class);
bindService(intent, conn, Context.BIND_AUTO_CREATE);
}
});
}
ServiceConnection conn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
iMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
if (iMyAidlInterface != null) {
try {
iMyAidlInterface.basicTypes(1024, 2048L, true, 3.14159F, 3.1415926D, "I come from MyRemoteService");
android.util.Log.d("RemoteValue", "Set value success!");
} catch (Exception e) {
android.util.Log.d("RemoteValue", "Set value fail!");
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
android.util.Log.d("RemoteValue", "onServiceDisconnected " + name);
}
};
}
至此臣嚣,同一應(yīng)用內(nèi)調(diào)用已經(jīng)完成净刮。
接下來(lái)就是被其它應(yīng)用調(diào)用,也就是我們實(shí)例中的應(yīng)用K調(diào)用硅则。
應(yīng)用K訪問(wèn)應(yīng)用A中的數(shù)據(jù)步驟
1.將應(yīng)用A的aidl文件拷貝一份到應(yīng)用K的程序中(這里一定要注意淹父,包路徑要和應(yīng)用A中的保持一致):
2.應(yīng)用K訪問(wèn)應(yīng)用A中的數(shù)據(jù)
public class MainActivity extends Activity {
IMyAidlInterface myAidlInterface;
View bind;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bind = findViewById(R.id.bind);
bind.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("MyRemoteAIDL");
//此處設(shè)置應(yīng)用A的包名
intent.setPackage("qihoo.testcodedemo");
Intent newIntent = buildExplicitIntent(MainActivity.this, intent);
boolean isbind = getApplicationContext().bindService(newIntent, connection, Context.BIND_AUTO_CREATE);
}
});
}
public Intent buildExplicitIntent(Context context, Intent intent) {
PackageManager pm = context.getPackageManager();
List<ResolveInfo> resolveInfo = pm.queryIntentServices(intent, 0);
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(intent);
// Set the component to be explicit
explicitIntent.setComponent(component);
return explicitIntent;
}
ServiceConnection connection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
myAidlInterface = IMyAidlInterface.Stub.asInterface(service);
if (myAidlInterface != null) {
try {
android.util.Log.e("RemoteService", " " + myAidlInterface.getanInt());
android.util.Log.e("RemoteService", myAidlInterface.getaString());
} catch (Exception e) {
}
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
}
PS:將兩個(gè)App同時(shí)運(yùn)行在同一臺(tái)手機(jī)上怎虫,可訪問(wèn)正確的數(shù)據(jù)值暑认;
至此困介,通過(guò)AIDL的方式進(jìn)行兩個(gè)不同App的數(shù)據(jù)訪問(wèn)已完成;
敬請(qǐng)各位童鞋關(guān)注本人微信公眾號(hào)“IT軟件人”蘸际,或掃碼關(guān)注座哩。
熱烈歡迎與各位童鞋進(jìn)行技術(shù)交流。