2012-11-13 19 views
6

Fondamentalmente quello che voglio fare è passare un oggetto parcelable personalizzato tramite intento, a RemoteViewsService e quindi a RemoteViewsFactory. Per qualche ragione, questo semplicemente non funziona: S Ogni volta che tento di farlo, il widget finisce per visualizzare invece il testo "Problema caricamento widget".Passare l'oggetto parcelable personalizzato extra o in ArrayList su RemoteViewsService interrompe l'appwidget

Quando provo la stessa cosa, ma invece di passarlo a RemoteViewsService, lo passo a un'attività normale, funziona esattamente come previsto.

Ho cercato di trovare la mia risposta online, ma non ho avuto successo, quindi ora inserisco qui nella speranza di essere aiutato.

Ho cercato di farlo funzionare nel mio programma principale per un po '. Ma non riuscivo a capirlo. Così ho provato a bollire, per vedere se in qualche modo ho fatto qualcosa di sbagliato ad un certo punto. Sono riuscito a ricreare il problema, e la base su cui ho ricreato il mio problema è da LoremWidget di CommonsGuy (https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget/LoremWidget) e un esempio casuale parcellabile (http://prasanta-paul.blogspot.dk/2010/06/android-parcelable-example.htm l) che ho modificato per funzionare per mostrare il mio problema. (Spero di non otterrete nei guai, dopo aver usato il codice a questi due link)

Heres il codice completo caricato il file host casuale nel caso qualcuno vuole TestRun cosa sto parlando: http://www.filedropper.com/remoteviewserviceparcelerrorexample

Quindi, per riassume la mia domanda:

