Android startService () tarda mucho tiempo en volver al subproceso de interfaz de usuario
mi usecase es (aproximadamente) lo siguiente en la primera puesta en marcha:
- la actividad inicia un servicio
- servicio obtiene y guarda datos en una base de datos
- servicio notifica la actividad con una intención
- la actividad muestra datos
Ahora quiero mostrar una barra de progreso mientras el servicio está ocupado. El problema es:
- Notificación de Android Push (lento)
- ¿Es posible ver variables en tiempo de ejecución?
- Android Convertir hora central a hora local
- Cómo obtener el tiempo de computación en NDK
- Android: ¿Activar / desactivar un botón en Runtime?
startService(new Intent(getApplicationContext(), UpdateDataService.class));
toma mucho tiempo para "volver" al hilo de la interfaz de usuario. Parece ser una función sincronizada (o no ?). Si se vacía la clase de servicio, el comando startService se procesa casi instantáneamente. Parece que el hilo de la interfaz de usuario espera a que el Serice maneje su trabajo, que no tiene sentido en absoluto. Intenté iniciar (por estúpido que parezca) para iniciar el servicio una tarea asíncrona mientras se muestra una barra de progreso en mi subproceso de interfaz de usuario. Curiosamente esto funciona a veces. Otras veces sólo recibo una pantalla en blanco mientras mi servicio está funcionando y después por un millisecond ma progressbar y luego mi interfaz de usuario.
Ahora mi pregunta: ¿Cómo puedo iniciar el servicio sin bloquear mi interfaz de usuario?
public class MyClass extends TabActivity { private ProgressDialog pd; @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = null; //building some tabs here, setting some text views.... // starting service if does not exist yet boolean serviceRunning = false; final ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); for (final RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if ("aegir.mobile.UpdateDataService".equals(service.service.getClassName())) { serviceRunning = true; Log.i(MY_APP_TAG, "Service found."); } } if (!serviceRunning) { pd = ProgressDialog.show(this, "Loading...", "Setting up data.", true, false); new StartServiceAsync().execute(""); } } private final Handler handler = new Handler() { @Override public void handleMessage(final Message msg) { pd.dismiss(); } }; public class StartServiceAsync extends AsyncTask<String, Void, String> { @Override protected String doInBackground(final String... params) { // starting service startService(new Intent(getApplicationContext(), UpdateDataService.class)); return null; } @Override protected void onPostExecute(final String result) { handler.sendEmptyMessage(0); super.onPostExecute(result); } }
- android: mostrar la notificación en un momento específico?
- Crear un NinePatch / NinePatchDrawable en tiempo de ejecución
- Glide image loading timeout increase
- SoundPool de Android tartamudea, retrasa, a veces no juega en absoluto
- Static static String definida en una interfaz no evaluada en tiempo de compilación - Android
- ¿Cómo se puede comprobar el permiso en tiempo de ejecución sin lanzar SecurityException?
- Android 4.0 org.apache.http.conn.ConnectTimeoutException: Conectarse a ... agotado el tiempo de espera
- ¿Cómo cambiar el retraso del hilo de sueño / temporizador en android durante el tiempo de ejecución?
Creo que debería mover la lógica del servicio al método doInBackground en la tarea asíncrona. Eso es lo que la tarea asíncrona son para ejecutar el trabajo duro que le da una manera sencilla de interactuar con la interfaz de usuario. Es extraño llamar a un servicio en la tarea asíncrona, ¿hay alguna razón por la que lo hiciste?
Del tema de la guía Servicios :
Precaución: Un servicio se ejecuta en el mismo proceso que la aplicación en la que se declara y en el subproceso principal de esa aplicación, de forma predeterminada. Por lo tanto, si su servicio realiza operaciones intensivas o de bloqueo mientras el usuario interactúa con una actividad de la misma aplicación, el servicio ralentizará el rendimiento de la actividad. Para evitar impactar el rendimiento de la aplicación, debe iniciar un nuevo subproceso dentro del servicio.
Esto no cambia sólo porque llama a startService
desde un AsyncTask.
Haga su trabajo en AsyncTask
sí mismo, utilice un IntentService
vez de un Service
viejo llano o comience un hilo de su Service
para hacer su trabajo. Un Service
en Android no utiliza inherentemente un hilo diferente ( IntentService
hace para hacer su trabajo).
A pesar de comenzar su Service
de un AsyncTask
, ahora parece que el trabajo real se está realizando en su hilo de interfaz de usuario.
por favor use este código de la manera fácil de hacer lo que pidió en cuestión.
@Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = null; registerReceiver(dataUpdated, new IntentFilter("<FLAG>")); //building some tabs here, setting some text views.... // starting service if does not exist yet boolean serviceRunning = false; final ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE); for (final RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) { if ("aegir.mobile.UpdateDataService".equals(service.service.getClassName())) { serviceRunning = true; Log.i(MY_APP_TAG, "Service found."); } } if (!serviceRunning) { pd = ProgressDialog.show(this, "Loading...", "Setting up data.", true, false); startService(new Intent(getApplicationContext(), UpdateDataService.class)); } } private BroadcastReceiver dataUpdated= new BroadcastReceiver() { @SuppressLint("ShowToast") @Override public void onReceive(Context context, Intent intent) { //<Your Process which you want when Service finishes a task > pd.dismiss(); } }; @Override protected void onDestroy() { unregisterReceiver(dataUpdated); }
En servicio cuando la tarea se complete llame a este método
sendBroadcast(new Intent("<FLAG>"));
- Cómo controlar el flujo de actividad – Botón Atrás contra botón Inicio
- Cómo agregar una nueva línea en el archivo de texto en android