2012-11-13 25 views
6

基本上我想做的是通過意圖傳遞一個自定義parcelable對象到RemoteViewsService,從而我的RemoteViewsFactory。出於某種原因,這不起作用:S每當我嘗試這樣做時,小部件最終會顯示「問題加載小部件」文本。傳遞自定義parcelable對象額外或ArrayList到RemoteViewsService打破appwidget

當我嘗試同樣的事情,而不是將它傳遞給RemoteViewsService,我只是將它傳遞給一個常規的活動,它完全按預期工作。

我試圖在網上找到我的答案,但我一直未成功,因此我現在在這裏發帖希望能夠得到幫助。

我一直試圖讓這個在我的主程序中工作一段時間。但我無法弄清楚。所以我試圖把它煮沸,看看我是否在某個時候做了錯誤的事情。我成功地重現了這個問題,並且我重新創建了我的問題的基礎是來自CommonsGuy的LoremWidget(https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget/LoremWidget)和一個隨機可供參考的示例(http://prasanta-paul.blogspot.dk/2010/06/android-parcelable-example.htm l),我已修改該示例以顯示我的問題。 (希望我不會惹上麻煩,已經用在這兩個環節上的代碼)

繼承人的情況下,任何人上傳隨機文件主機完整的代碼要testrun什麼我談論: http://www.filedropper.com/remoteviewserviceparcelerrorexample

所以要總結我的問題:

爲什麼我無法將我的parcelable對象(單獨或包裝在ArrayList中)傳遞給我的RemoteViewsService? (當相同的代碼適用於一個活動很好)

我真的希望有人能夠幫助我。現在在我的主程序中,我序列化到內部存儲器,然後幾乎立即從RemoteViewsService中反序列化它,從我讀過的所有內容來看,都不是非常有效!

編輯: 只記得,由於某種原因,在我的主要程序,如果我通過自定義對象之一,與ArrayList和設置爲空字符串,和布爾值都爲假(基本上究竟如何對象外觀在創建時),小部件看起來正常(即沒有「問題加載小部件」消息)。

編輯: 說完看了一下(不過濾,我運行應用程序)我現在看到的一些錯誤(猜我更好地學習一下吧所有未經過濾的,當我得到什麼f​​ilered :))後:

 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

請發表任何相關的錯誤logcat。你應該看到一些記錄在那裏的問題。 –

+0

那麼事情是,我沒有看到logcat中的任何錯誤,除非我嘗試從包裹im傳遞打印信息(在這種情況下,我只是得到一個空指針)。你還想看看這個logcat錯誤嗎?唯一告訴我一些問題是錯誤的是,小部件本身顯示「問題加載小部件」,以及從RemoteViewsService和工廠發佈的日誌消息從不打印(即從未被調用或由於某種原因達不到)的事實。 – Chris6647

+0

你確定你在logcat中什麼都看不到?你是否過濾了logcat? –

回答

1

最後我做什麼跋涉中談到這裏: https://groups.google.com/d/msg/android-developers/KX0BUAbOTKY/jqW_ZokCH3gJ

我所做的是創建一個「Bundleable」界面,基本上沒有什麼 是Parcelable打算做。擴展這個接口的對象可以把它們自己並從一個Bundle對象中重新創建,它本身就是Parcelable,所以你可以像你的對象一樣發送它 - 除了小系統總是知道如何加載一個 Bundle類型所以你不會遇到這個錯誤。

而繼他的代碼示例:

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

工作就像我預料整個包裹處理從一開始就做! :)

0

如果您無法使用Parcelable獲得此功能,請自行完成。改爲將ParcelData改爲String。只要你writeToParcel()ParcelData(Parcel source)方法轉換爲這樣的事情(-窮人的「系列化」):

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

我沒有通過編譯器運行它,所以它可能有愚蠢的語法錯誤。你應該明白這個主意。

+0

我最終做了我寫的答案。我感謝你迫使我看看未經過濾的原木。我的成功線索確實在那裏:) – Chris6647

+0

很高興你能解決它。過濾日誌通常是一個糟糕的主意;-) –

+0

呵呵,通常情況下,未過濾的日誌是垃圾郵件與非常不同的信息,它很難實際跟蹤我的重要。這就是爲什麼我通常總是將它過濾到即時消息工作的應用程序。我將定義一定要檢查出未經過濾的一個,如果我運行的任何其他問題,沒有顯示在過濾的一個! :) – Chris6647

0

我知道這太晚了,我的意思是太晚了,但今天我遇到了同樣的問題,並找到了一個最小代碼行的解決方案。決定與解決方案分享。 因此,基本上,您可以使用Google的Gson API將任何對象(甚至是對象列表)轉換爲字符串。檢查出來:

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

或者閱讀對象 「的另一面」:

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

這裏是convertToJsonStringconvertFromJsonString方法:

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); 
} 
相關問題