App Widget Update Service有时会关闭 - 需要帮助!

时间:2011-05-16 18:30:25

标签: java android android-appwidget

此问题的背景。我有一个与我的应用程序关联的appwidget,它定期更新设置的时间间隔,使用更新服务对服务器发送http帖子,并使用从服务器接收的数据更新小部件。

我从测试和用户报告中注意到,当窗口小部件更新和网络状态从可用更改为不可用时,这个特定的强制关闭实例会定期(但很少见)发生。因为我在纽约地铁的手机上注意到了这一点。

调试时我发现如果http帖子发生并且网络状态在收到响应之前发生了变化,它基本上会收到IOException。所以我处理了这个异常,并在此特定情况下使用默认更新更新了小部件。它运作良好。

但有趣的是,我再次注意到了Force Close,并且想法如何解决这个问题。

以前有没有人遇到过这个问题并且知道如何处理这个问题?

 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)

一些代码段可能会帮助您的所有专家更好地了解问题并帮助初学者。

@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);
        }   
}

这是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));

}

更新小部件的UpdateService类的OnStart方法内的线程。

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();  

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.  
} 

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

扩展Service类的UpdateService类的OnStart()方法内的线程正在创建问题。

解决方案:

摆脱了widgetUpdateThread线程而不是扩展Service类,使用了IntentService。这会自动产生一个线程,就像一个魅力。在使用IntentService时,我将代码放在@Override onHandleIntent和Voila中,而不是OnStart!即使在并行使用像FruitNinja这样CPU和内存密集的应用程序时也没有强制关闭。

专家!开发人员社区和Android Framework工程师强烈建议使用IntentService。所以在更新小部件时要检查它。

答案 1 :(得分:0)

我认为在manager.updateAppWidget(thisWidget,updateViews)中thisWidget值可能为null。

希望这会有所帮助。 CD。