Android AIDLの基本的な使い方
14212 ワード
一、概要本論文では、基本的なaidl使用方法によるプロセス間通信の実現について述べ、その後、自分の書いたサービスをシステムサービスに加入すれば、システムアプリケーションに提供して使用し、典型的なケースではロックを適用することについて述べる.
二、構想1を作成し、サーバー側はaidlと伝達されたbeanクラスを定義し、それから具体的なaidl実装クラスを作成し、onBindメソッドで実装されたbinderクラスオブジェクトを返す新しいサービスを作成する.2、クライアントはサービス側定義のaidlおよび関連クラスを新規作成する必要があり、サーバ側はaidlおよび関連クラスを1つのパッケージに定義することを提案する.クライアントが使用するときとコピーします.三、符号化具体実現demo
1、サーバー側*1、mainの下にaidiフォルダを新規作成し、パッケージを新規作成し、Bookを定義する.JAvaクラス、Parcelableインタフェースを実現し、コードは以下の通りである.
2、aidlインタフェースを新しくして、私がここで新しく作ったのはIBookManagerです.aidlは、使用するエンティティクラスをインポートし、対応するaidlファイルを作成する2つのメソッドを定義します.ここではBookクラスを使用してBookを定義します.aidl.
3、Book.aidlコードは以下の通りです.
4、サービス側はサービスクラスを書き、binder実装クラスを書く必要があります.コードは以下の通りです.
2、クライアント1、サーバ側aidlのパケットを直接コピーし、サーバ側のサービスをバインドしてインタフェースオブジェクトを取得する.コードは次のとおりです.
四、aidlの基本的な使い方は以上のように、多くの読者が私と同じように、最初に接触したときに困惑すると信じています.なぜこんなに面倒なのか、実はaidlはプロセス間のマルチスレッドを実現するために、普段の日常応用開発ではプロセス間通信を必要としませんが、システム開発では非常に重要です.binderはandroidがプロセス間通信を実現する特有の方法であるため、SystemServerプロセスにおけるサービスはすべてbinder方式で通信するものであり、例えばActivityManagerServiceなど、app開発においてContent.getSystemService(")の方法でシステムサービス側を取得する例はbinderプロセス間通信ですが、ここのプロセスはSystemServerプロセスと私たちのAPPプロセスが通信しているだけです.
二、構想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プロセスが通信しているだけです.