AndroidのService- IntentService概要
IntentServiceもServiceの一種だが、特殊な機能を提供してくれる。
まず、なぜIntentServiceが必要なのか。
通常Seriviceの問題点
- Serivceは独自のスレッドではなく、アプリと同じスレッド内である
- 新スレッドではないので、時間がかかる処理を書くのはよくない。
書く場合には、サンプルコードのように別スレッドを起動しやるべき。
IntentServiceは上記欠点を補うためでクラスである。
IntentServiceの概要
- IntentServiceは独自のworkerスレッドをIntentの要求を処理する
- IntentServiceは独自のworkerスレッドでonHandleIntent()で実装した処理を実行するので、開発者はマルチスレッドは考えなくて済む
- 要求を処理した後に、IntentServiceは自動停止する
- onBind()が実装されていて、nullを返す
- onStartCommand()が実装されていて、Intentをキューに入れる
サンプルコード
概要 : - MyService.java - 起動すると20秒待つ(重い処理)ことによってANR(Application Not Responding)いよう発生 - MyIntentService.java - 起動すると20秒待つ(重い処理)を行うがUI更新(時刻)はできる
MyService.java
package com.example.liguofeng.firstservice; import android.app.Service; import android.content.Intent; import android.os.IBinder; public class MyService extends Service { @Override public IBinder onBind(Intent intent) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { System.out.println("onStartCommand"); // 20秒を待つ long endTime = System.currentTimeMillis() + 20 * 1000; while (System.currentTimeMillis() < endTime) { synchronized (this) { try { wait(endTime - System.currentTimeMillis()); } catch (Exception e) { // nothing } } } return START_STICKY; } }
MainActivity .java
package com.example.liguofeng.firstservice; import android.app.Service; import android.content.ComponentName; import android.content.Intent; import android.content.ServiceConnection; import android.os.IBinder; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity { Button normorService, intentService; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); normorService = (Button) findViewById(R.id.normalService); intentService = (Button) findViewById(R.id.intentService); // 起動用Intent final Intent intent1 = new Intent(MainActivity.this, MyService.class); final Intent intent2 = new Intent(MainActivity.this, MyIntentService.class); normorService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // start service startService(intent1); } }); intentService.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // start service startService(intent2); } }); } }