每10秒自我更新一次的小部件Handler.postDelayed问题

发布于 2024-10-05 03:07:50 字数 2640 浏览 3 评论 0原文

我正在尝试使工作成为 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
}

我把它放在以防有人发现它有用。

但让我直接进入正题:当我让手机退出睡眠状态(打开屏幕)时,小部件会疯狂并开始以类似快进的效果更改 TextView。 我认为这是因为队列中有一些 postDelayed 事件,或者可能在 updateAppWidget 队列中。 我已经使用此处显示的代码尝试了解决方法: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/ 您可以在我的代码的第一个片段中看到它,我检查一个已存储屏幕状态的布尔变量,以避免在屏幕关闭时使用 postDelayed。但这似乎并不能解决问题。

这个问题已经让我发疯了一个星期了,所以我绝望地问:有什么办法可以正确地做到这一点吗?

I'm trying to make work a self-updating functionality in an Android widget, something simple as changing two TextViews of it every 10 seconds. The ideal solution would be to make it similar to the genie widget (news & weather). And so far, it works okay: it updates every 10 seconds via Handler.postDelayed's Runnable.

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

The runnable is initially launched in the onUpdate method of my Widget class:

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

I put this in case someone finds it useful.

But let me go straight to the point: when I get the phone out of sleep (turn on the screen), the widget goes crazy and starts changing the TextViews with a fastforward-like effect.
I assume it is because there are some postDelayed events in queue, or may be in the updateAppWidget queue.
I've already tried a workaround using the code shown in here: http://thinkandroid.wordpress.com/2010/01/24/handling-screen-off-and-screen-on-intents/
You can see it in the first snippet in my code, I check a boolean variable that has stored screen state to avoid using postDelayed when the screen is turned off. But that doesn't seem to fix it.

This problem is driving me crazy for one week now, so I ask out of despair: is there any way to do this properly?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吻安 2024-10-12 03:07:50

您的 postDelayed 调用不在 if (screenEnabled) 块内,因此即使 screenEnabled 为 false,它也会继续发布事件

Your postDelayed call isn't inside your if (screenEnabled) block, so it will continue to post the events even when the screenEnabled is false

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文