10

Quindi ho un widget di app che si sta rinfrescando bene, caricando una nuova bitmap in un ImageView regolarmente come un orologio. Poi, ad un certo punto, e in silenzio, smetterà di aggiornarsi ulteriormente. Posso dire dal registro, e dall'attività su un server che il mio codice sta interrogando, che il widget sta ancora continuando a sparare regolarmente (tramite le trasmissioni catturate da onReceive() e facendo le sue cose come previsto. L'unica cosa che non è sta accadendo è che il contenuto del widget non si sta aggiornandoappwidget si blocca e si rifiuta di aggiornare più: ignora updateAppWidget

Quindi, nel codice che viene eseguito quando il widget si attiva, sto creando un nuovo RemoteViews e aggiungendo cose ad esso, incluso il caricamento di una nuova bitmap tramite remoteViews.setImageViewBitmap(imageViewID, bmp) e infine chiamando appWidgetManager.updateAppWidget(appWidgetId, remoteViews) per aggiornare il contenuto del widget. Funziona bene ... finché non smette di funzionare.

Non sono sicuro del codice da pubblicare, perché la cosa funziona perfettamente il 99% delle volte, ma a volte il updateAppWidget() smette di funzionare , senza una ragione apparente. Sembra che sia un problema di sistema, piuttosto che un bug nel mio codice, ma potrei sbagliarmi.

L'unica cosa che sembra richiedere questo è quando ci sono cambiamenti nella connettività, ad es. passando da nessun segnale a WiFi, forse frequenti questi cambiamenti. Sembra che succeda di più in quelle situazioni.

E una volta che il widget si blocca, l'unica cosa che lo sblocca è il riavvio del dispositivo. Senza riavviare, anche rimuovere il widget e aggiungerne uno non funziona. Infatti, l'aggiunta di una nuova porta a un widget morto che non risponde nemmeno a un clic per aprire l'attività di configurazione, presumibilmente perché remoteViews.setOnClickPendingIntent(R.id.widget, configPendingIntent) viene ignorato come qualsiasi altra cosa nello RemoteViews Io costruisco e inviamo attentamente a appWidgetManager.updateAppWidget().

sembra essere più o meno come descritto da molti altri qui:

https://code.google.com/p/android/issues/detail?id=28216

e ancora non sembra esserci alcuna cura conosciuta. Il post allo https://code.google.com/p/android/issues/detail?id=28216#c56 sembrava offrire qualche promessa, ma ho provato a chiamare AppWidgetHost.startListening() in vari posti, anche a intervalli regolari tramite un allarme ripetuto per vedere se potevo avviare il widget, ma niente sembra funzionare.

e gli altri utenti (piuttosto che sviluppatori) sembrano essere vedere questo problema troppo: http://androidforums.com/threads/clock-widget-keeps-freezing-please-help.530333/

Tutte le idee? Mi sta facendo impazzire lentamente!

+0

Non ho anche trovato una soluzione, ma ho trovato una soluzione (anche se non buona). Ho scoperto che il problema è scomparso dopo aver rimosso diversi altri widget simili dalla schermata iniziale. Il mio widget è simile ad altri sul Play Store, quindi ho avuto un paio di widget dalla mia competizione anche sulla mia schermata iniziale. Da quando ho rimosso il loro, il mio è stato aggiornato senza alcun problema tecnico. Ho anche provato a liberare più memoria possibile, a svuotare le cache delle app e il logcat (componi * # 9900 # nel telefono, quindi premi il pulsante "Elimina dumpstate/logcat"). Da allora va bene. – drmrbrewer

risposta

5
remoteViews.setImageViewBitmap(imageViewID, bmp) 

Non farlo. Facendo questo, pacchi la bitmap e invia l'intera operazione come una transazione di binder. I raccoglitori hanno lo scopo di trasferire una piccola quantità di dati e non gestiscono bene i bitmap. Anche quando il widget si aggiorna, utilizza più risorse di sistema del necessario e più risorse di avvio (il programma di avvio deve rimuovere la bitmap, almeno temporaneamente memorizzando sia i byte parcelati che quelli non selezionati, e deve essere fatto sul thread dell'interfaccia utente . Ma il problema che state vedendo è il bug si è collegato, a volte grandi transazioni legante innescare un TransactionTooLargeException e la AppWidgetManagerService non gestisce correttamente questo arrestando tutti gli aggiornamenti futuri (a volte a tutti i widget, a volte solo per il vostro).

Invece si dovrebbe utilizzare setImageViewUrihttps://developer.android.com/reference/android/widget/RemoteViews.html#setImageViewUri(int,%20android.net.Uri).È un po 'più di lavoro perché è necessario salvare la bitmap e quindi inviare al programma di avvio un uri per esso, anche se attualmente tutti o quasi tutti i lanciatori hanno READ_EXTERNAL_STORAGE quindi un uri file:/// su memoria esterna potrebbe funzionare, non dovresti fare affidamento su quello in futuro e invece dovrei usare un FileProviderhttps://developer.android.com/reference/android/support/v4/content/FileProvider.html