2012-11-13 29 views
6

Zasadniczo chcę, aby przekazać niestandardowy obiekt działkowy z zamiarem do usługi RemoteViewsService, a tym samym do mojego RemoteViewsFactory. Z jakiegoś powodu po prostu to nie działa: S Ilekroć próbuję to zrobić, widget kończy się wyświetlając zamiast niego tekst "Problem ładowania widgetu".Przekazywanie niestandardowego obiektu paczkowanego w postaci dodatkowej lub w tablicy ArrayList do aplikacji RemoteViewsService powoduje przerwanie aplikacji

Kiedy próbuję tego samego, ale zamiast przekazania go do RemoteViewsService, po prostu przekazuję je do zwykłej aktywności, działa dokładnie zgodnie z oczekiwaniami.

Próbowałem znaleźć moją odpowiedź w Internecie, ale nie udało mi się, dlatego teraz zamieszczam tutaj, licząc na pomoc.

Próbowałem uruchomić to w moim głównym programie przez jakiś czas. Ale po prostu nie mogłem tego rozgryźć. Więc próbowałem go zagotować, żeby zobaczyć, czy w jakiś sposób coś złego zrobiłem. Udało mi się odtworzyć problem, a podstawą, na której odtworzyłem swój problem, jest plik LoremWidget CommonsGuy (https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget/LoremWidget) i przykład losowego paczki (http://prasanta-paul.blogspot.dk/2010/06/android-parcelable-example.htm l), który zmodyfikowałem tak, aby pokazać mój problem. (Mam nadzieję, że przyzwyczajenie się w kłopoty, które korzystały z kodu na tych dwóch linków)

Herezje pełny kod przesłany na losowy serwer plików w przypadku gdy ktoś chce TestRun co mówię: http://www.filedropper.com/remoteviewserviceparcelerrorexample

tak Podsumuj moje pytanie:

Dlaczego nie mogę przekazać moich obiektów do pakowania (pojedynczych lub zapakowanych w ArrayList) do mojej RemoteViewsService? (Kiedy ten sam kod działa dobrze z Aktywnością)

Naprawdę mam nadzieję, że ktoś będzie mógł mi pomóc. W tej chwili w moim głównym programie serializuję do pamięci wewnętrznej, a następnie deserializuję ją ponownie z RemoteViewsService po operacji, co z tego co przeczytałem, nie może być bardzo skuteczne!

Edytować: Po prostu pamiętać, że z jakiegoś powodu w moim głównym programie, jeśli przekazać jeden z niestandardowych obiektów, z ArrayList i ciągi ustawione na null, a booleans wszystko na false (w zasadzie dokładnie, jak obiekt wygląda po utworzeniu) widżet wygląda normalnie (tzn. nie ma komunikatu "Problem loading widget").

Edit: Po spojrzał na wygląd (nie przefiltrowanej do aplikacji biegałam) Teraz widzę pewne błędy (Chyba lepiej nauczyć się patrzeć na to wszystko niefiltrowane, kiedy się nic 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

proszę umieszczać żadnych istotnych błędów z logcat. Powinieneś zobaczyć tam niektóre problemy. –

+0

Chodzi o to, że nie widzę żadnych błędów w kodzie logującym, chyba że spróbuję wydrukować informacje z paczki im przechodzącej (w takim przypadku po prostu dostaję zerowy wskaźnik). Czy nadal chcesz zobaczyć ten błąd logcat? Jedyne, co mówi mi, że coś jest nie tak, to sam widżet wyświetlający "Problem podczas ładowania widżetu" oraz fakt, że komunikaty dziennika publikowane z RemoteViewsService i fabryki, nigdy nie są drukowane (tj. Nigdy nie są wywoływane lub osiągane z jakiegoś powodu). – Chris6647

+0

Jesteś pewien, że w logcatie nic nie widzisz? Czy w ogóle filtrujesz logcat? –

Odpowiedz

1

skończyło się na tym, co mówi o treking tu: https://groups.google.com/d/msg/android-developers/KX0BUAbOTKY/jqW_ZokCH3gJ

Co robiłem jest utworzyć interfejs „Bundleable”, która w zasadzie robi co Parcelable przeznaczony jest do zrobienia.Przedmioty rozciągające ten interfejs można położyć się i ponownie się z obiektu Bundle, która sama jest Parcelable więc można wysłać go wokół tak samo, jak obiekt - z wyjątkiem mniejszej faktu, że system zawsze wie, jak załadować typ Bundle więc nie napotkasz tego błędu.

A po jego przykład kodu:

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); 

działało jak się spodziewałem i całość działki czynienia zrobić od początku! :)

0

Jeśli nie możesz tego uruchomić, używając Parcelable, zrób to sam. Przekaż zamiast tego ParcelData jako String. Tylko konwertować writeToParcel() i ParcelData(Parcel source) metod, aby coś takiego („serializacji” niskiej mężczyzny):

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]; 
     } 
    } 
} 

nie uruchomić to przez kompilator, więc może mieć głupie błędy składniowe. Powinieneś dostać pomysł.

+0

Skończyłem, robiąc to, co napisałem jako moją odpowiedź. Dziękuję, że zmusiłeś mnie do spojrzenia na niefiltrowane dzienniki. Wskazówki do mojego sukcesu, gdzie tak naprawdę :) – Chris6647

+0

Cieszę się, że udało się to rozwiązać. Filtrowanie dzienników jest zazwyczaj złym pomysłem ;-) –

+0

Heh, zwykle nieodfiltrowany log jest spamowany z tak wieloma różnymi informacjami, że trudno jest mu właściwie śledzić, co jest dla mnie ważne. Dlatego zazwyczaj zawsze filtruje je do aplikacji, nad którą pracuję. Na pewno nie zapomnę sprawdzić niefiltrowanego, jeśli wystąpią jakiekolwiek inne problemy, które nie są widoczne w przefiltrowanym! :) – Chris6647

0

Wiem, że jest już za późno, a mam na myśli późno, ale dzisiaj wpadłem na ten sam problem i znalazłem rozwiązanie z minimalnymi liniami kodu. Postanowili podzielić się z rozwiązaniem. Tak więc, zasadniczo można przekonwertować dowolny obiekt, nawet listę obiektów, na ciąg znaków za pomocą interfejsu API Gson firmy Google. Sprawdź:

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

Albo przeczytać ten obiekt "po drugiej stronie":

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

A oto convertToJsonString i convertFromJsonString metody:

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); 
}