6

我有一个DashClockExtension有时不更新。

它使用 LocalBroadcastReceiver 来更新类似于http://bit.ly/1e4uMl0的扩展。接收者在onInitialize()方法中注册:

@Override
    protected void onInitialize(boolean isReconnect) {
        super.onInitialize(isReconnect);

        LocalBroadcastManager broadcastMgr = LocalBroadcastManager.getInstance(this);
        if (mDashClockReceiver != null) {
            try {
                broadcastMgr.unregisterReceiver(mDashClockReceiver);
            } catch (Exception ignore) {}
        }
        mDashClockReceiver = new DashClockUpdateReceiver();
        broadcastMgr.registerReceiver(mDashClockReceiver, new IntentFilter(UPDATE_DASHCLOCK));
    }

这就是我发送广播的方式:

public static void updateDashClock() {
    LocalBroadcastManager.getInstance(Application.getContext()).sendBroadcast(new Intent(UPDATE_DASHCLOCK));
}        

那是我的广播接收器:

private class DashClockUpdateReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        retrieveDataAndUpdateWidget();
    }
}

我注意到,当广播被触发时,接收器有时不会收到事件。
我通过杀死我的应用程序对其进行了测试,但这并没有重现问题,所以我不知道为什么会发生这种情况。

任何人?

4

3 回答 3

2

请看一下 GCM 广播接收器是如何在Google 的 GCM 客户端示例中实现的。

这可能是因为您的应用程序被 Android 操作系统杀死,因为它需要更多内存(或出于任何原因),然后您将无法在广播接收器中接收到广播。

希望对您有所帮助,如果没有,请向我们提供一些日志和更多信息。

祝你好运!

于 2013-12-19T17:02:26.117 回答
1

在运行了广泛的测试之后,我得到了一些其他开发人员可能也会感兴趣的结果:

  • 当应用程序被Android杀死时确实会发生这种情况(我没有等待Android杀死应用程序而是手动杀死它)
  • DashClock Widget 会在一段时间后再次绑定服务。我的猜测是,当它运行大约每小时一次的预定 ui 更新时,它会再次绑定服务(根据 DashClockExtension javadoc)。不过,我没有通过查看源代码来确认这个猜测。
  • 因此,扩展最终将更新,但仅在常规更新周期运行后才会更新,这可能长达一个小时都不会发生。

这是我的解决方法:

  • DashClock Widget 侦听 ACTION_PACKAGE_CHANGED Intents ( http://developer.android.com/reference/android/content/Intent.html#ACTION_PACKAGE_CHANGED ) 以查找所有 DashClockExtensions (使用 ACTION_EXTENSION 意图过滤器的服务)
  • 通过在我的应用程序启动时禁用和重新启用 DashClockExtension 服务,我可以“强制”DashClock Widget 立即绑定该服务。
  • 我对此进行了测试,在应用程序被终止并重新启动后需要几秒钟,直到 DashClock 小部件 ui 再次更新。

以下是我禁用、启用服务的方法:

configureComponent("mypackagename.DashClockService", false); // disable
configureComponent("mypackagename.DashClockService", true);  // enable

private void configureComponent(Context context, String className, boolean enable) {
    PackageManager pkMgr = context.getPackageManager();
    String packageName = context.getPackageName();
    ComponentName component = new ComponentName(packageName, className);
    int newState = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED : PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
    pkMgr.setComponentEnabledSetting(component, newState, PackageManager.DONT_KILL_APP);
}
于 2013-12-20T21:43:09.013 回答
1

虽然我的第一个答案有效,但它有一些不受欢迎的副作用。因此,我想出了一个没有副作用的更好的解决方案。

指示 DashClockWidget 使用 addWatchContentUris 观察某个 Uri,然后当需要更新小部件时,只需在该 Uri 上调用 notifyChange:

public class DashClockService extends DashClockExtension {
    private static final Uri URI_BASE = Uri.parse("content://com.myauthority");
    private static final String URI_PATH_SEGMENT = "dashclock/update";

    public static void updateWidget(Context context) {
        ContentResolver contentResolver = context.getContentResolver();
        Uri uri = Uri.withAppendedPath(URI_BASE, URI_PATH_SEGMENT);
        contentResolver.notifyChange(uri, null);
    }

    @Override
    protected void onInitialize(boolean isReconnect) {
        super.onInitialize(isReconnect);

        removeAllWatchContentUris();
        Uri uri = Uri.withAppendedPath(URI_BASE, URI_PATH_SEGMENT);
        addWatchContentUris(new String[] {uri.toString()});
    }

可以从代码中的任何位置调用 updateWidget 来更新小部件。最重要的是,它可以在应用程序启动时调用,例如在它被 Android 杀死并重新启动之后(我在 Application.onCreate() 中调用更新)。

于 2014-05-13T04:46:45.577 回答