La fuerza del servicio de actualización de widgets de aplicaciones se cierra a veces. ¡Necesita ayuda!

Antecedentes de este problema. Tengo un widget de aplicación asociado con mi aplicación que se actualiza a intervalos establecidos periódicamente, utilizando un Servicio de actualización que realiza publicaciones http en el servidor y actualiza el widget con los datos recibidos del servidor.

Lo que he notado en mis pruebas e informes de usuario es que esta instancia particular de cierre forzado ocurre periódicamente (pero es raro) cuando es hora de que el widget se actualice y el estado de la red cambia de disponible a no disponible. Desde que noté esto en mi teléfono en el metro de Nueva York.

Mientras depuraba, pensé que si la publicación http ha sucedido y el estado de la red cambia antes de que se haya recibido la respuesta, básicamente recibe una IOException. Así que manejé esta excepción y actualicé el widget en este caso particular con una actualización predeterminada. Funcionó bien.

Pero, curiosamente, he notado este cierre de fuerza de nuevo y me estoy quedando sin ideas sobre cómo resolverlo.

¿Alguien se ha encontrado con esto antes y sabe cómo puedo manejar esto?

 java.lang.NullPointerException
    at android.widget.RemoteViews$ReflectionAction.writeToParcel(RemoteViews.java:399)
    at android.widget.RemoteViews.writeToParcel(RemoteViews.java:1003)
    at com.android.internal.appwidget.IAppWidgetService$Stub$Proxy.updateAppWidgetProvider(IAppWidgetService.java:402)
    at android.appwidget.AppWidgetManager.updateAppWidget(AppWidgetManager.java:283)
    at com.tyu.android.TyuWidget$UpdateService$1.run(TyuWidget.java:167)

Algunos fragmentos de código que pueden ayudar a todos los expertos a comprender mejor el problema y ayudar a un principiante.

@Override
public void onReceive(Context context, Intent intent) {
        check_intent = intent.getAction();
            if(check_intent.equals("android.appwidget.action.APPWIDGET_UPDATE")){
        this.onUpdate(context, intent);
        }   
}

Aquí está el fragmento de código del método OnUpdate.

    public void onUpdate(Context context, Intent intent){
            Intent widgetUpdate = new Intent(context, TyuWidget.class);
            widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
            AlarmManager alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
            PendingIntent newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate,PendingIntent.FLAG_UPDATE_CURRENT);
            alarms.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ PERIOD, newPending);
            context.startService(new Intent(context, UpdateService.class));

}

Hilo dentro del método OnStart de la clase UpdateService que actualiza el widget.

widgetUpdateThread = new Thread(){
                @Override
                public void run(){
                    RemoteViews updateViews = buildUpdate(getApplicationContext());
                    if(updateViews!=null){
                        ComponentName thisWidget = new ComponentName(getApplicationContext(), TyuWidget.class);
                        AppWidgetManager manager = AppWidgetManager.getInstance(getApplicationContext());
                        manager.updateAppWidget(thisWidget, updateViews);
                    }
                    else{
                        updateViews = new RemoteViews(getApplicationContext().getPackageName(), R.layout.tuwidget);
                        updateViews.setImageViewResource(R.id.ad, R.drawable.tyu_null_game);
                        Intent defineIntent1 = new Intent(getApplicationContext(), Tyu3.class);
                        PendingIntent pendingIntent1 = PendingIntent.getActivity(getApplicationContext(),
                                0 /* no requestCode */, defineIntent1, 0 /* no flags */);
                        updateViews.setOnClickPendingIntent(R.id.tuwidget, pendingIntent1);
                        ComponentName thisWidget = new ComponentName(getApplicationContext(), TyuWidget.class);
                        AppWidgetManager manager = AppWidgetManager.getInstance(getApplicationContext());
                        manager.updateAppWidget(thisWidget, updateViews);

                    }
                }
            };             
            widgetUpdateThread.start();  

Fragmento de código del método buildUpdate.

public RemoteViews buildUpdate(Context context) {   

httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
response = httpclient.execute(httppost);
entity = response.getEntity();
is = entity.getContent();

//etc etc...and then I return the update view and it gets updated.  
} 

Gracias por la ayuda.

preguntado el 16 de mayo de 11 a las 18:05

¿De qué línea se origina la NPE? -

@Programmer Bruce manager.updateAppWidget (thisWidget, updateViews); dentro de widgetUpdateThread run () ... eso es lo que me dicen los informes de Android Market Force Close. en com.tyu.android.TyuWidget $ UpdateService $ 1.run (TyuWidget.java:167) -

¿Hay algo en esa línea de código nulo en el momento del error? -

Lo único que podría ser nulo es updateViews. Dado que la línea está dentro de la condición if (updateViews! = Null) {} no hay razón por la cual esta línea se ejecutará si updateViews = null. Eso es lo que no entiendo. -

No creo que el análisis sea correcto. Esa línea de código tiene mucho más en marcha que solo updateViews. Me parece que se necesitan registros y análisis adicionales. -

2 Respuestas

El hilo dentro del método OnStart () de la clase UpdateService que extendió la clase Service estaba creando el problema.

Solución:

Se deshizo del hilo widgetUpdateThread y en lugar de extender la clase Service, usé IntentService. Esto genera automáticamente un hilo y funciona como un encanto. En lugar de OnStart, cuando uso IntentService, pongo el código dentro de @Override onHandleIntent y ¡Voila! No fuerce el cierre incluso cuando se usan aplicaciones en paralelo que consumen mucha CPU y memoria como FruitNinja.

¡Tipo! IntentService es altamente recomendado por la comunidad de desarrolladores y los ingenieros de Android Framework. Así que compruébalo mientras actualizas los widgets.

contestado el 18 de mayo de 11 a las 23:05

Creo que el valor de thisWidget puede ser nulo en manager.updateAppWidget (thisWidget, updateViews).

Espero que esto ayude. CD.

contestado el 18 de mayo de 11 a las 13:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.