IntentService onHandleIntent () sigue funcionando después de onDestroy () despedido
En mi pantalla de preferencia, quiero iniciar un servicio para descargar archivos desde Internet cuando se hace clic en una de las preferencias. Si el servicio ya se está ejecutando (descarga de archivos), el servicio debe detenerse (cancelar la descarga).
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; } }); } }
La clase de servicio:
- Mantener viva Servicio de Intención después de que la aplicación es asesinada
- Biblioteca de clientes API de REST para Android
- Android: Servicio de Intención con bibliotecas de red (Retrofit o Volley)
- Cómo crear tostadas de IntentService? Se queda atascado en la pantalla
- ¿Cómo probar IntentService android?
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; } }
Este servicio está destinado a ejecutarse hasta que la descarga haya finalizado. La función downloadFiles()
no utiliza AsyncTask
. Guarda la HttpURLConnection
con un FileOutputStream
directamente.
El servicio se inició correctamente cuando hice clic en la preferencia. Ahora el problema es, cuando hago clic para detener el servicio con stopService()
, DownloadService
activado onDestroy()
inmediatamente; sin embargo, según los registros, onHandleIntent()
sigue funcionando porque todavía puedo ver las solicitudes HTTP continuamente. ¿Esto es porque el Service
funciona en un hilo él mismo, o estoy haciendo algo mal? ¿Cómo puedo asegurarme de que todo en onHandleIntent()
detenga inmediatamente (o al menos sea capaz de detenerlo) cuando stopService()
esté siendo llamado?
- Antecedentes Proceso para escanear la ubicación del usuario a intervalos regulares y actualizar la base de datos local incluso cuando la aplicación no está abierta
- Cómo determinar si la aplicación se ejecuta desde el servicio
- Android: IntentService no hace cola correctamente
- ¿Puede un IntentService ejecutarse indefinidamente?
- Cómo enviar datos de IntentService a clase Non-Activity
- ¿Cómo se declara un servicio de intención en el manifiesto de Android?
- El oyente de ubicación funciona desde un servicio pero no es un servicio de IntentService
- Múltiples instancias de IntentService en Android
Finalmente averiguó cómo hacerlo funcionar.
Como dije en mi pregunta, de alguna manera onHandleIntent () creará un hilo para hacer el trabajo. Así que incluso cuando el servicio en sí es destoryed, el hilo sigue funcionando. Alcancé mi objetivo añadiendo una variable global
private static boolean isStopped = false;
a la clase DownloadService
.
Para cancelar mi servicio, en lugar de llamar
Setting.this.stopService(new Intent(Setting.this, DownloadService.class));
acaba de establecer DownloadService.isStopped = true
.
Por último, al hacer las cosas en onHandleIntent()
, compruebe este booleano periódicamente para ver si debe detener la descarga. Si isStopped = true
, devuelve inmediatamente y el servicio se detendrá.
Espero que esto ayude a alguien que se encuentra con este problema también. Y gracias por su tiempo leyendo esta pregunta.
Tiene un hilo separado para hacer el trabajo, y dependiendo de lo que está haciendo puede que no sea posible detenerlo inmediatamente. Si está bloqueando en E / S, la interrupción probablemente no tendrá ningún efecto.
- ¿Cómo evitar el parpadeo de Vista cuando se utiliza la animación?
- ¿Puedo establecer un color de texto para los enlaces dentro de una vista de texto?