Android AIDLの基本的な使い方


一、概要本論文では、基本的なaidl使用方法によるプロセス間通信の実現について述べ、その後、自分の書いたサービスをシステムサービスに加入すれば、システムアプリケーションに提供して使用し、典型的なケースではロックを適用することについて述べる.
二、構想1を作成し、サーバー側はaidlと伝達されたbeanクラスを定義し、それから具体的なaidl実装クラスを作成し、onBindメソッドで実装されたbinderクラスオブジェクトを返す新しいサービスを作成する.2、クライアントはサービス側定義のaidlおよび関連クラスを新規作成する必要があり、サーバ側はaidlおよび関連クラスを1つのパッケージに定義することを提案する.クライアントが使用するときとコピーします.三、符号化具体実現demo
1、サーバー側*1、mainの下にaidiフォルダを新規作成し、パッケージを新規作成し、Bookを定義する.JAvaクラス、Parcelableインタフェースを実現し、コードは以下の通りである.
package com.android.topwise.applock;

import android.os.Parcel;
import android.os.Parcelable;

public class Book implements Parcelable {

    public int bookId;
    public String bookName;
    public Book(int id, String name) {
        this.bookId = id;
        this.bookName = name;
    }
    public Book() {
    }

    protected Book(Parcel in) {
        bookId = in.readInt();
        bookName = in.readString();
    }

    public static final Creator CREATOR = new   Creator() {
        @Override
        public Book createFromParcel(Parcel in) {
            return new Book(in);
        }

        @Override
        public Book[] newArray(int size) {
            return new Book[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(bookId);
        parcel.writeString(bookName);
    }
}

2、aidlインタフェースを新しくして、私がここで新しく作ったのはIBookManagerです.aidlは、使用するエンティティクラスをインポートし、対応するaidlファイルを作成する2つのメソッドを定義します.ここではBookクラスを使用してBookを定義します.aidl.
// IBookManager.aidl
package com.android.topwise.applock;

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

import com.android.topwise.applock.Book;

interface IBookManager {
    /**
     * 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);

    void addBook(in Book  book);
    List getBookList();
}

3、Book.aidlコードは以下の通りです.
// Book.aidl
package com.android.topwise.applock;
parcelable Book;

4、サービス側はサービスクラスを書き、binder実装クラスを書く必要があります.コードは以下の通りです.
package com.android.topwise.applock;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
import java.util.ArrayList;
import java.util.List;

public class BookService extends Service {


    private List books  = new ArrayList<>();

    public BookService() {
    }
    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
         return  new MyBookManager();
    }
    private final class  MyBookManager extends IBookManager.Stub
    {


        @Override
        public void basicTypes(int anInt, long aLong, boolean aBoolean, float aFloat, double aDouble, String aString) throws RemoteException {

        }

        @Override
        public void addBook(Book book) throws RemoteException {
                     books.add(book);
        }

        @Override
        public List getBookList() throws RemoteException {


            return books;
        }
    }
}

2、クライアント1、サーバ側aidlのパケットを直接コピーし、サーバ側のサービスをバインドしてインタフェースオブジェクトを取得する.コードは次のとおりです.
package com.android.topwise.applock;

import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

import java.util.List;

import butterknife.Bind;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {

    @Bind(R.id.id_tv_show)
    TextView idTvShow;
    @Bind(R.id.id_btn_add)
    Button idBtnAdd;
    @Bind(R.id.id_btn_get)
    Button idBtnGet;
    private IBookManager mIBookManager;


    private ServiceConnection mServiceConnection = new ServiceConnection() {

        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mIBookManager = IBookManager.Stub.asInterface(iBinder);

        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);
        Intent intent = new Intent("com.android.topwise.applock.IBookManager");
        Intent intentHide = createExplicitFromImplicitIntent(this, intent);
        bindService(intentHide, mServiceConnection, Context.BIND_AUTO_CREATE);

    }

   //                   Intent
    public Intent createExplicitFromImplicitIntent(Context context, Intent implicitIntent) {
        // Retrieve all services that can match the given intent
        PackageManager pm = context.getPackageManager();
        List resolveInfo = pm.queryIntentServices(implicitIntent, 0);

        // Make sure only one match was found
        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(implicitIntent);

        // Set the component to be explicit
        explicitIntent.setComponent(component);

        return explicitIntent;
    }


    @OnClick({R.id.id_btn_add, R.id.id_btn_get})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.id_btn_add:
                Book book = new Book(0, "     ");
                try {
                    mIBookManager.addBook(book);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
                break;
            case R.id.id_btn_get:

                try {
                    List books = mIBookManager.getBookList();
                    if (books.size() > 0) {
                        idTvShow.setText(books.get(0).bookName);
                    }

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

四、aidlの基本的な使い方は以上のように、多くの読者が私と同じように、最初に接触したときに困惑すると信じています.なぜこんなに面倒なのか、実はaidlはプロセス間のマルチスレッドを実現するために、普段の日常応用開発ではプロセス間通信を必要としませんが、システム開発では非常に重要です.binderはandroidがプロセス間通信を実現する特有の方法であるため、SystemServerプロセスにおけるサービスはすべてbinder方式で通信するものであり、例えばActivityManagerServiceなど、app開発においてContent.getSystemService(")の方法でシステムサービス側を取得する例はbinderプロセス間通信ですが、ここのプロセスはSystemServerプロセスと私たちのAPPプロセスが通信しているだけです.