Расширение 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);
}