Расширение Dashclock Widget не обновляется

У меня есть 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));
}        

Это мой BroadcastReceiver:

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

Я заметил, что во время запуска трансляции приемник иногда не получает событие.
Я протестировал его, убив мое приложение, но это не воспроизводит проблему, поэтому я не понимаю, почему это произойдет.

Кто-нибудь?

3 ответа

Решение

Хотя мой первый ответ работает, у него есть некоторые нежелательные побочные эффекты. Поэтому я придумал лучшее решение без побочных эффектов.

Поручите DashClockWidget наблюдать за определенным Uri, используя addWatchContentUris, а затем, когда пришло время обновить виджет, просто вызовите notifyChange для этого Uri:

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()).

Посмотрите, как реализован приемник вещания GCM в примере Google GCM Client.

Это может быть из-за того, что ваше приложение было убито ОС Android, потому что ему требовалось больше памяти (или по какой-либо причине), и тогда вы не будете получать трансляции в своем приемнике вещания.

Я надеюсь, что это поможет, если нет, пожалуйста, предоставьте нам некоторые журналы и дополнительную информацию.

Удачи!

После выполнения обширных тестов я получил некоторые результаты, которые могут быть интересны и другим разработчикам:

  • Это действительно происходит, когда приложение убивается Android (я не ждал, пока Android убьет приложение, но, конечно, убил его вручную)
  • DashClock Widget через некоторое время снова связывает сервис. Я предполагаю, что он снова связывает службу, когда запускает запланированное обновление пользовательского интерфейса, которое выполняется примерно раз в час (согласно Javadoc DashClockExtension). Однако я не подтвердил эту догадку, пройдя исходный код.
  • Таким образом, расширение будет обновляться в конце концов, но только после выполнения обычного цикла обновления, который может продолжаться не более часа.

Вот мой обходной путь:

  • DashClock Widget прослушивает ACTION_PACKAGE_CHANGED Intents ( http://developer.android.com/reference/android/content/Intent.html), чтобы найти все расширения DashClockExtensions (служба с фильтром намерений ACTION_EXTENSION)
  • Отключив и повторно включив службу DashClockExtension при запуске моего приложения, я могу "заставить" DashClock Widget сразу связать службу.
  • Я проверил это, и прошло несколько секунд после того, как приложение было убито и перезапущено, пока пользовательский интерфейс виджета DashClock снова не обновился.

Вот как я отключаю, включаю сервис:

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);
}
Другие вопросы по тегам