【问题标题】:App Widget Update Service force closes sometimes - Need help!App Widget Update Service force 有时会关闭 - 需要帮助!
【发布时间】:2011-05-19 03:08:34
【问题描述】:

这个问题的背景。我有一个与我的应用关联的 appwidget,它会定期更新,使用更新服务向服务器发送 http 帖子,并使用从服务器接收到的数据更新小部件。

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

调试时我发现如果http post已经发生并且在收到响应之前网络状态发生变化,它基本上会收到一个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)

一些代码 sn-ps 可能会帮助所有专家更好地理解问题并帮助初学者。

@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 方法代码 sn-p。

    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 方法代码 sn-p.

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

感谢您的帮助。

【问题讨论】:

  • NPE 来自哪一行?
  • @Programmer Bruce manager.updateAppWidget(thisWidget, updateViews);在widgetUpdateThread run() ...这就是Android Market Force Close 报告告诉我的内容。在 com.tyu.android.TyuWidget$UpdateService$1.run(TyuWidget.java:167)
  • 出错时该行代码是否为空?
  • 唯一可以为空的是updateViews。由于该行位于 if(updateViews!=null){} 条件内,因此如果 updateViews = null 则没有理由执行该行。那是我不明白的。
  • 我不认为这种分析是正确的。那行代码除了 updateViews 之外还有更多工作要做。在我看来,额外的日志记录和分析是有序的。

标签: java android android-appwidget


【解决方案1】:

UpdateService 类的 OnStart() 方法中扩展 Service 类的线程造成了问题。

解决方案:

摆脱了 widgetUpdateThread 线程,而不是扩展服务类,使用 IntentService。这会自动产生一个线程并且像一个魅力一样工作。而不是 OnStart,当使用 IntentService 时,我将代码放在 @Override onHandleIntent 中,瞧!即使并行使用像 FruitNinja 这样占用大量 CPU 和内存的应用程序,也不会强制关闭。

伙计们! IntentService 受到开发者社区和 Android 框架工程师的强烈推荐。所以在更新小部件时检查一下。

【讨论】:

    【解决方案2】:

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

    希望这会有所帮助。 光盘。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 2011-09-15
      • 2021-11-12
      • 2014-09-22
      • 2014-08-31
      • 2018-02-15
      相关资源
      最近更新 更多