2012-11-13 31 views
6

Về cơ bản những gì tôi muốn làm, là chuyển một đối tượng có thể đặt hàng tùy chỉnh qua mục đích, đến RemoteViewsService và do đó đến RemoteViewsFactory của tôi. Đối với một số lý do, điều này chỉ đơn giản là không làm việc: S Bất cứ khi nào tôi cố gắng để làm điều này, các widget kết thúc lên hiển thị "vấn đề tải phụ tùng" văn bản thay thế.Chuyển đối tượng có thể đặt gói tùy chỉnh thêm hoặc trong ArrayList sang RemoteViewsService ngắt appwidget

Khi tôi thử điều tương tự, nhưng thay vì chuyển nó đến RemoteViewsService, tôi chỉ chuyển nó đến một Hoạt động thông thường, nó hoạt động chính xác như mong đợi.

Tôi đã cố gắng tìm câu trả lời trực tuyến, nhưng tôi đã không thành công, do đó tôi hiện đăng bài ở đây với hy vọng được trợ giúp.

Tôi đã cố gắng làm điều này để làm việc trong chương trình chính của mình một thời gian. Nhưng tôi chỉ không thể hiểu được. Vì vậy, tôi đã cố gắng để đun sôi nó xuống, để xem nếu bằng cách nào đó tôi đã làm điều gì đó sai tại một số điểm. Tôi đã thành công trong việc tái tạo vấn đề và cơ sở mà tôi tái tạo vấn đề của mình là từ LoronsWidget của CommonsGuy (https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget/LoremWidget) và một ví dụ có thể chuyển nhượng ngẫu nhiên (http://prasanta-paul.blogspot.dk/2010/06/android-parcelable-example.htm l) mà tôi đã sửa đổi để làm việc để hiển thị vấn đề của mình. (Hy vọng tôi sẽ không gặp rắc rối, có sử dụng mã trên hai liên kết này)

Heres mã đầy đủ đăng tải trên filehost ngẫu nhiên trong trường hợp bất cứ ai muốn testrun những gì tôi đang nói về: http://www.filedropper.com/remoteviewserviceparcelerrorexample

Vì vậy, để tổng hợp câu hỏi của tôi:

Tại sao tôi không thể chuyển các đối tượng có thể chuyển nhượng của mình (một mình hoặc được bao bọc trong một ArrayList) đến RemoteViewsService của tôi? (Khi cùng một mã hoạt động tốt với Hoạt động)

Tôi thực sự hy vọng ai đó sẽ có thể giúp tôi. Ngay bây giờ trong chương trình chính của tôi im serializing để lưu trữ nội bộ và sau đó deserializing nó một lần nữa từ RemoteViewsService khá nhiều immedietly sau, mà từ tất cả tôi đã đọc, không thể rất effecient! Chỉ cần nhớ rằng, vì một số lý do trong chương trình chính của tôi, nếu tôi vượt qua một trong các đối tượng tùy chỉnh, với ArrayList và Strings được đặt thành null, và các booleans tất cả là false (về cơ bản chính xác cách đối tượng trông như thế nào?). khi tạo), tiện ích trông bình thường (ví dụ: không có thông báo "Tải vấn đề phụ tùng").

Edit: Sau khi nhìn vào giao diện (không lọc để ứng dụng tôi đã chạy) i bây giờ nhìn thấy một số lỗi (đoán tôi tốt hơn học cách nhìn vào nó tất cả lọc khi tôi nhận được gì 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

Xin vui lòng gửi bất kỳ lỗi nào có liên quan từ logcat. Bạn sẽ thấy một số vấn đề được đăng nhập ở đó. –

+0

Vâng điều là, rằng tôi không thấy bất kỳ lỗi trong logcat, trừ khi tôi cố gắng in thông tin từ bưu kiện im đi qua (trong trường hợp tôi chỉ nhận được một con trỏ null). Bạn vẫn muốn thấy lỗi logcat này? Điều duy nhất cho tôi biết điều gì đó sai, chính là tiện ích hiển thị "Vấn đề tải tiện ích" và thực tế là các thông điệp tường trình được đăng từ RemoteViewsService và nhà máy, không bao giờ được in (nghĩa là chúng không bao giờ được gọi hoặc đạt được vì một số lý do). – Chris6647

+0

Bạn chắc chắn bạn không thấy gì cả trong logcat? Bạn có lọc logcat không? –

Trả lời

1

tôi đã kết thúc làm những gì TreKing nói về ở đây: https://groups.google.com/d/msg/android-developers/KX0BUAbOTKY/jqW_ZokCH3gJ

Những gì tôi đã làm là tạo ra một "Bundleable" giao diện mà về cơ bản không gì Parcelable được thiết kế để làm.Các đối tượng mở rộng giao diện này có thể tự đặt và tự tái tạo từ đối tượng Bundle, trong đó là chính nó Dễ dàng để bạn có thể gửi nó xung quanh giống như đối tượng của mình - ngoại trừ một thực tế nhỏ là hệ thống luôn biết cách tải Loại gói do đó bạn không gặp phải lỗi này.

Và sau mã ví dụ của mình:

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

Làm việc như tôi mong đợi cả Parcel đối phó để làm lại từ đầu! :)

0

Nếu bạn không thể làm điều này để hoạt động bằng cách sử dụng Parcelable, hãy tự làm. Thay vào đó, hãy chuyển số ParcelData làm String. Chỉ cần chuyển đổi writeToParcel()ParcelData(Parcel source) bạn phương pháp để một cái gì đó như thế này ("serialization" kém của con người):

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

Tôi không chạy này thông qua một trình biên dịch, vì vậy nó có thể có những sai lầm ngu ngốc cú pháp. Bạn nên có ý tưởng.

+0

Tôi đã làm những gì tôi đã viết như câu trả lời của mình. Tôi cảm ơn bạn vì đã buộc tôi phải xem nhật ký chưa được lọc. Những manh mối cho sự thành công của tôi, nơi thực sự ngay tại đó :) – Chris6647

+0

Vui vì bạn đã có thể giải quyết nó. Lọc nhật ký thường là một ý tưởng tồi ;-) –

+0

Heh, thông thường nhật ký không được lọc bị spam với nhiều thông tin khác nhau, thật khó để theo dõi những gì quan trọng với tôi. Đó là lý do tại sao tôi thường luôn luôn lọc nó vào ứng dụng im làm việc trên. Tôi chắc chắn sẽ chắc chắn để kiểm tra một trong những chưa lọc nếu tôi chạy trong bất kỳ vấn đề khác mà arent thể hiện trong một lọc! :) – Chris6647

0

Tôi biết đã quá trễ và tôi muốn nói đến muộn, nhưng hôm nay tôi đã gặp phải vấn đề tương tự và đã tìm ra giải pháp có dòng mã tối thiểu. Quyết định chia sẻ với giải pháp. Vì vậy, về cơ bản, bạn có thể chuyển đổi bất kỳ đối tượng nào, thậm chí là danh sách các đối tượng, thành chuỗi bằng cách sử dụng API Gson từ Google. Check it out:

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

Hoặc đọc đối tượng này "ở phía bên kia":

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

Và đây là những convertToJsonStringconvertFromJsonString phương pháp:

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