Java 应用程序小部件更新服务有时关闭-需要帮助!

Java 应用程序小部件更新服务有时关闭-需要帮助!,java,android,android-appwidget,Java,Android,Android Appwidget,这个问题的背景。我有一个与我的应用程序相关联的appwidget,它使用一个更新服务定期更新,该服务向服务器发送http消息,并使用从服务器接收的数据更新小部件 我从测试和用户报告中注意到,强制关闭的特定实例会定期(但很少)发生,此时小部件将更新,网络状态从可用变为不可用。自从我在纽约地铁的电话里注意到这个 在调试过程中,我发现如果http post已经发生,并且在收到响应之前网络状态发生了变化,那么它基本上会收到一个IOException。因此,我处理了这个异常,并在这个特殊情况下使用默认更新

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

我从测试和用户报告中注意到,强制关闭的特定实例会定期(但很少)发生,此时小部件将更新,网络状态从可用变为不可用。自从我在纽约地铁的电话里注意到这个

在调试过程中,我发现如果http post已经发生,并且在收到响应之前网络状态发生了变化,那么它基本上会收到一个IOException。因此,我处理了这个异常,并在这个特殊情况下使用默认更新更新了小部件。它工作得很好

但有趣的是,我注意到这股力量再次关闭,我已经没有办法解决这个问题了

以前有没有人遇到过这种情况,知道我如何处理

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

}
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.  
} 
更新小部件的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 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));

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

感谢您的帮助。

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

希望这有帮助。 CD.

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

解决方案:

摆脱了widgetUpdateThread线程,使用了IntentService而不是扩展服务类。这会自动生成一个线程,并像符咒一样工作。在使用IntentService时,我没有使用OnStart,而是将代码放在@Override onHandleContent中,瞧!即使在并行使用像《忍者》这样CPU和内存非常密集的应用程序时,也没有强制关闭


伙计们!开发者社区和Android框架工程师强烈推荐IntentService。因此,在更新小部件时查看它。

NPE来自哪一行?@Programmer Bruce manager.updateAppWidget(这个小部件,updateViews);widgetUpdateThread run()…这就是Android市场力量关闭报告告诉我的。在com.tyu.android.TyuWidget$UpdateService$1.run(TyuWidget.java:167)上,出错时代码行中的任何内容是否为null?唯一可以为null的是updateViews。由于该行位于条件if(updateViews!=null){}内,因此没有理由在updateViews=null时执行该行。这就是我不理解的。我认为这种分析是不正确的。这行代码比updateViews有更多的功能。在我看来,额外的日志记录和分析是必要的。