3

私は AOSP をいじっていて、System Services について何かに気づきました。それらの多くは、次のようにシステム サービス スタブに直接アクセスすることを好みます。

IDevicePolicyManager dpm = IDevicePolicyManager.Stub.asInterface(
                ServiceManager.getService(Context.DEVICE_POLICY_SERVICE));

これは、次のように mContext を使用してリクエストする代わりに行われます。

DevicePolicyManager dpm = (DevicePolicyManager)  
     context.getSystemService(Context.DEVICE_POLICY_SERVICE);

最初は、利用可能なコンテキストがないためかもしれないと思っていましたが、あります。この優れた例は、PackageManagerService クラスの一部である deletePackageX メソッドにあります。スタブ メソッドを getSystemService メソッドに変更すると、すべてが正常に動作するように見えます。

アプリがスタブ方式を使えないのには当然セキュリティ上の理由がありますが、システムサービスにスタブ方式を使っているのには何らかの理由があるはずです。

問題は、他のシステム サービスを取得するために、コンテキストを介してスタブを使用する理由です。

4

1 に答える 1

1

そのため、ContextImpl.java を掘り下げて getSystemService 呼び出しが何を行っているかを確認した後、実際には、システム サービスでよく見られる Stub.asInterface 呼び出しの単なるラッパーにすぎません。そのため、システム サービスを作成し、それを SDK に公開する場合は、それをコンテキストに登録して、システム以外のアプリがハンドルを取得できるようにする必要があります。登録は、ほとんどのサービスで次のようになります。

registerService(ALARM_SERVICE, new ServiceFetcher() {
                public Object createService(ContextImpl ctx) {
                    IBinder b = ServiceManager.getService(ALARM_SERVICE);
                    IAlarmManager service = IAlarmManager.Stub.asInterface(b);
                    return new AlarmManager(service, ctx);
                }});

おなじみですか?ただし、システム サービスを取得すると、サービス フェッチャーはサービスをキャッシュするなどの他のオーバーヘッドを実行するため、後続の呼び出しでサービスをより迅速に取得できます。(詳しく調べていないオーバーヘッドがありますが、最適化のためだと思います)

したがって、基本的には、スタブを介してサービスを直接取得することで、オーバーヘッドを節約し、コンテキストを通過する場合よりも高速に操作を実行できます。コンテキストは、システム以外のアプリからサービスにアクセスできるようにするためだけにあり、SDK を介して公開する必要があります。しかし、最終的には同じコードが実行されます。

システム アプリの場合は、スタブ経由でサービスを取得する方がおそらく高速です。

于 2013-11-22T19:40:15.560 に答える