我正在尝试使工作成为 Android 小部件中的自我更新功能,就像每 10 秒更改两个 TextView 一样简单。理想的解决方案是使其类似于精灵小部件(新闻和天气)。到目前为止,它运行良好:它通过 Handler.postDelayed 的 Runnable 每 10 秒更新一次。
Runnable updateWidgetText = new Runnable()
{
@Override
public void run() {
if (screenEnabled) {
AppWidgetManager gm = AppWidgetManager.getInstance(ctx);
ComponentName thisWidget = new ComponentName(ctx,AnimeUndergroundWidget.class);
int index = (int)(REFRESH_COUNT % WIDGET_NEWS_TO_SHOW);
Noticia n = AUnder.single().getNoticiaByIndex(index);
if (n!=null)
{
last = n;
RemoteViews views = new RemoteViews(ctx.getPackageName(),R.layout.auwidget);
views.setTextViewText(R.id.widget_textview, n.getTitulo());
views.setTextViewText(R.id.widget_textototal, n.getTexto().replace("\n", ""));
Intent clickintent = new Intent(INTENT_GO_TO_NEW);
PendingIntent pendingIntentClick = PendingIntent.getBroadcast(ctx, 0, clickintent, 0);
views.setOnClickPendingIntent(R.id.widget_fondo_titulo, pendingIntentClick);
Intent click2intent = new Intent(INTENT_GO_TO_NEW);
PendingIntent pendingIntentClick2 = PendingIntent.getBroadcast(ctx, 0, click2intent, 0);
views.setOnClickPendingIntent(R.id.widget_fondo_Texto, pendingIntentClick2);
gm.updateAppWidget(thisWidget, views);
}
REFRESH_COUNT++;
}
handler.removeCallbacks(this);
handler.postDelayed(this, WIDGET_REFRESH_TIME*1000);
}
};
runnable 最初是在我的 Widget 类的 onUpdate 方法中启动的:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
ctx = context;
context.startService(new Intent(context, UpdateWidgetService.class));
handler.postDelayed(updateWidgetText,WIDGET_REFRESH_TIME*1000);
// here goes some more code, updating the views and refreshing click intents
}
我放这个以防有人发现它有用。
但是让我直奔主题:当我让手机脱离睡眠状态(打开屏幕)时,小部件会发疯,并开始以类似快进的效果更改 TextViews。我认为这是因为队列中有一些 postDelayed 事件,或者可能在 updateAppWidget 队列中。我已经使用此处显示的代码尝试了一种解决方法:http: //thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/ 您可以在在我的代码中的第一个片段,我检查了一个布尔变量,该变量存储了屏幕状态以避免在屏幕关闭时使用 postDelayed。但这似乎并不能解决问题。
这个问题让我疯狂了一个星期,所以我绝望地问:有什么办法可以正确地做到这一点?