ラベル Service の投稿を表示しています。 すべての投稿を表示
ラベル Service の投稿を表示しています。 すべての投稿を表示

0から始めるAndroid ~常駐アプリを作る 死なないService編~

前回、Serviceに負荷を掛けるとANRが発生することが判明したので、
今回はメイン処理を別スレッドで実行するとどのような結果になるか調査する。

結論から言うと、成功である。
が但し、以下の条件付き。
1.サービスは停止していないが、正常終了しないことが頻繁に発生する。
2.USB接続を切断すると、一定間隔のスレッド起動の予定が
 間隔に大きな誤差が生じることが頻繁に発生する。
3.USB接続を切断すると、スレッドが起動しないことが頻繁に発生する。
4.USB接続すると、スレッドが正常に起動することが頻繁に発生する。

1については、アプリの仕様に問題がある可能性が高いので保留とする。
2~4については、開発目的の手順でインストールしたことが原因かも知れないので、
手動でapkファイルを生成してから再度インストールする試験をいずれ実施する。


public class Login01Service extends Service {
 private final int REPEAT_INTERVAL = 1 * 60 * 1000;
 private Handler handler = new Handler();
 private Runnable runnable;

 @Override
 public void onStart(Intent intent, int startId) {

  //このおまじないのおかげでサービスが殺されにくくなっている?
  Notification lNotification = new Notification(0, "ticker", System.currentTimeMillis());
  startForeground(1, lNotification);

  runnable = new Runnable() {
   public void run() {

    //繰り返し処理
    mainTran();

    handler.postDelayed(this, REPEAT_INTERVAL);
   }
  };

  handler.postDelayed(runnable, REPEAT_INTERVAL);
 }
}

0から始めるAndroid ~常駐アプリを作る Serviceも死ぬ編~

前回のBroadcastReceiverについて調査していくと、
常駐アプリはどうやらBroadcastReceiverではなくServiceを利用するのが適切なのかも知れない。
そこで、前回の構成を一部だけ変更して、親クラスをActivityからServiceに変更することに。
すると、ANR(Application Not Responding)で死亡する運命となってしまった。
確かに、Webサービスに接続してレスポンスが悪いと固まってしまうのは事実だからしょうがない。
しかし、少しだけ希望が見えた。
Service自身がメイン処理を実行しているのが問題であることが分かったので、
別スレッドでメイン処理を実行すれば成功するのではないか?

0から始めるAndroid ~常駐アプリを作る BroadcastReceiverは死ぬ編~

タイトル通りBroadcastReceiverは死ぬ。いや、死ぬかも知れない。
以前に作成したDoCoMoのSPモードメール、SMS、Gmailなどの
メールを受信時に起動するアプリでは気づかなかったが、
BroadcastReceiverの仕様で「10秒以内に処理が完了しないと停止する」ということだ。
ここで問題なのは、onReceiveが中断されることよりも
BroadcastReceiver自身が停止してしまうことである。
一旦停止されると、ユーザ操作により再度起動するしかない。
ちなみに今回作ろうとしているアプリは、
GPSを一定間隔で取得、Googleサービスにアクセスしてデータ登録及び取得するという代物で
10秒ルールを守れないことも多々ある。

下記の方法では、停止する可能性あり。


public class SampleActivity extends Activity {

 private BroadcastReceiver receiver;

 @Override
 public void onCreate(Bundle savedInstanceState) {

  IntentFilter filter = new IntentFilter();
  filter.addAction(Intent.ACTION_TIME_TICK); //毎分

  receiver = new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {
    //定期処理を記述

   }
  }
 }
}