OnHandleIntent () no se llama en IntentService

Sé que esta pregunta se ha hecho antes, pero he estado sobre todas las respuestas que pude encontrar y aún no he sido capaz de resolver el problema.

El problema es que cuando BroadcastReceiver inicia el IntentService onHandleIntent () no se llama. Curiosamente, el constructor se ejecuta (como puedo ver en la salida del registro). Este es mi código:

NoLiSeA.class (Esta clase contiene el BroadcastReceiver que inicia mi servicio)

public void toProcess(StatusBarNotification sbn) { LocalBroadcastManager.getInstance(this).registerReceiver(notificationForwarder, new IntentFilter("to_forward")); Intent intent = new Intent("to_forward"); intent.putExtra("sbn", sbn); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); Log.i("NoLiSe.TAG", "toProcess"); } private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("NoLiSe.TAG", "BroadCastReceiver.onReceive"); Intent i = new Intent(context, CoreTwoA.class); i.putExtras(intent); startService(i); } } }; 

CoreTwoA.class (Este es el IntentService. OnHandleIntent () no se llama como puedo ver debido a ningún texto de registro en la consola.)

 public class CoreTwoA extends IntentService { private TextToSpeech mtts; public CoreTwoA() { super("TheCoreWorker"); Log.d("source", "exception", new Exception()); Log.i("CoreTwoA.TAG", "Constructor"); } @Override protected void onHandleIntent(Intent intent) { Log.i("CoreTwoA.TAG", "onHandleIntent"); } } 

AndroidManifest.xml

  <service android:name=".CoreTwoA" android:label="@string/service_name" android:exported="false"> </service> 

ACTUALIZAR

Así que basado en las discusiones a continuación, pude reducir el problema a la siguiente línea de código en el BroadCastReceiver:

 i.putExtra("sbn", sbn) 

Si lo elimino, es decir, no agregamos extras a la intención, entonces mi método onHandleIntent () en mi IntentService se ejecuta.

Si se incluye, onHandleIntent () no se ejecuta y lo siguiente se escribe en logcat por el Log.d () en el constructor de mi IntentService

 06-10 19:40:35.355 25094-25094/com.dezainapps.myapp D/source: exception java.lang.Exception at com.dezainapps.myapp.CoreTwoA.<init>(CoreTwoA.java:20) at java.lang.Class.newInstance(Native Method) at android.app.ActivityThread.handleCreateService(ActivityThread.java:2859) at android.app.ActivityThread.-wrap4(ActivityThread.java) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1427) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5417) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 06-10 19:40:35.355 25094-25094/com.dezainapps.myapp I/CoreTwoA.TAG: Constructor 

¿Alguna idea de por qué pasar un objeto StatusBarNotification, que implementa Parcelable, a un IntentService a través de un Intent no funciona? Curiosamente, la difusión de la misma StatusBarNotfication sbn objeto de mi método toProcess () a través de una intención (ver código) funciona.

Tuve el mismo problema que el OP.

El problema resultó ser que estaba pasando un enorme ArrayList (de unos 4000 elementos Parcelable ) a través de la Intent que inicia el IntentService . Era extremadamente difícil de diagnosticar ya que fallaba 'silenciosamente' en el dispositivo de un cliente, así que no recibí ningún informe de error ACRA.

De todos modos, utilicé un truco rápido y sucio para solucionar el problema – básicamente para almacenar el ArrayList en un elemento estático que he utilizado para establecer / obtener la ArrayList en lugar de intentar pasar a través de la Intención.

En la investigación adicional (haciendo algunas pruebas de otros dispositivos) encontré una TransactionTooLargeException siendo lanzado. Más discusión sobre eso aquí .

Aquí está mi código de prueba si alguien quisiera replicar:

Código de prueba

Si desea que funcione, cambie el valor 4000 a algo mucho más pequeño.

 ArrayList<ParcelableNameValuePair> testArrayList = new ArrayList<>(); for (int i = 0; i < 4000; i++) { testArrayList.add(new ParcelableNameValuePair("name" + i, "value" + i)); } TestIntentService.startAction(AdminHomeActivity.this, testArrayList); 

