2016-03-07 35 views
0

我想要一个android应用程序小部件来定期更新。我使用了Handler来达到这个目的,因为我希望它更频繁地更新(一分钟一次)。在onEnabled()上声明Handler的调用按预期工作。但有时会失败。该小部件不升级,并通过日志记录,我发现Handler成为null。所以我宣布Service来更新小部件并宣布Handler并用它更新。现在我所有的小部件都是在onEnabled()呼叫中启动服务,并在onDisabled()呼叫上停止它。 Service始终运行并更新小部件。代码:使用服务处理程序更新应用程序小部件

public void onCreate() { 
    super.onCreate(); 
    handler=new Handler(); 
    runnable=new Runnable() { 
     @Override 
     public void run() { 
      ComponentName appWidget=new ComponentName(getApplicationContext().getPackageName(),widget.class.getName()); 
      AppWidgetManager widgetManager= AppWidgetManager.getInstance(getApplicationContext()); 
      int ids[]=widgetManager.getAppWidgetIds(appWidget); 
      for(int id:ids) 
      { 
       RemoteViews views = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widgetLayout); 
//Update Widget here      
     widgetManager.updateAppWidget(id, views); 
      } 
      handler.postDelayed(runnable, delay); 
     } 
    }; 
} 
@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    handler.post(runnable); 
    return super.onStartCommand(intent, flags, startId); 
} 

这是更新窗口小部件的最佳方法吗?因为这意味着用户可以使用任务杀手来终止该服务,这将导致该小部件无法正常工作,并且如果该设备重新启动,则该服务将不会运行。那么如何摆脱这个并更新小部件?还是有一种更有效的方式来非常频繁且可靠地更新小部件?谢谢。

回答

0

为了更确定您不会遇到您描述的不当行为,您应该将其从您的进程中移除,并让其他组件处理更新间隔。 AlarmManager有一个功能,可以为你做这个:public void setRepeating (int type, long triggerAtMillis, long intervalMillis, PendingIntent operation)

您可以使用它像这样

AlarmManager aManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
aManager.setRepeating(/*clock_type*/, /*first trigger*/, /*update time*/, /*action*/); 

您可以在这里找到的文档:http://developer.android.com/reference/android/app/AlarmManager.html

通过移动你想要的AlarmManager的功能,如果您的应用程序就会被杀死也没关系。因为AlarmManager会送你一个新的Intent你的过程将被带回生活和你的小工具将继续同时正常工作

,如果你正在使用窗口小部件,你可能想看看AppWidgetProviderhttp://developer.android.com/reference/android/appwidget/AppWidgetProvider.html)。它专门用于创建和控制部件

+0

感谢您的回答。我已经尝试使用小部件中的'AlarmManager'。它的工作,但它也有时失败,我的小部件被冻结。这就是为什么我使用Handler。 –

+0

只要对AlarmManager进行调用,我认为不会有太大的区别。我很惊讶地听到它有时会失败 – 0xDEADC0DE

+0

是的。有时候我会看到这个小部件刚刚被冻结而没有更新。即使当我使用处理程序从小部件内部进行更新时,也会发生这种情况。当我手动触发配置活动的更新时,该更新将起作用。但不能与AlarmManager或处理程序。 –