【问题标题】:Android AppWidget onClick not working after garbage collection垃圾收集后Android AppWidget onClick不起作用
【发布时间】:2013-10-30 20:54:53
【问题描述】:

我为我的应用创建了一个 AppWidget 并将 updatePeriodMillis 设置为 0, 因为如果用户不交互,这个 Widget 什么都不做。

一切正常,直到 Android 清理内存。然后小部件将不再响应,直到应用程序再次启动或设备重新启动(在这两种情况下,onUpdate() 都会再次运行)。

所以我的问题是:在 Android 踢出应用程序后,我需要做什么才能让它恢复工作?

这是清单的一部分:

    <receiver android:name="WidgetProvider" >
        <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            <action android:name="PATH.widgetBtnStartClicked" />
        </intent-filter>
        <meta-data android:name="android.appwidget.provider"
                   android:resource="@xml/appwidget_provider_info" />
    </receiver>

这是我的 WidgetProvider 的一部分:

public class WidgetProvider extends AppWidgetProvider {

private static final String BTN_START_CLICKED = "PATH.widgetBtnStartClicked";


private static Values values;

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
        int[] appWidgetIds) {

    super.onUpdate(context, appWidgetManager, appWidgetIds);

    // get RemoteView (widget):
    for (int i = 0; i < appWidgetIds.length; i++) {
        int appWidgetId = appWidgetIds[i];

        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.appwidget);


        // Register onClick for App-start-button:
        Intent intentLaunch = new Intent(BTN_APP_LAUNCH_CLICKED);
        intentLaunch.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        PendingIntent pendingIntentLaunch = PendingIntent.getBroadcast(
                context, appWidgetId, intentLaunch,
                PendingIntent.FLAG_UPDATE_CURRENT);
        views.setOnClickPendingIntent(R.id.appwidget_btn_launch,
                pendingIntentLaunch);


        appWidgetManager.updateAppWidget(appWidgetId, views);

    }

}

@Override
public void onReceive(Context context, Intent intent) {
    RemoteViews views = new RemoteViews(context.getPackageName(),
            R.layout.appwidget);

    super.onReceive(context, intent);

    AppWidgetManager appWidgetManager = AppWidgetManager
            .getInstance(context);
    ComponentName componentName = new ComponentName(context,
            WidgetProvider.class);

    if (intent.getAction().equals(BTN_APP_LAUNCH_CLICKED)) {

        //do some stuff..
    }
    // update views
    appWidgetManager.updateAppWidget(componentName, views);

}

我希望有你需要的一切来理解这个问题。如果没有,请告诉我!

【问题讨论】:

    标签: android android-appwidget appwidgetprovider


    【解决方案1】:

    我认为您的应用仅依赖 onUpdate() 来刷新小部件。还有其他事件会导致挂起的意图“放弃”小部件。 比如你提到的内存清理。

    我建议你:
    + 将您的小部件更新代码放在单独的服务类中
    + 在发生不同事件时触发该类。 onUpdate() 和其他事件,例如导致 RAM 被清除的事件。
    + 确保您每次都使用远程视图更新所有内容,因为不会保留旧的待处理意图等。

    您可以完全控制触发小部件更新的事件。

    如果适合您的情况,您还可以使用警报管理器和接收器类设置任意警报。这样,您可以将警报设置为仅在手机唤醒时接收,并使用它来调用您的更新服务类。在您的更新服务类中,然后清除任何警报(如果从另一个事件调用更新)并设置另一个警报。

    关于 SO 有很多关于谁使用带有小部件的服务的问题。解决它应该不会花很长时间。将这些信息放在这里超出了这个问题的范围。

    【讨论】:

    • 没错,它只依赖onUpdate()。我曾经听说过使用一项服务,但我仍然不知道如何以适当的方式使用它。你能给我一个小例子吗?我只需要知道从哪里开始这项服务以及它应该是什么样子。我不知道哪些事件会导致 ram 被清除……如果没有足够的可用空间(比如打开一个大应用程序时),Android 就会这样做。我会很高兴有一个简短的例子或更多信息。到目前为止谢谢!
    • 感谢您的解释,但我还是完全不明白。如何将 AppWidgetManager 或 appWidgetIds 等信息传递给服务?即使我这样做了,我怎样才能在正确的时间触发?我的意思是正确的时间应该是小部件可见的时候。我问自己谷歌是如何在它的“声音搜索”小部件中做到这一点的。现在在 ram-cleaning 和更新小部件之间有时间。我的意思是当我关闭导致 ram-cleaning 的应用程序时,这个应用程序仍然有效,但我的不是。
    • Service-Thing 不是大问题(我让它运行了),但我仍然不知道如何在 ram 被清理后调用它(或者甚至像你说的那样) :设备唤醒后)。我试图找到答案(当然是好几个小时),但我仍然没有进展。
    • 我会试试这个:stackoverflow.com/questions/13443543/…你是这个意思吗?
    • 我会做一些进一步的测试,但我认为这很有魅力:-)
    猜你喜欢
    • 2011-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多