Perché non posso passare i miei oggetti parcelable (da solo o racchiusi in un ArrayList) al mio RemoteViewsService? (Quando lo stesso codice funziona bene con un'attività)

Spero davvero che qualcuno possa darmi una mano. Proprio ora, nel mio programma principale, sto eseguendo la serializzazione su memoria interna e poi la deserializza nuovamente da RemoteViewsService in modo abbastanza immediato, il che, da tutto ciò che ho letto, non può essere molto efficace!

Modifica: appena ricordato, che per qualche motivo nel mio programma principale, se mi passa uno degli oggetti personalizzati, con l'ArrayList e archi impostati su nulla, e le booleani tutto su false (in pratica esattamente come gli sguardi degli oggetti al momento della creazione), il widget appare normale (ovvero non viene visualizzato il messaggio "Problema caricamento widget").

Edit: Dopo aver guardato l'aspetto (non filtrata per l'applicazione correvo) ora vedo alcuni errori (indovino che meglio imparare a guardare tutto non filtrata quando ottengo nulla filered :)):

 11-13 17:14:27.268: D/AndroidRuntime(8840): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
    11-13 17:14:27.268: D/AndroidRuntime(8840): CheckJNI is ON 
    11-13 17:14:27.340: D/AndroidRuntime(8840): Calling main entry com.android.commands.pm.Pm 
    11-13 17:14:27.348: W/ActivityManager(90): No content provider found for permission revoke: file:///data/local/tmp/com.commonsware.android.appwidget.lorem.LoremActivity.apk 
    11-13 17:14:27.348: W/ActivityManager(90): No content provider found for permission revoke: file:///data/local/tmp/com.commonsware.android.appwidget.lorem.LoremActivity.apk 
    11-13 17:14:27.356: I/PackageManager(90): Removing non-system package:com.commonsware.android.appwidget.lorem 
    11-13 17:14:27.360: I/ActivityManager(90): Force stopping package com.commonsware.android.appwidget.lorem uid=10034 
    11-13 17:14:27.360: I/ActivityManager(90): Killing proc 8798:com.commonsware.android.appwidget.lorem/10034: force stop 
    11-13 17:14:27.400: D/dalvikvm(90): GC_CONCURRENT freed 511K, 17% free 8611K/10311K, paused 0ms+0ms 
    11-13 17:14:27.400: I/PackageManager(90): Package com.commonsware.android.appwidget.lorem codePath changed from /data/app/com.commonsware.android.appwidget.lorem-2.apk to /data/app/com.commonsware.android.appwidget.lorem-1.apk; Retaining data and using new 
    11-13 17:14:27.404: I/PackageManager(90): Running dexopt on: com.commonsware.android.appwidget.lorem 
    11-13 17:14:27.440: D/dalvikvm(8850): DexOpt: load 12ms, verify+opt 4ms 
    11-13 17:14:27.448: W/PackageManager(90): Code path for pkg : com.commonsware.android.appwidget.lorem changing from /data/app/com.commonsware.android.appwidget.lorem-2.apk to /data/app/com.commonsware.android.appwidget.lorem-1.apk 
    11-13 17:14:27.448: W/PackageManager(90): Resource path for pkg : com.commonsware.android.appwidget.lorem changing from /data/app/com.commonsware.android.appwidget.lorem-2.apk to /data/app/com.commonsware.android.appwidget.lorem-1.apk 
    11-13 17:14:27.452: I/ActivityManager(90): Force stopping package com.commonsware.android.appwidget.lorem uid=10034 
    11-13 17:14:27.460: D/PackageManager(90): New package installed in /data/app/com.commonsware.android.appwidget.lorem-1.apk 
    11-13 17:14:27.472: I/ActivityManager(90): Force stopping package com.commonsware.android.appwidget.lorem uid=10034 
    11-13 17:14:27.496: D/dalvikvm(266): GC_EXPLICIT freed 127K, 9% free 6766K/7367K, paused 0ms+0ms 
    11-13 17:14:27.512: D/dalvikvm(221): GC_EXPLICIT freed 878K, 57% free 15010K/34119K, paused 0ms+0ms 
    11-13 17:14:27.584: D/dalvikvm(90): GC_EXPLICIT freed 385K, 18% free 8558K/10311K, paused 0ms+0ms 
    11-13 17:14:27.588: D/PackageManager(90): generateServicesMap(android.accounts.AccountAuthenticator): 2 services unchanged 
    11-13 17:14:27.620: D/PackageManager(90): generateServicesMap(android.content.SyncAdapter): 4 services unchanged 
    11-13 17:14:27.620: D/BackupManagerService(90): Received broadcast Intent { act=android.intent.action.PACKAGE_REMOVED dat=package:com.commonsware.android.appwidget.lorem flg=0x10000010 (has extras) } 
    11-13 17:14:27.620: D/PackageManager(90): generateServicesMap(android.accounts.AccountAuthenticator): 2 services unchanged 
    11-13 17:14:27.620: D/PackageManager(90): generateServicesMap(android.content.SyncAdapter): 4 services unchanged 
    11-13 17:14:27.628: W/ResourceType(90): Failure getting entry for 0x7f060000 (t=5 e=0) in package 0 (error -75) 
    11-13 17:14:27.632: D/BackupManagerService(90): Received broadcast Intent { act=android.intent.action.PACKAGE_ADDED dat=package:com.commonsware.android.appwidget.lorem flg=0x10000010 (has extras) } 
    11-13 17:14:27.636: V/BackupManagerService(90): updatePackageParticipantsLocked: #1 
    11-13 17:14:27.640: W/RecognitionManagerService(90): no available voice recognition services found 
    11-13 17:14:27.652: D/dalvikvm(8854): Not late-enabling CheckJNI (already on) 
    11-13 17:14:27.684: I/ActivityManager(90): Start proc com.commonsware.android.appwidget.lorem for broadcast com.commonsware.android.appwidget.lorem/.WidgetProvider: pid=8854 uid=10034 gids={} 
    11-13 17:14:27.688: D/BackupManagerService(90): Received broadcast Intent { act=android.intent.action.PACKAGE_REPLACED dat=package:com.commonsware.android.appwidget.lorem flg=0x10000010 (has extras) } 
    11-13 17:14:27.688: V/BackupManagerService(90): updatePackageParticipantsLocked: #1 
    11-13 17:14:27.740: I/dalvikvm(8854): Turning on JNI app bug workarounds for target SDK version 11... 
    11-13 17:14:27.756: D/dalvikvm(90): GC_EXPLICIT freed 409K, 16% free 8687K/10311K, paused 0ms+4ms 
    11-13 17:14:27.792: D/AndroidRuntime(8840): Shutting down VM 
    11-13 17:14:27.796: D/dalvikvm(8840): GC_CONCURRENT freed 99K, 79% free 447K/2048K, paused 0ms+0ms 
    11-13 17:14:27.796: D/dalvikvm(8840): Debugger has detached; object registry had 1 entries 
    11-13 17:14:27.812: I/AndroidRuntime(8840): NOTE: attach of thread 'Binder Thread #3' failed 
    11-13 17:14:27.820: D/WidgetProvider(8854): ParcelData=ParcelData [id=0, name=null, desc=null, cities=[suwon, delhi]] 
    11-13 17:14:27.820: D/WidgetProvider(8854): ArrayList<ParcelData>=[ParcelData [id=0, name=null, desc=null, cities=[suwon, delhi]]] 
    11-13 17:14:27.824: V/ParcelData(8854): writeToParcel...0 
    11-13 17:14:27.824: V/ParcelData(8854): writeToParcel...0 
    11-13 17:14:27.828: V/ParcelData(8854): writeToParcel...0 
    11-13 17:14:27.828: V/ParcelData(8854): writeToParcel...0 
    11-13 17:14:27.828: E/Parcel(221): Class not found when unmarshalling: com.commonsware.android.appwidget.lorem.ParcelData, e: java.lang.ClassNotFoundException: com.commonsware.android.appwidget.lorem.ParcelData 
    11-13 17:14:27.832: W/AppWidgetHostView(221): updateAppWidget couldn't find any view, using error view 
    11-13 17:14:27.832: W/AppWidgetHostView(221): android.os.BadParcelableException: ClassNotFoundException when unmarshalling: com.commonsware.android.appwidget.lorem.ParcelData 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readParcelable(Parcel.java:1966) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readValue(Parcel.java:1854) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readListInternal(Parcel.java:2103) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readArrayList(Parcel.java:1544) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readValue(Parcel.java:1875) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Parcel.readMapInternal(Parcel.java:2094) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Bundle.unparcel(Bundle.java:223) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Bundle.putInt(Bundle.java:436) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.content.Intent.putExtra(Intent.java:4695) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.widget.RemoteViews$SetRemoteViewsAdapterIntent.apply(RemoteViews.java:401) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.widget.RemoteViews.performApply(RemoteViews.java:1606) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.widget.RemoteViews.apply(RemoteViews.java:1583) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.appwidget.AppWidgetHostView.updateAppWidget(AppWidgetHostView.java:289) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.appwidget.AppWidgetHost.updateAppWidgetView(AppWidgetHost.java:283) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.appwidget.AppWidgetHost$UpdateHandler.handleMessage(AppWidgetHost.java:84) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Handler.dispatchMessage(Handler.java:99) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.os.Looper.loop(Looper.java:137) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at android.app.ActivityThread.main(ActivityThread.java:4424) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at java.lang.reflect.Method.invokeNative(Native Method) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at java.lang.reflect.Method.invoke(Method.java:511) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) 
    11-13 17:14:27.832: W/AppWidgetHostView(221): at dalvik.system.NativeStart.main(Native Method) 
    11-13 17:14:28.116: D/AndroidRuntime(8872): >>>>>> AndroidRuntime START com.android.internal.os.RuntimeInit <<<<<< 
    11-13 17:14:28.116: D/AndroidRuntime(8872): CheckJNI is ON 
    11-13 17:14:28.200: D/AndroidRuntime(8872): Calling main entry com.android.commands.am.Am 
    11-13 17:14:28.204: I/ActivityManager(90): START {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000 cmp=com.commonsware.android.appwidget.lorem/.LoremActivity} from pid 8872 
    11-13 17:14:28.208: W/WindowManager(90): Failure taking screenshot for (192x135) to layer 21020 
    11-13 17:14:28.220: W/NetworkManagementSocketTagger(90): setKernelCountSet(10034, 1) failed with errno -2 
    11-13 17:14:28.240: D/AndroidRuntime(8872): Shutting down VM 
    11-13 17:14:28.244: D/dalvikvm(8872): GC_CONCURRENT freed 100K, 77% free 475K/2048K, paused 4ms+0ms 
    11-13 17:14:28.244: D/dalvikvm(8872): Debugger has detached; object registry had 1 entries 
    11-13 17:14:28.244: I/AndroidRuntime(8872): NOTE: attach of thread 'Binder Thread #1' failed 
    11-13 17:14:28.252: W/InputManagerService(90): Window already focused, ignoring focus gain of: [email protected] 
    11-13 17:14:28.504: W/NetworkManagementSocketTagger(90): setKernelCountSet(10034, 0) failed with errno -2 
