AIDL(1)--定義以及簡單使用

AIDL

AIDL:Android 接口定義語言 (AIDL) 與您可能使用過的其他接口語言 (IDL) 類似。您可以利用它定義客戶端與服務均認可的編程接口,以便二者使用進程間通信 (IPC) 進行相互通信。在 Android 中,一個進程通常無法訪問另一個進程的內存。因此,爲進行通信,進程需將其對象分解成可供操作系統理解的原語,並將其編組爲可供您操作的對象。編寫執行該編組操作的代碼較爲繁瑣,因此 Android 會使用 AIDL 爲您處理此問題。

注意:只有在需要不同應用的客戶端通過 IPC 方式訪問服務,並且希望在服務中進行多線程處理時,您纔有必要使用 AIDL。如果您無需跨不同應用執行併發 IPC,則應通過實現 Binder 來創建接口;或者,如果您想執行 IPC,但不需要處理多線程,請使用 Messenger 來實現接口。無論如何,在實現 AIDL 之前,請您務必理解綁定服務。

您可以通過 IPC 接口,將某個類從一個進程發送至另一個進程。不過,您必須確保 IPC 通道的另一端可使用該類的代碼,並且該類必須支持 Parcelable 接口。支持 Parcelable 接口很重要,因爲 Android 系統能通過該接口將對象分解成可編組至各進程的原語。在第二部分介紹這塊.

代碼結構

在這裏插入圖片描述

demo

aidl文件:

// IMyAidlInterface.aidl
package com.example.buringteng.myapplication;

// Declare any non-default types here with import statements

interface IMyAidlInterface {
    /**
     * Demonstrates some basic types that you can use as parameters
     * and return values in AIDL.
     */
    void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
            double aDouble, String aString);
}

AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.buringteng.myapplication">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name=".RemoteService"
            android:enabled="true"
            android:exported="true" >

        </service>

    </application>

</manifest>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    //The interface will be calling in service
    IMyAidlInterface iRemoteService = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        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();
                Intent intent = new Intent(MainActivity.this,RemoteService.class);
               intent.setAction(IMyAidlInterface.class.getName());
               bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
            }
        });
    }
    private ServiceConnection mConnection = new ServiceConnection() {
        // Called when the connection with the service is established
        public void onServiceConnected(ComponentName className, IBinder service) {
            Log.e("aidl test", "Service connected");
            // Following the example above for an AIDL interface,
            // this gets an instance of the IMyAidlInterface, which we can use to call on the service
            iRemoteService = IMyAidlInterface.Stub.asInterface(service);
         //   iRemoteService.basicType;
            try {
                iRemoteService.basicTypes(1, 2L,false, 7.72f,
                6.77f, "Hello world");
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        }
        // Called when the connection with the service disconnects unexpectedly
        public void onServiceDisconnected(ComponentName className) {
            Log.e("aidl test", "Service has unexpectedly disconnected");
            iRemoteService = null;
        }
    };

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

}

RemoteService.java

public class RemoteService extends Service {
    @Override
    public void onCreate() {
        super.onCreate();
    }
    @Override
    public IBinder onBind(Intent intent) {
        // Return the interface
        Log.e("onBind", "invoke");
        return binder;
    }

   private final IMyAidlInterface.Stub binder = new IMyAidlInterface.Stub() {
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat,
                               double aDouble, String aString){
            Log.e("Stub test", ""+anInt);
        }
    };
}

補充

        <service
            android:name=".RemoteService"
            android:enabled="true"
            android:exported="true" >

android:enable 用於執行service能否被實例化
android.exported 用於制定其他應用程序組件能否調用service或者與其交互.true表示能,false表示不能.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章