AIDL詳解1——簡單數據通信

看過官方文檔以及其他的博客和慕課網對AIDL的介紹,做了以下的整理,方便隨時查看:

AIDL介紹

AIDL(Android interface Definition Language,安卓接口定義語言),使用AIDL可以實現跨進程通信。

Android中的綁定服務有三種,分別是:擴展Binder類,Messenger,AIDL。

  • 擴展Binder類主要用於服務只是本應用的後臺工作線程。
  • Messenger實現跨不同的進程工作,是執行進程間通信 (IPC) 的最簡單方法,因爲 Messenger 會在單一線程中創建包含所有請求的隊列,服務一次接受一個請求,這樣就不必對服務進行線程安全設計。
  • AIDL用於跨進程通信,讓服務同時處理多個請求,需要服務具備多線程處理能力,採用線程安全式設計。

注意:只有運行不同應用的客戶端,用IPC訪問服務,並且想要在服務中處理多線程時,纔有必要使用AIDL。

AIDL創建

在Android Studio裏,直接在Java包上右擊,創建一個AIDL文件,就會自動生成aidl包,並創建了指定的aidl文件。
這裏寫圖片描述


這裏寫圖片描述


這裏寫圖片描述


完成aidl文件的創建後,點擊上方的這裏寫圖片描述
這樣就會自動生成相應的java類:
這裏寫圖片描述

AIDL實現

注意 AIDL中不能有修飾訪問符(public,private,protected),支持Java基本數據類型(除short,例如int,long,char等),支持String,CharSequence,List,Map。必須爲其他數據類型加入import語句。在方法參數使用時,所有非原語參數(我認爲是其他數據類型),要有in,out,inout來標記數據走向,默認爲in。(in表示客戶端的參數輸入,out表示服務端的參數輸入,inout表示客戶端可輸入、服務端也可輸入)


下面是使用AIDL進行簡單的數據傳輸:

在IMyAIDL中聲明一個方法,我們想要通過這個方法獲取字符串信息,修改完畢後點擊這個按鈕,Android SDK工具會生成aidl文件相應的java接口文件

這裏寫圖片描述

// IMyAIDL.aidl
package com.example.aidldemo;
interface IMyAIDL {
   String getMessage(String  s);
}

創建Service的類MyService,在Manifest中註冊Service:

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

我們通過SDK生成的java接口文件中包括一個名爲Stub的子類,這個子類是其父接口的抽象實現,用於聲明aidl文件中的所有方法。我們通過Service實現這個接口,向客戶端公開接口,以便客戶端進行綁定,這就需要通過onBinde方法了:

public class MyService extends Service {
    public MyService() {
    }

    @Override
    public IBinder onBind(Intent intent) {
       return  mbinder;
    }

    private final IMyAIDL.Stub mbinder = new IMyAIDL.Stub() {
        @Override
        public String getMessage(String s) throws RemoteException {
            return "收到消息"+s;//返回獲取到的內容
        }
    };

}

現在當客戶端調用bindService連接服務器,客戶端的OnServiceConnected()回調會接收服務的onBind()方法返回mbinder實例。Stub中定義了asInterface()方法,這個方法將IBinder傳遞給客戶端的onServiceConnected()。

 ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAIDL = IMyAIDL.Stub.asInterface(service);

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iMyAIDL = null;
        }
    };

完整代碼

public class MainActivity extends AppCompatActivity {
    private TextView textView ;
    private  EditText editText;
    private  IMyAIDL iMyAIDL;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = (TextView) findViewById(R.id.text);
        editText = (EditText) findViewById(R.id.edit);

        Intent intent = new Intent(MainActivity.this, MyService.class);
        bindService(intent, connection, Context.BIND_AUTO_CREATE);

    }

    ServiceConnection connection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            iMyAIDL = IMyAIDL.Stub.asInterface(service);

        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            iMyAIDL = null;
        }
    };

    public void startService(View view) {
        try {
           String message = iMyAIDL.getMessage(editText.getText().toString());
            textView.setText(message);

        } catch (RemoteException e) {
            e.printStackTrace();
        }
    }
}

佈局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.aidldemo.MainActivity">
    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edit"
        />
  <Button
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:onClick="startService"
      />
    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/text"
        />

</LinearLayout>

效果如圖
這裏寫圖片描述

發佈了43 篇原創文章 · 獲贊 13 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章