+0

Si prega di inviare eventuali errori rilevanti il logcat. Dovresti vedere alcuni problemi registrati lì. –

+0

Beh, il fatto è che non vedo errori nel logcat, a meno che non provi a stampare le informazioni dal pacchetto im passando (nel qual caso ottengo solo un puntatore nullo). Ti piacerebbe ancora vedere questo errore logcat? L'unica cosa che mi dice che qualcosa non va, è il widget stesso che mostra "Problem loading widget" e il fatto che i messaggi di log pubblicati da RemoteViewsService e factory non vengono mai stampati (cioè non vengono mai chiamati o raggiunti per qualche motivo). – Chris6647

+0

Sei sicuro di non vedere nulla nel logcat? Stai filtrando il logcat? –

risposta

1

ho finito per fare quello che treking parla qui: https://groups.google.com/d/msg/android-developers/KX0BUAbOTKY/jqW_ZokCH3gJ

Quello che ho fatto è creare un'interfaccia "Bundleable" che fa sostanzialmente quello Parcelable è destinato a fare.Gli oggetti che estendono questa interfaccia possono mettersi e ricreare se stessi da un oggetto Bundle, che è Parcelable in modo che tu possa inviarlo come il tuo oggetto - tranne con il fatto che il sistema sa sempre come caricare un tipo di pacchetto quindi non ti imbatti in questo errore.

