blog

アプリケーションからバインダーについて話す

バインダーにトップダウンで導入するには、その後、アプリケーション開発バインダーの存在が透明であるために、バインダーのコンポーネントの接触の日常的な開発から開始する必要があり、うっかりバインダーを介して...

Mar 11, 2020 · 5 min. read
シェア

はじめに

トップダウンでBinderを紹介するには、Binderの存在が透けて見えるため、アプリケーション開発の最初に接するBinderコンポーネントの日常的な開発から始める必要があり、うっかりBinderを介して一連の操作を完了してしまう可能性があるため、次に紹介するのは、アプリケーション開発とBinderとBinderの最も密接な関係にある部分を、Binder上の読者に知ってもらうためです。読者がシステムのバインダーの存在を予備的に理解することができるように、アプリケーション開発とバインダーに最も密接に関連する部分を紹介します。

Activity

アクティビティの起動は、私は最も頻繁に使用される機能の開発であるバインダーのシーンを使用することを考えたのは初めてですが、バインダーがどのような役割を果たしているかを確認するために、アクティビティの起動に飛び込むために私を次の外観は、アクティビティの特定の詳細で、特定の起動プロセスを気にしない、ちょうどバインダーの関連部分を見てすることができます。

~コードのビッグウェーブがまもなく到来

//frameworks/base/core/java/android/app/Activity.java
@Override
public void startActivity(Intent intent) {
 startActivity(intent, null);
}

このバーの理解は、アクティビティに位置し、多くの説明は、Intent、Intentのパラメータを渡すことは、コンポーネント間のパラメータを渡すために使用されていることを知っているが、より深い理解は、バインダレベルから、それはParcelableであり、その後Parcelableそれは何ですか?ここでまず簡単に言うと、Parcelableはインターフェイスであり、Parcelableを継承するということは、Parcelにオブジェクトデータを書き込むことができるということです。まあ、この目的のために、トピックに戻って、その背後にある記事の詳細な説明をしないでください。

//frameworks/base/core/java/android/app/Activity.java
public void startActivityForResult(Intent intent, int requestCode, Bundle options) {
 
 Instrumentation.ActivityResult ar =
 mInstrumentation.execStartActivity(
 this, mMainThread.getApplicationThread(), mToken, this,
 intent, requestCode, options);
 ....
}
//frameworks/base/core/java/android/app/Instrumentation.java
public ActivityResult execStartActivity(
 Context who, IBinder contextThread, IBinder token, Activity target,
 Intent intent, int requestCode, Bundle options) {
 
 int result = ActivityManagerNative.getDefault()
 .startActivity(whoThread, who.getBasePackageName(), intent,
 intent.resolveTypeIfNeeded(who.getContentResolver()),
 token, target != null ? target.mEmbeddedID : null,
 requestCode, 0, null, null, options);
 return null;
}

このActivityManagerNativeとは何でしょうか?最初に宣言しますが、実はここにも分割線があり、この分割線の上部はアプリケーションで、正確に言えば、アプリケーションのプロセスで、分割線の下部はBinder Serverのプロセスで、このプロセスはsystem_serverプロセスで、Binder Serverが多数あり、1つのプロセスが複数のBinder Serverである可能性があります ああ、Binder ServerがActivityの起動を完了します。サーバーああ、アクティビティは、バインダサーバーは、ActivityManagerServer、小さな名前AMSと呼ばれる起動を完了します。ここのビューの別の観点から、バインダC / Sプロセスかもしれませんが、また、システムレベルのアーキテクチャ、アプリケーション層/フレームワーク層にすることができます。ここでいわゆるIPCのクロスプロセス通信は、アプリケーションプロセスの開発からBinderサービスのシステムプロセスsystem_serverプロセスを呼び出すには、一連のトランザクションを完了し、戻り、アプリケーションプロセスのためのこのプロセスは、クラスメソッドを呼び出すようなプロセス通信を完了することができますつまり、無意味です、バインダぼやけたプロセスの境界。これらのバインダプロセス通信の詳細については、記事のこのシリーズの主なタスクは、雲の深い理解が実際に何が起こったかの間に霧を開くようになります。

service

//frameworks/base/core/java/android/app/ContextImpl.java
@Override
public ComponentName startService(Intent service) {
 warnIfCallingFromSystemProcess();
 return startServiceCommon(service, mUser);
}
@Override
public boolean bindService(Intent service, ServiceConnection conn,
 int flags) {
 warnIfCallingFromSystemProcess();
 return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}

