手当たり次第に入手可能なアプリケーションの対象

2229 ワード

Androidの開発では、ApplicationオブジェクトとContextオブジェクトが私たちが最も接触しているオブジェクト、特にContextオブジェクトであるはずです.
ActivityまたはServiceのいずれかにある場合、それら自体がContextのサブクラスであるため、「this」はContextオブジェクトと同等に使用できます.しかし、このContextはそれほど手当たり次第ではない場合が多いので、以下の状況を考えてみましょう.
  • はContextのSDKを使用する必要があり、開発者はSDKを使用するためにContextの伝達コードを追加する必要がある.
  • 二次パッケージのプラグインコードContextを使用する必要がある場合は、元の論理を修正し、Contextを渡す必要があります.
  • がJava環境に注入された後、Contextを使用して、各種IPCのサービスにアクセスする必要がある.
  • したがって,従来の論理に触れずに現在のプロセスのApplicationオブジェクトを取得できる方法が見つかれば,上述した問題は解決できる.ここでは、カスタムアプリケーションクラスを作成する場合など、静的メソッドgetContext(または他の類似の名前)を追加するのが一般的です.
    class final MyApplication extends Application{
        private static Application sInstance;
    
        @Override
        public void onCreate(){
            sInstance = this;
        }
    
        public static Application getContext(){
            return sInstance;
        }
    
        //...
        //...
    }

    このコードは、後でContextを使うときに使うのが便利で、Applicationはグローバルなので、内在的な漏洩を防ぐことができます.しかし、このようにしないで、カスタムアプリケーションがない場合でも、このアプリケーションオブジェクトを手に入れることができるようにするにはどうすればいいのでしょうか.
    実は今回の乾物は多くありませんが、ここでは1.6から5.1に互換性がある方法を提供します(その後のファームウェアも互換性があるはずです).
    主に反射によって、システムクラスの静的フィールドを取得します.プロセスは次のとおりです.
  • RuntimeInitクラスを介して、android型のmApplicationObject静的フィールドを取得する.app.ActivityThread$ApplicationThread;
  • ApplicationThreadクラスを通じてthis$0フィールドを取得し、これはコンパイラが生成したものであり、このフィールドのタイプはandroidであることに注意する.app.ActivityThread;
  • Activity Threadクラスを通じて、そのmInitialApplicationフィールドを取得します.このフィールドはApplicationオブジェクトです.

  • 反射呼び出しにかかわるので、完全なコードは書かないで、簡単な偽コードを書きましょう.
    Applicatioin app = RuntimeInit.mApplicationObject.this$0.mInitialApplication;

    これは唯一の方法ではないことは間違いありません.皆さん、何かいい方法がありますか.共有を歓迎します.