3

設定画面で、設定の 1 つがクリックされたときに、インターネットからファイルをダウンロードするサービスを開始したいと考えています。サービスが既に実行されている (ファイルをダウンロードしている) 場合は、サービスを停止する必要があります (ダウンロードをキャンセルします)。

public class Setting extends PreferenceActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    downloadPref.setOnPreferenceClickListener(new OnPreferenceClickListener() {

        @Override
        public boolean onPreferenceClick(Preference pref) {
            if (DownloadService.isRunning) {
                Setting.this.stopService(new Intent(Setting.this,
                    DownloadService.class));
            } else {
                Setting.this.startService(new Intent(Setting.this,
                    DownloadService.class));
            }
            return false;
        }
    });
    }
}

サービスクラス:

public class DownloadService extends IntentService {

public static final int DOWNLOAD_SUCCESS = 0;
public static final int DOWNLOAD_FAIL = 1;
public static final int DOWNLOAD_CANCELLED = 2;
public static final int SERVER_FAIL = 3;

public static boolean isRunning = false;
private int result;

public DownloadService() {
    super("DownloadService");
}

@Override
public void onCreate() {
    super.onCreate();
    isRunning = true;
}

@Override
protected void onHandleIntent(Intent intent) {
    if (NetworkStateUtils.isInternetConnected(getApplicationContext())) 
        result = downloadFiles(getApplicationContext());

}

@Override
public void onDestroy() {
    super.onDestroy();
    switch (result) {
    case DOWNLOAD_SUCCESS:
        Toast.makeText(getApplicationContext(), R.string.download_finished,
                Toast.LENGTH_SHORT).show();
        break;
    case DOWNLOAD_CANCELLED:
        Toast.makeText(getApplicationContext(), R.string.download_canceled,
                Toast.LENGTH_SHORT).show();
        break;
    case DOWNLOAD_FAIL:
        Toast.makeText(getApplicationContext(), R.string.download_failed,
                Toast.LENGTH_SHORT).show();
        break;
    }
    isRunning = false;
}
}

このサービスは、ダウンロードが完了するまで実行されることを意図しています。関数downloadFiles()は no を使用しAsyncTaskます。を直接保存しHttpURLConnectionますFileOutputStream

設定をクリックすると、サービスが正しく開始されました。問題は、クリックしてサービスを停止するとstopService()、すぐにDownloadServiceトリガーされることです。onDestroy()ただし、ログによると、onHandleIntent()HTTP 要求を引き続き確認できるため、まだ実行されています。これServiceは、スレッド自体で実行されているためですか、それとも何か間違っていますか? が呼び出されたときに、すべてonHandleIntent()がすぐに停止する (または少なくとも停止できる) ようにするにはどうすればよいstopService()ですか?

4

2 に答える 2

8

最後に、それを機能させる方法を考え出しました。

私の質問で述べたように、どういうわけか onHandleIntent() は仕事をするためのスレッドを作成します。したがって、サービス自体が破棄されても、スレッドは実行され続けます。グローバル変数を追加することで目標を達成しました

private static boolean isStopped = false;

DownloadServiceクラスへ。

サービスをキャンセルするには、電話ではなく

Setting.this.stopService(new Intent(Setting.this, DownloadService.class));

セットするだけDownloadService.isStopped = true

最後に、 で作業を行っている間onHandleIntent()、このブール値を定期的にチェックして、ダウンロードを停止する必要があるかどうかを確認します。の場合isStopped = trueは、すぐに戻ると、サービスは自動的に停止します。

これが、この問題に遭遇した人にも役立つことを願っています。そして、この質問を読んでくれてありがとう。

于 2012-10-18T02:44:38.027 に答える
4

作業を行うための別のスレッドがあり、実行していることによっては、すぐに停止できない場合があります。I / Oをブロックしている場合は、中断しても効果がない可能性があります。

于 2012-10-17T05:15:40.800 に答える