質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

Q&A

0回答

730閲覧

【Android】Serviceの停止方法について

MasanaoMatsuda

総合スコア6

Android

Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

0グッド

1クリップ

投稿2017/12/18 05:48

###前提・実現したいこと
Androidアプリを開発しています。作成中のプログラムは「スタートボタンをクリックすると、バックグラウンドにて、一定時間後待機したのち処理を開始する」というものです。
現在は、バックグラウンド処理を途中で停止させる機能を追加実装するところでハマってしまいました。そこでServiceを停止させる方法についてアドバイス頂きたいです。
ソースコード内のコメントの仕方など、初心者で我流のためお見苦しいところがあるかも知れませんが、どうかよろしくお願いいたします。

###発生している問題・エラーメッセージ
疑問1:こちらのServiceはそもそも停止しているのか(ストップボタンを押す押さないで挙動が異なるも、本当に停止しているようには思えない)。
疑問2:停止していない場合に、次にTryするべきことについてアドバイス。

コードを実行して得られるLogはこちらです。

◆ストップボタンを押さない場合
12-18 13:55:33.353 16600-16600/com.example.android.asobisugi D/Check: Inside findLauncherApp: com.sonyericsson.home
12-18 13:55:48.224 16600-16600/com.example.android.asobisugi D/Check: I'm inside onCreate() in CountTimeService.class.
12-18 13:55:48.238 16600-16600/com.example.android.asobisugi D/Check: [service starting] I'm inside onStartCommand().
12-18 13:55:48.245 16600-19103/com.example.android.asobisugi D/Check: 1分待機. Thread ID: 13221
12-18 13:56:48.280 16600-19103/com.example.android.asobisugi D/Check: After Thread.sleep() and stopSelf() Thread ID: 13221
12-18 13:56:48.281 16600-16600/com.example.android.asobisugi D/Check: onDestroy()が呼出。Thread ID: 1

◆ストップボタンを押した場合
12-18 13:59:18.976 16600-16600/com.example.android.asobisugi D/Check: I'm inside onCreate() in CountTimeService.class.←スタートボタン押下
12-18 13:59:18.978 16600-16600/com.example.android.asobisugi D/Check: [service starting] I'm inside onStartCommand().
12-18 13:59:18.982 16600-19369/com.example.android.asobisugi D/Check: 1分待機. Thread ID: 13224
12-18 14:00:19.020 16600-16600/com.example.android.asobisugi D/Check: onDestroy()が呼出。Thread ID: 1←ストップボタン押下
12-18 14:00:19.020 16600-19369/com.example.android.asobisugi D/Check: After Thread.sleep() and stopSelf() Thread ID: 13224

###該当のソースコード
※Serviceの停止処理はMainActivityから行うようにしています。(下部参照)

public class CountTimeService extends Service {

private final String TAG = "Check"; // onCreate()にて初期化 private Looper mServiceLooper; private ServiceHandler mServiceHandler; String action; String launcherPackName; // Looperから受け取る処理を実行するHandlerを継承したクラス private final class ServiceHandler extends Handler { public ServiceHandler(Looper looper) { super(looper); } @Override public void handleMessage(Message msg) { try { Log.d(TAG, "1分待機. Thread ID: " + Thread.currentThread().getId()); Thread.sleep(60000); } catch (InterruptedException e) { // Restore interrupt status. Thread.currentThread().interrupt(); } stopSelf(msg.arg1); Log.d(TAG, "After Thread.sleep() and stopSelf() Thread ID: " + Thread.currentThread().getId()); } } @Override public void onCreate() { Log.d(TAG, "I'm inside onCreate() in CountTimeService.class."); // 別スレッドを生成 HandlerThread thread = new HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND); thread.start(); // Get the HandlerThread's Looper and use it for our Handler mServiceLooper = thread.getLooper(); mServiceHandler = new ServiceHandler(mServiceLooper); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.d(TAG, "[service starting] I'm inside onStartCommand()."); Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show(); action = intent.getAction(); launcherPackName = intent.getPackage(); Message msg = mServiceHandler.obtainMessage(); msg.arg1 = startId; mServiceHandler.sendMessage(msg); return START_STICKY; } @Override public IBinder onBind(Intent intent) { // We don't provide binding, so return null return null; } @Override public void onDestroy() { Log.d(TAG, "onDestroy()が呼出。Thread ID: " + Thread.currentThread().getId()); Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show(); }

}

※MainActivityのonCreate()にて以下のclickListenerから停止のIntentを投げる仕組み。

Button stopBtn = (Button) findViewById(R.id.stop_btn); stopBtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent( MainActivity.this, CountTimeService.class); stopService(intent); Log.d("Check", "stopService()を実行。 Thread ID: " + Thread.currentThread().getId()); } });

###試したこと
【経過】
①IntentServiceを使ってバックグラウンド処理を実装。
→順次処理のため?、停止対象のIntentServiceが完了するまで停止処理が実行されない。
→booleanの変数を追加し、プログラムの要所要所にIf文でstopSelf()/stopService()を呼び出すようにした(https://stackoverflow.com/questions/11258083/how-to-force-an-intentservice-to-stop-immediately-with-a-cancel-button-from-an-a)。スレッドが違うからか?うまくいかない。
②AsyncTaskを使うことも考えたが、長時間処理には非推奨のため断念(使い方によっては30分~数時間動作する想定)。
③ノーマルなServiceを使ってみた(※現在)

###補足情報(言語/FW/ツール等のバージョンなど)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問