『Android開発芸術探索』読書ノート---第二章:Android IPCプロフィール、マルチプロセスモデル


Android IPCの概要
  • 定義IPCはInter-Process Communicationの略であり、プロセス間通信またはプロセス間通信を意味し、2つのプロセス間でデータを交換するプロセスを指す.
  • プロセスとスレッドは、オペレーティングシステムの説明に従って、スレッドはCPUスケジューリングの最小ユニットであり、スレッドは限られたシステムリソースである.プロセスは一般に実行ユニットを指し、PCおよびモバイルデバイス上でプログラムまたはアプリケーションを指す.1つのプロセスに複数のスレッドを含めることができるため、プロセスとスレッドは含まれる関係を含む.Androidでは、メインスレッドもUIスレッドと呼ばれ、UIスレッドではインタフェース要素を操作できます.
  • ANR例外(Application Not Responding)プロセスが大量の時間のかかるタスクを実行する場合、これらのタスクをメインスレッドに配置して実行すると、インタフェースが応答できなくなりやすくなります.すなわち、アプリケーションが応答せず、ANRが異常になります.

  • IPCはAndroid特有のものではなく、Windows上でクリップボード、パイプ、メールスロットなどを通じてプロセス間通信を行うことができるなど、どのオペレーティングシステムにも応答するIPCメカニズムが必要です.Linuxでは,パイプの命名,共有メモリ,信号量などによりプロセス間通信が可能である.異なるオペレーティングシステムには異なるプロセス間通信方式があり、AndroidにとってはLinuxカーネルベースのモバイルオペレーティングシステムであり、独自のプロセス間通信方式もある.Androidで最も特徴的なプロセス間通信方式はBinderで、Binderで簡単にプロセス間通信が実現できます.またSocketでも任意の2つの端末間の通信が実現できます.もちろん、同じデバイス上の2つのプロセスでもSocketで通信できます.
  • マルチプロセスの場合は2つに分けられる:1.1つのアプリケーションは、特定の理由で個別のプロセスで実行する必要があるモジュールや、1つのアプリケーションのメモリを増やすためにマルチプロセスによって複数のメモリ領域を取得するモジュールなど、いくつかの理由でマルチプロセスモードを採用する必要がある.Androidは、単一アプリケーションで使用できる最大メモリ容量を制限しており、初期は16 MBだった可能性があり、デバイスによって異なる.2.現在のアプリケーションが他のアプリケーションにデータを取得するには、2つのアプリケーションであるため、マルチプロセス間通信を採用する必要があり、システムのContentProviderを使用してデータを照会する場合も、実は1つのプロセス間通信である.

  • Androidでのマルチプロセスモード
    Androidの4つのコンポーネントにandroid:processプロパティを設定することで、マルチプロセスモードを簡単に開くことができますが、使用中に未知のエラーが多く発生することがあります.
  • マルチプロセスモードAndroidをオンにするマルチプロセスとは、1つのアプリケーション内の複数のプロセスの場合を指すので、ここでは2つのアプリケーション間のマルチプロセスの場合については説明しない.Androidでマルチプロセスを使用するには、4つのコンポーネントにMenifestファイルにprocessプロパティを指定する方法しかありません.スレッドまたはエンティティクラスに実行時のプロセスを指定することはできません.もう1つの非常に規則的な方法:JNIによってnative層でforkの新しいプロセスを除去し、特殊な状況に属する.
  • <activity  android:name=".SecondActivity" android:process="com.gechao.test.one" />
     <activity  android:name=".ThirdActivity" android:process=":one" />

    2つのActivityが起動すると、システムはそれぞれ1つのプロセスを作成し、1つのデフォルトのプロセスを加えると、3つのプロセスがあり、デフォルトのプロセス名はパッケージ名で、DDMSでプロセス情報を表示することができます.
    上でプロセスを指定すると、次の2つの書き方が表示されます.
  • 第1種は完全な書き方で、com.gechao.test.one
  • の2つ目は省略の書き方で、結果は:com.gechao.test:oneは、前に完全なパッケージ名
  • を追加します.
  • では、最初のプロセスは現在のアプリケーションのプライベートプロセスに属し、他のアプリケーションとコンポーネントは同じプロセスに走ることができず、最初の書き方のプロセスはグローバルプロセスに属し、他のアプリケーションはShareUID方式で同じプロセスに走ることができる.

  • マルチプロセスモードの実行メカニズム
    アプリケーションがマルチプロセスを開くと、多くの奇妙な現象が発生します.ActivityをSecondActivityとして追加し、publicの静的変数が格納された新しいプロセスを指定すると、
    public class Manager {
        public static int Uid = 1;
    }
  • その後、MainActivityのonCreateメソッドでUidの値を2に変更し、SecondActivityを起動してUidの値を印刷すると、Uidの値が1なのか、それとも1なのかがわかります.通常の論理では、静的変数はすべての場所で共有され、各箇所の変更は同期されます.通常の理解では、Uidの値は2に変更されているはずです.
  • この問題は、SecondActivityが個別のプロセスで実行されているためです.Androidはアプリケーションごとに独立した仮想マシンを割り当てたり、プロセスごとに独立した仮想マシンを割り当てたりして、異なる仮想マシンがメモリ割り当てに異なるアドレスを持っていることを知っています.これにより、異なる仮想マシンで同じクラスのオブジェクトにアクセスすると複数のコピーが生成されます.この例では、プロセス名がパッケージ名であるデフォルトのプロセスがあります.SecondActivityには別々のプロセスがあり、両方のプロセスにはマネージャクラスが存在し、両方のクラスが干渉せず、同じプロセスでUIDの値を変更すると現在のプロセスにのみ影響します.他のプロセスには影響しません.

  • 異なるプロセスで実行されるすべての4つのコンポーネントは、メモリを介してデータを共有する必要がある場合に失敗します.これもマルチプロセスがもたらす主な影響です.通常、4つのコンポーネントが一部の中間層を介してデータを共有しないと、単純な指定プロセス名では正常に動作しません.もちろん、特定の場合、一部のコンポーネント間でデータを共有する必要はなく、Menifestでプロセス名を直接指定することでマルチプロセスを実現することができますが、このようなシーンは一般的ではありません.
    一般的に、マルチプロセスを使用すると、次のような問題が発生します.
  • 静的メンバーおよび単一モードは完全に失効した.
  • スレッド同期メカニズムは完全に失効した.
  • SharePreferencesの信頼性は低下した.
  • アプリケーションは複数回作成されます.

  • 1つ目の問題は分析済みで、2つ目の問題は1つ目と似ています.メモリではない以上、ロックオブジェクトでもロックグローバルクラスでもスレッドの同期は保証されません.異なるプロセスがロックされているのは同じオブジェクトではないためです.3つ目は、SharePreferencesが2つのプロセスを同時に書き込み操作を実行することをサポートしていないためです.そうしないと、SharePreferencesの最下位層はXMLファイルを読み書きすることによって実現されるため、同時書き込みは明らかに問題が発生しやすく、同時読み取り/書き込みでも問題が発生します.4つ目の質問:コンポーネントが新しいプロセスに走っている場合、システムは新しいプロセスを作成すると同時に独立した仮想マシンを割り当てるため、このプロセスは実際にアプリケーションを起動するプロセスであるため、システムはまたこのアプリケーションを再起動し、もちろん自動的に新しいアプリケーションを作成します.同じプロセスで実行されるコンポーネントは同じ仮想マシンと同じApplicationに属し、異なるプロセスでのコンポーネントは異なる仮想マシンとApplicationに属し、ApplicationのonCreateメソッドでテストできます.
    ここではマルチプロセスがもたらす問題を分析したが、マルチプロセスに多くの問題があるからといって使用しないわけにはいかない.この問題を解決するために、システムは多くのプロセス間通信の方法を提供している.メモリを直接共有することはできないが、プロセス間通信はデータ相互作用を実現することができ、プロセス間通信を実現する方法はたくさんある.これから一つ一つ紹介します.