サービスのスタートアップをもう一度見てみましょう。

private ComponentName startServiceCommon(Intent service, UserHandle user) {
 ...
 ComponentName = ActivityManagerNative.getDefault().startService(
 mMainThread.getApplicationThread(), service,
 service.resolveTypeIfNeeded(getContentResolver()), user.getIdentifier());
 ...
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, int flags,
 UserHandle user) {
 ...
 int res = ActivityManagerNative.getDefault().bindService(
 mMainThread.getApplicationThread(), getActivityToken(),
 service, service.resolveTypeIfNeeded(getContentResolver()),
 sd, flags, user.getIdentifier());
 ...
}

はい再びActivityManagerNative、目に見えるサービスの起動プロセスとAMSの間の関係も非常に大きなああ、同じの実装の具体的な詳細に注意を払っていない見慣れた顔を見ることではありませんが、ここで同じような分割行は、バインダーのC / Sエンドを分割します。フレームワークのリアルタイムでは、IPC通信にバインダを介してされるXXXNatvie.getDefaultなど、多くの同様のコードを見ることができます。

ブロードキャストの登録

//frameworks/base/core/java/android/app/ContextImpl.java
@Override
public Intent registerReceiver(BroadcastReceiver receiver, IntentFilter filter) {
 return registerReceiver(receiver, filter, null, null);
}

その後、4つのコンポーネントを終了することです放送を見て?その通りです、気の利いたお坊ちゃん、信じないかもしれませんが、BinderがAndroid IPCの骨格となるアーキテクチャだとどうして言えるのでしょう。これらは、私が本当に嘘をついていないと信じてもらうためです!

//frameworks/base/core/java/android/app/ContextImpl.java
private Intent registerReceiverInternal(BroadcastReceiver receiver, int userId,
 IntentFilter filter, String broadcastPermission,
 Handler scheduler, Context context) {
 ...
 return ActivityManagerNative.getDefault().registerReceiver(
 mMainThread.getApplicationThread(), mBasePackageName,
 rd, filter, broadcastPermission, userId);
 ...
}

もう一度言いますが、旧友の紹介はもう結構です。

ContentProvider

@Override
//frameworks/base/core/java/android/app/ContextImpl.java
public ContentResolver getContentResolver() {
 return mContentResolver;
}

ContentResolverは、ContentProviderのサービス・インターフェイスです。おわかりでしょう!

public final Cursor query(final Uri uri, String[] projection,
 String selection, String[] selectionArgs, String sortOrder,
 CancellationSignal cancellationSignal) {
 ....
 IContentProvider unstableProvider = acquireUnstableProvider(uri);
 ...
 stableProvider = acquireProvider(uri);
 ....
}

このクエリの動作をご覧ください。

 public final IContentProvider acquireProvider(
 Context c, String auth, int userId, boolean stable) {
 final IContentProvider provider = acquireExistingProvider(c, auth, userId, stable);
 ...
 try {
 holder = ActivityManagerNative.getDefault().getContentProvider(
 getApplicationThread(), auth, userId, stable);
 } catch (RemoteException ex) {
 }
 ...
}

今回も4つのコンポーネントを読んで、Binderと4つのコンポーネントには大きな関係があること、Binder Server側としてのAMSと4つのコンポーネントにも大きな関係があること、それは単にActivityコンポーネントとの関係だけではないことが理解できたと思います。まだBinderの顔は見えていませんが、次の一連の章では、このようにBinderの内容をより深く紹介していきます。

のまとめ

実際には4つ以上のコンポーネントがあり、ここでは最も代表的なBinder関連の開発コンポーネントをいくつかピックアップして紹介しますが、AIDL、一般的に使用されるgetSystemServiceメソッド、カメラのプレビュー、音楽の再生などといったものもあり、これらはBinderのサポートと切り離せません。プロセスがあります。

Read next

ES6 Essentials 06-セットとマップ

Set は配列に似たデータ構造で、メンバは一意であり、重複する値はありません。 Set 自体は、Set データ構造を生成するコンストラクタです。 add メソッドを使用してセットに値を追加すると、重複した値が再び追加されることはありません。このメソッドと配列マップメソッドの使用は、配列で強調する必要はありません。 値を追加し、Set 構造体に戻します。

Mar 11, 2020 · 3 min read