【发布时间】: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