E seguendo il suo esempio di codice:

public interface Bundleable 
{ 
public Bundle toBundle(); 

public void fromBundle(Bundle b); 
} 

public class MyClass implements Bundleable 
{ 
public Bundle toBundle() 
{ 
    Bundle b = new Bundle(); 
    // Fill b with data 
    return b; 
} 

public void from Bundle(Bundle b) 
{ 
    // set properties from data in b 
} 
} 

// ... 

MyClass m = new MyClass(); 
Intent i = new Intent(); 
i.putBundleExtra("MyClass", m.toBundle()); 

// ... Elsewhere 

Bundle b = intent.getBundleExtra("MyClass"); 
MyClass m = new MyClass(b); // Constructor calls fromBundle(b); 

funzionato come mi aspettavo l'intera parcella molto a che fare fin dall'inizio! :)

0

Se non riesci a farlo funzionare utilizzando Parcelable, fallo da solo. Passa invece il ParcelData come String. Basta convertire i writeToParcel() e ParcelData(Parcel source) metodi per qualcosa di simile ("serializzazione" del povero-man):

public String serializeToString() { 
    StringBuilder sb = new StringBuilder(); 
    sb.append(Integer.toString(id)).append('|').append(name).append('|').append(desc) 
     .append('|'); 
    for (String c : cities) { 
     sb.append(c).append(';'); 
    } 
    sb.append('|'); 
    return sb.toString(); 
} 

ParcelData(String source) { 
    String[] parts = source.split("|"); 
    id = Integer.parseInt(parts[0]); 
    name = parts[1]; 
    desc = parts[2]; 
    cc = parts[3].split(";"); 
    if (cc.length == 0) { 
     cities = new String[0]; // No cities 
    } else { 
     cities = new String[cc.length - 1]; // Last element is empty 
     for (int i = 0; i < cc.length - 1; i++) { 
      cities[i] = cc[i]; 
     } 
    } 
} 

non aver corso questo attraverso un compilatore, quindi potrebbe avere degli errori di sintassi stupidi. Dovresti avere l'idea.

+0

Ho finito per fare quello che ho scritto come risposta. Ti ringrazio per avermi costretto a guardare i tronchi non filtrati. Gli indizi per il mio successo dove effettivamente proprio lì :) – Chris6647

+0

Felice che tu fossi in grado di risolverlo. Il log dei filtri è di solito una cattiva idea ;-) –

+0

Heh, di solito il log non filtrato è pieno di informazioni così diverse che è difficile tenere traccia di ciò che conta per me. Questo è il motivo per cui di solito lo filtro sempre sull'app in cui sto lavorando. Sarò sicuramente sicuro di controllare il non filtrato se corro in altri problemi che non sono mostrati in quello filtrato! :) – Chris6647

0

So che è troppo tardi, e intendo troppo tardi, ma oggi ho incontrato lo stesso problema e ho trovato una soluzione con un numero minimo di righe di codice. Deciso di condividere con la soluzione. Quindi, in pratica, puoi convertire qualsiasi oggetto, anche un elenco di oggetti, in una stringa usando l'API Gson di Google. Check it out:

ComplextObject object=new ComplexObject(); 
Type type = new TypeToken<ComplextObject>() {}.getType(); 
intent.putExtra("key",convertToJsonString(object,type)); //that's it 

O leggere questo oggetto "dall'altra parte":

String jsonString=intent.getStringExtra("key"); 
Type type = new TypeToken<ComplexObject>() {}.getType(); 
ComplexObject object=convertFromJsonString(jsonString,type); 

Ed ecco i convertToJsonString e convertFromJsonString metodi:

public static <T> T convertFromJsonString(String jsonString, Type type){ 
    if(jsonString==null) return null; 
    Gson gson=new Gson(); 
    return gson.fromJson(jsonString,type); 
} 

public static String convertToJsonString(Object object, Type type){ 
    if(object==null) return null; 
    Gson gson=new Gson(); 
    return gson.toJson(object,type); 
}