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でタスクが実行されているときに、新しいタスクリクエストを送信すると、新しいタスクは、前のタスクが完了するまで待機してから実行を開始します。
進行中のタスクは中断できません。