Open7

Android

Kazuki MatsudaKazuki Matsuda

https://developer.android.com/guide/components/fundamentals?hl=ja

  • Android オペレーティング システムはマルチユーザーの Linux システムであり、各アプリがそれぞれ異なるユーザーになります。
  • デフォルトで、各アプリに一意の Linux ユーザー ID が割り当てられます(ID はシステムのみで使用され、アプリは ID を関知しません)。アプリに割り当てられたユーザー ID のみがアプリ内のすべてのファイルにアクセスできるよう、パーミッションが設定されます。
  • 各プロセスにはそれぞれ独自の仮想マシン(VM)があるため、アプリのコードは他のアプリとは分離して実行されます。
  • デフォルトで、すべてのアプリは独自の Linux プロセスで実行されます。Android システムはアプリのコンポーネントのいずれかを実行する必要があるときにプロセスを開始し、それが必要なくなったときや、システムが他のアプリ用にメモリを回復させる必要があるときにプロセスをシャットダウンします。

システムがコンポーネントを開始すると、そのアプリのプロセスがまだ実行されていない場合にはプロセスを開始し、コンポーネントに必要なクラスをインスタンス化します。たとえば、写真を撮影するカメラアプリのアクティビティをアプリで開始すると、そのアクティビティはアプリのプロセスではなく、カメラアプリのプロセスで実行します。そのため、他の多くのシステムのアプリとは異なり、Android アプリのエントリ ポイントは 1 つではありません(main() 関数はありません)。

Kazuki MatsudaKazuki Matsuda

https://developer.android.com/guide/components/services?hl=ja

フォアグラウンド サービス

フォアグラウンド サービスは、ユーザーが認識できる操作を行います。たとえば、オーディオ アプリは、フォアグラウンド サービスを使用してオーディオ トラックを再生します。フォアグラウンド サービスは通知を表示する必要があります。フォアグラウンド サービスは、ユーザーがアプリを操作していない間も動作し続けます。

バックグラウンド サービス

バックグラウンド サービスは、ユーザーには直接認識されない操作を行います。たとえば、ストレージを圧縮するサービスをアプリで使用する場合、そのサービスは通常、バックグラウンド サービスになります。

バインドされたサービス

アプリ コンポーネントが bindService() を呼び出してサービスにバインドすると、サービスは「バインドされた」状態になります。バインドされたサービスは、コンポーネントがサービスを操作したり、リクエストを送信したり、結果を受信したり、さらにはプロセス間通信(IPC)でもそれを行えるクライアントサーバー型インターフェースを提供したりします。バインドされたサービスは、他のアプリ コンポーネントがそれにバインドしている限り動作し続けます。サービスには同時に複数のコンポーネントがバインドできますが、すべてがアンバインドされると、サービスは破棄されます。

サービスは、そのホスティング プロセスのメインスレッドで実行されます。特に指定しない限り、サービスが自身のスレッドを作成することはなく、別のプロセスで実行されることもありません。サービスが CPU を集中的に使う作業やブロック操作(MP3 の再生やネットワーク作業など)を行う場合は、サービス内に新しいスレッドを作成してその作業を行う必要があります。別のスレッドを使うことで、「アプリが応答していません(ANR)」というエラーが発生するリスクを軽減でき、アプリのメインスレッドをアクティビティのユーザー操作専用にすることができます。

フォアグラウンド サービスは、ユーザーがその存在を認識しているサービスであり、メモリ残量が少なくなった場合でも、システムによる強制終了の候補にはなりません。フォアグラウンド サービスではステータスバーに通知を表示する必要があり、「継続中」という見出しの下に通知が表示されます。これは、サービスが停止するか、フォアグラウンドから削除されない限り、通知を消すことができないことを意味します。

ユーザーがアプリを直接操作していないときでも、ユーザーが認識できるタスクをアプリが実行する必要がある場合にのみ、フォアグラウンド サービスを使用するようにしてください。そのため、フォアグラウンド サービスは、アプリが何を行っているかをユーザーが認識できるように、優先度が PRIORITY_LOW 以上のステータスバー通知を表示する必要があります。操作の重要性が低く、優先度が最も低い通知でも十分な場合は、サービスを使用するのではなく、スケジュールされたジョブを使用することを検討してください。

サービスを実行するアプリはすべて、システムに余分な負荷をかけ、システム リソースを消費します。優先度が低い通知を使用して、アプリがサービスを隠そうとする場合、ユーザーがアクティブに操作しているアプリのパフォーマンスが低下することがあります。そのため、優先度が最も低い通知を使用するサービスをアプリが実行しようとすると、システムは、通知ドロワーの下部セクションにアプリの動作を表示します。

public class ExampleService extends Service {
    int startMode;       // indicates how to behave if the service is killed
    IBinder binder;      // interface for clients that bind
    boolean allowRebind; // indicates whether onRebind should be used

    @Override
    public void onCreate() {
        // The service is being created
    }
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // The service is starting, due to a call to startService()
        return mStartMode;
    }
    @Override
    public IBinder onBind(Intent intent) {
        // A client is binding to the service with bindService()
        return mBinder;
    }
    @Override
    public boolean onUnbind(Intent intent) {
        // All clients have unbound with unbindService()
        return mAllowRebind;
    }
    @Override
    public void onRebind(Intent intent) {
        // A client is binding to the service with bindService(),
        // after onUnbind() has already been called
    }
    @Override
    public void onDestroy() {
        // The service is no longer used and is being destroyed
    }
}