1. 程式人生 > >Android studio中的aidl

Android studio中的aidl

1.什麼是AIDL?

這是百度百科的定義:
AIDL:Android Interface Definition Language,即Android介面定義語言。 Android系統中的程序之間不能共享記憶體,因此,需要提供一些機制在不同程序之間進行資料通訊。為了使其他的應用程式也可以訪問本應用程式提供的服務,Android系統採用了遠端過程呼叫(Remote Procedure Call,RPC)方式來實現。 我們知道4個Android應用程式元件中的3個(Activity、BroadcastReceiver和ContentProvider)都可以進行跨程序訪問,另外一個Android應用程式元件Service同樣可以。因此,可以將這種可以跨程序訪問的服務稱為AIDL(Android Interface Definition Language)服務。
總之,AIDL就是通過服務來實現跨程序通訊。

2.服務。

服務作為Android中的四大元件之一,主要有兩種開啟方式。 start開啟方式:這種方式開啟的服務會常駐記憶體,在後臺執行,例如播放音樂,網路下載等等。 bind開啟方式:這種方式開啟的服務和開啟者不求同生,但求共死。服務會隨著呼叫者的銷燬二銷燬。

思考:既然已經有了start方式,為什麼還要有bind方式。

除了生命週期的差別外,bind方式可以讓我們呼叫服務中的方法。

3.遠端服務。

如果你已經熟練掌握了bind的方式呼叫服務中的方法,那麼AIDL你也能很容易的理解。 如果你對bind方式還不太瞭解,那麼也不會影響你對AIDL的操作。。。
a.首先建立一個遠端服務,也就是新建一個AS專案

b.選擇main->New->AIDL->AIDL File建立一個AIDL資料夾


此時會在main目錄下生產aidl檔案
開啟 IMyAidlInterface.aidl檔案,可以看到
其中basicTypes就是呼叫遠端服務中的方法,我們可以自己定義這個方法
這時候選擇Build-->Make Project 可以看到在build目錄下回生成
開啟可以看到
其中Stub繼承Binder,也就是說Stub是bind服務中的那個中間人物件

c.建立遠端服務

public class 
RemoteService extends Service { @Nullable @Override public IBinder onBind(Intent intent) { return new MyBinder();//返回中間人物件 } /** * 中間人的類 */ public class MyBinder extends IMyAidlInterface.Stub{ @Override public void callRemoteMethod() throws RemoteException { //呼叫服務中的方法 remoteMethod(); } } Handler mHandler = new Handler(); //定義服務中的方法 private void remoteMethod() { mHandler.post(new Runnable() { @Override public void run() { Toast.makeText(getApplicationContext(), "這是遠端服務中的方法", Toast.LENGTH_SHORT).show(); } }); } }

d.在AndroidManifest中配置服務

<service android:name=".RemoteService">
    <intent-filter>
        <action android:name="com.zhouxin.remoteService"/>
    </intent-filter>
</service>

4.本地app

再建立一個as專案,用於呼叫遠端服務中的方法 將遠端服務專案中的main目錄下的aidl目錄複製到本地app的main目錄下,然後Build-->Make Porject 在build目錄下生成和遠端服務一樣的東西
在本地app中寫兩個按鈕用於測試
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.zhuoxin.localapp.MainActivity">
    <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="bind服務"
android:onClick="bindService"/>
    <Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="呼叫遠端服務中方法"
android:onClick="callRemoteMethod"/>
</LinearLayout>

在MAinActivity中程式碼如下:
public class MainActivity extends AppCompatActivity {
    private IMyAidlInterface mIMyAidlInterface;
@Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}

    /**
     * 繫結服務
     * @param view
*/
public void bindService(View view){
        Intent mIntent = new Intent();
mIntent.setAction("com.zhouxin.remoteService");
bindService(mIntent,new MyServiceConnection(),BIND_AUTO_CREATE);
}

    /**
     * 呼叫服務中的方法
     * @param v
*/
public void callRemoteMethod(View v){
        try {
            mIMyAidlInterface.callRemoteMethod();
} catch (RemoteException e) {
            e.printStackTrace();
}
    }

    class MyServiceConnection implements ServiceConnection{



        /**
         * 服務連線成功時呼叫
         * @param name
* @param service
*/
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
            mIMyAidlInterface = IMyAidlInterface.Stub.asInterface(service);
}

        /**
         * 服務斷開時呼叫
         * @param name
*/
@Override
public void onServiceDisconnected(ComponentName name) {

        }
    }
}

4.測試結果

先執行RemoteService,在執行LocalApp 先繫結服務 在呼叫服務中的方法
prefect!!!