TestIntentService.java

 public class TestIntentService extends IntentService { private static final String LOG_TAG = TestIntentService.class.getSimpleName(); private static final String TEST_ACTION = "com.example.action.FOO"; private static final String EXTRA_PARAM1 = "com.example.extra.PARAM1"; private static final String EXTRA_PARAM2 = "com.example.extra.PARAM2"; public TestIntentService() { super("TestIntentService"); } public static void startAction(Context context, ArrayList<ParcelableNameValuePair> testArrayList) { Log.d(LOG_TAG, "1. startAction()"); Utilities.makeToast(context, "1. startAction()"); try { int arrayListSize = (testArrayList == null) ? -1 : testArrayList.size(); Log.d(LOG_TAG, "2. arrayListSize: " + arrayListSize); Utilities.makeToast(context, "2. arrayListSize: " + arrayListSize); Intent intent = new Intent(context, TestIntentService.class); intent.setAction(TEST_ACTION); //intent.putExtra(EXTRA_PARAM1, testArrayList); intent.putParcelableArrayListExtra(EXTRA_PARAM2, testArrayList); /** * This line should result in a call to onHandleIntent() but, if we're sending a huge ArrayList, it doesn't... */ context.startService(intent); } catch(Exception e) { Log.e(LOG_TAG, "Exception starting service", e); Utilities.makeToast(context, "Exception starting service: " + e); } } @Override protected void onHandleIntent(Intent intent) { Log.d(LOG_TAG, "3. onHandleIntent()"); Utilities.makeToast(getApplicationContext(), "3. onHandleIntent()"); try { if (intent != null) { final String action = intent.getAction(); if (TEST_ACTION.equals(action)) { ArrayList<ParcelableNameValuePair> testArrayList = intent.getParcelableArrayListExtra(EXTRA_PARAM1); int testArrayListSize = (testArrayList == null) ? -1 : testArrayList.size(); Log.d(LOG_TAG, "4. testArrayListSize: " + testArrayListSize); Utilities.makeToast(getApplicationContext(), "4. testArrayListSize: " + testArrayListSize); ArrayList<ParcelableNameValuePair> testArrayList2 = intent.getParcelableArrayListExtra(EXTRA_PARAM2); int testArrayList2Size = (testArrayList2 == null) ? -1 : testArrayList2.size(); Log.d(LOG_TAG, "5. testArrayList2Size: " + testArrayList2Size); Utilities.makeToast(getApplicationContext(), "5. testArrayList2Size: " + testArrayList2Size); } } } catch(Exception e) { Log.e(LOG_TAG, "Exception handling service intent", e); Utilities.makeToast(getApplicationContext(), "Exception handling service intent: " + e); } } } 

ParcelableNameValuePair.java

 public class ParcelableNameValuePair implements Parcelable { private String name, value; public ParcelableNameValuePair(String name, String value) { this.name = name; this.value = value; } public String getName() { return name; } public String getValue() { return value; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel out, int flags) { out.writeString(name); out.writeString(value); } public static final Parcelable.Creator<ParcelableNameValuePair> CREATOR = new Parcelable.Creator<ParcelableNameValuePair>() { public ParcelableNameValuePair createFromParcel(Parcel in) { return new ParcelableNameValuePair(in); } public ParcelableNameValuePair[] newArray(int size) { return new ParcelableNameValuePair[size]; } }; private ParcelableNameValuePair(Parcel in) { name = in.readString(); value = in.readString(); } } 

Como digo, usé una solución rápida y sucia para solucionar este problema. Creo que una mejor solución sería que la aplicación escriba ArrayList en el sistema de archivos y luego pase una referencia a ese archivo (por ejemplo, filename / path) a través de Intent to the IntentService y luego deje que IntentService recuperara el contenido del archivo y convirtiera De nuevo a una ArrayList .

Cuando el IntentService ha hecho con el archivo, debe eliminarlo o pasar la instrucción de nuevo a la aplicación a través de una difusión local para eliminar el archivo que creó (pasando la misma referencia de archivo que se le proporcionó).

¿Ha intentado usar context.startService (intención) ;?

Cuando usted está en un receptor de la difusión como esto usted no tiene un contexto sus el propio para referirlo creo así que usted necesita utilizar el pasado al método onRecieve.

Utilizar esta:

 private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.i("NoLiSe.TAG", "BroadCastReceiver.onReceive"); Intent i = new Intent(context, CoreTwoA.class); i.putExtra("intent",intent); context.startService(i); } } 

};

Utilice el siguiente código:

 private BroadcastReceiver notificationForwarder = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e("NoLiSe.TAG", "BroadCastReceiver.onReceive"); Intent i = new Intent(context, CoreTwoA.class); i.putExtra("sbn",intent.getParcelableExtra("sbn")); startService(i); } }; 

Está utilizando incorrectamente i.putExtras(intent); Que he eliminado y agregó otra forma de enviar el objeto StatusBarNotification través de putExtra .

He probado este código y llamo onHandleIntent

  • ¿Cómo puede manejar el descarte de un DialogFragment (compatibilidad lib) al completar un AsyncTask
  • Debug Lua en un proyecto de Java usando LuaJava
  • 'Java' plugin no es compatible con los complementos de Android
  • Android - ¿Cómo cambiar los elementos de vista de encabezado / pie de página para ListView existentes?
  • FindFirstVisibleItemPositions no funciona para recycleview android
  • Dagger 2 actividad inyección no funciona
  • Cómo configurar el tamaño del archivo PDF con PdfDocument en Android
  • El valor del tipo org.json.JSONArray no se puede convertir en JSONObject
  • Cambiar el tamaño de una vista de imagen en android
  • ¿El selector de archivos de Android 4.4 WebView no se abre?
  • ¿Existe una forma de reutilizar el código del constructor para la adaptación
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.