[Android] Android IntentServiceソースコード分析

Android IntentServiceソースコード分析

1.はじめに

サービスは、Androidの4つの主要コンポーネントの1つです。バックグラウンドで実行するために使用されますが、サービスはまだメインスレッドで実行されているため、時間のかかる操作を直接実行することはできません。時間のかかる操作がある場合でも、それを子スレッドに配置する必要があります。手動でスレッドを開始するか、Androidが提供する非常に単純なクラスIntentServiceを使用できます。このクラスのソースコードはまだ非常に単純です。この記事では、その実装を分析します。

二、HandlerThread

IntentServiceを分析する前に、まずHandlerThreadを理解する必要があります。名前を見ると、このクラスがHandlerに関連するスレッドクラスであることがわかります。APIはこれを次のように説明しています:
ルーパーを持つ新しいスレッドを開始するための便利なクラス。ルーパーを使用してハンドラークラスを作成できます。start()はまだ呼ばれる。
それは、ルーパーオブジェクトでスレッドを作成するためのヘルパークラスです。ルーパーオブジェクトを使用して、ハンドラークラスを作成できます。もちろん、スレッドを開始するためにまだstart()が呼び出されます。
前の記事のAndroidハンドラーの原則では、スレッドがハンドラーを作成する場合、そのハンドラーにはルーパーオブジェクトが必要であり、ルーパーを使用してメッセージループを開くことがわかっています。メインスレッドでは、システムがこれを行いました。では、他の子スレッドでLooperを作成するにはどうすればよいですか?HandlerThreadのrun()メソッドを見てください。

public void run() {
    
    
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
    
    
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

このメソッドでLooper.prepare()を呼び出して、スレッドのLooperオブジェクトを取得し、オブジェクトを保存します。次に、Looper.loop()を呼び出してメッセージループを開始します。このメソッドでは、メッセージキューからメッセージを継続的に取り出す無限ループが存在するため、このスレッドのメッセージシステムが確立されます。これらは前の記事で分析されています。

3、IntentService

HandlerThreadを理解すると、IntentServiceは非常に簡単です。IntentServiceはHandlerThreadを内部で使用します。IntentServiceはServiceを継承し、抽象クラスです。次に、onCreate()メソッドを示します。

public void onCreate() {
    
    
    // TODO: It would be nice to have an option to hold a partial wakelock
    // during processing, and to have a static startService(Context, Intent)
    // method that would launch the service & hand off a wakelock.

    super.onCreate();
    HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");
    thread.start();

    mServiceLooper = thread.getLooper();
    mServiceHandler = new ServiceHandler(mServiceLooper);
}

private final class ServiceHandler extends Handler {
    
    
    public ServiceHandler(Looper looper) {
    
    
        super(looper);
    }

    @Override
    public void handleMessage(Message msg) {
    
    
        onHandleIntent((Intent)msg.obj);
        stopSelf(msg.arg1);
    }
}

このメソッドでHandlerThreadオブジェクトが作成され、そのルーパーが取得されてから、このルーパーを使用してハンドラーが作成されます。IntentServiceのhandleMessageメソッドは、受信したメッセージをonHandleIntentに転送して処理します。このメソッドは抽象メソッドであり、IntentServiceを使用するときに書き換える必要があるメソッドでもあります。onHandleIntentが処理された後、IntentServiceはstopSelf()を呼び出して自動的に停止します。handleMessageはLooper.loop()メソッドで呼び出され、HandlerThreadで実行されるため、時間のかかる操作を安全に処理できます。
ニュースはどうやって来たのですか?onStartCommand()のソースコードを見てください。

public int onStartCommand(Intent intent, int flags, int startId) {
    
    
    onStart(intent, startId);
    return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
}
public void onStart(Intent intent, int startId) {
    
    
    Message msg = mServiceHandler.obtainMessage();
    msg.arg1 = startId;
    msg.obj = intent;
    mServiceHandler.sendMessage(msg);
}

非常に単純で、インテントパラメータをメッセージのobjにラップしてから、メッセージを送信します。ここでのインテントは、サービスが開始されたときのstartService(Intent)のインテントです。
サービスの場合、startService(Intent)が複数回呼び出されると、onCreate()メソッドは1回だけ呼び出されるため、ここで初期化作業が行われ、それに応じてonStartCommandが複数回呼び出されます。したがって、インテントパラメータが異なる限り、異なるタスクを実行できます。

4、まとめ

上記の分析からわかるように、ハンドラーの原理を理解していれば、IntentServiceはよりよく理解されます。IntentServiceを使用するときに注意すべき点がいくつかあります。UIを
直接操作することはできません。実行結果をUIに反映するには、結果をアクティビティに返す必要があります。
作業タスクキューは順次実行されます。IntentServiceでタスクが実行されているときに、新しいタスクリクエストを送信すると、新しいタスクは、前のタスクが完了するまで待機してから実行を開始します。
進行中のタスクは中断できません。

おすすめ

転載: blog.csdn.net/sinat_36955332/article/details/108278905