【发布时间】:2014-12-31 11:49:21
【问题描述】:
我有一个包含几个按钮的小部件。 按下每个按钮时,都会打开我的主应用程序并向其发送不同的对象。 这些对象作为可打包的附加项传递下来。
但是,当 Activity 启动任何尝试访问额外内容的方法(在这种情况下将它们写入日志)时,应用程序会崩溃。
对象已正确实现(我在使用 onSaveInstance 等时对它们进行打包和解包)。
为什么会发生错误以及在将对象发送到应用程序时如何防止它?
这是日志:
12-31 13:27:45.505: I/GABI(9710): WIDGET - createContactIntents()
12-31 13:27:45.505: V/GABI(9710): creating intent number:0
12-31 13:27:45.505: V/GABI(9710): contact:db
12-31 13:27:45.505: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:db number:0506583522 id:4, widgetCallingButton=0, widgetChosenAction=1}]
12-31 13:27:45.505: V/GABI(9710): intent data:Intent { act=0 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.505: V/GABI(9710): creating intent number:1
12-31 13:27:45.510: V/GABI(9710): contact:Developers
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=com.a.example.ContactGroup@4055cfb8, widgetCallingButton=1, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=1 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:2
12-31 13:27:45.510: V/GABI(9710): contact:gabi
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:gabi number:0506583522 id:1, widgetCallingButton=2, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=2 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:3
12-31 13:27:45.510: V/GABI(9710): contact:asaf
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:asaf number:*********id:2, widgetCallingButton=3, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=3 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): widget number:7 id:37
12-31 13:27:45.510: I/GABI(9710): WIDGET - createContactIntents()
12-31 13:27:45.510: V/GABI(9710): creating intent number:0
12-31 13:27:45.510: V/GABI(9710): contact:db
12-31 13:27:45.510: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:db number:**********id:4, widgetCallingButton=0, widgetChosenAction=1}]
12-31 13:27:45.510: V/GABI(9710): intent data:Intent { act=0 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.510: V/GABI(9710): creating intent number:1
12-31 13:27:45.510: V/GABI(9710): contact:Developers
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=com.a.example.ContactGroup@4055cfb8, widgetCallingButton=1, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=1 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.515: V/GABI(9710): creating intent number:2
12-31 13:27:45.515: V/GABI(9710): contact:gabi
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:gabi number:******* id:1, widgetCallingButton=2, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=2 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:45.515: V/GABI(9710): creating intent number:3
12-31 13:27:45.515: V/GABI(9710): contact:asaf
12-31 13:27:45.515: V/GABI(9710): WIDGET- Bundle[{widgetChosenContact=name:asaf number:********id:2, widgetCallingButton=3, widgetChosenAction=1}]
12-31 13:27:45.515: V/GABI(9710): intent data:Intent { act=3 cmp=com.a.example/.MainActivity (has extras) }
12-31 13:27:46.380: W/KeyCharacterMap(9710): No keyboard for id 0
12-31 13:27:46.380: W/KeyCharacterMap(9710): Using default keymap: /system/usr/keychars/qwerty.kcm.bin
12-31 13:27:49.855: V/GABI(9710): widget activation
12-31 13:27:49.855: V/GABI(9710): extras:Bundle[mParcelledData.dataSize=328]
12-31 13:27:49.855: D/AndroidRuntime(9710): Shutting down VM
12-31 13:27:49.855: W/dalvikvm(9710): threadid=1: thread exiting with uncaught exception (group=0x4001e578)
12-31 13:27:49.860: E/AndroidRuntime(9710): FATAL EXCEPTION: main
12-31 13:27:49.860: E/AndroidRuntime(9710): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.a.example/com.a.example.MainActivity}: java.lang.RuntimeException: Parcel android.os.Parcel@4056eb48: Unmarshalling unknown type code 6881399 at offset 224
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1651)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1667)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.access$1500(ActivityThread.java:117)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:935)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Handler.dispatchMessage(Handler.java:99)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Looper.loop(Looper.java:123)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.main(ActivityThread.java:3691)
12-31 13:27:49.860: E/AndroidRuntime(9710): at java.lang.reflect.Method.invokeNative(Native Method)
12-31 13:27:49.860: E/AndroidRuntime(9710): at java.lang.reflect.Method.invoke(Method.java:507)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605)
12-31 13:27:49.860: E/AndroidRuntime(9710): at dalvik.system.NativeStart.main(Native Method)
12-31 13:27:49.860: E/AndroidRuntime(9710): Caused by: java.lang.RuntimeException: Parcel android.os.Parcel@4056eb48: Unmarshalling unknown type code 6881399 at offset 224
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Parcel.readValue(Parcel.java:1913)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Parcel.readMapInternal(Parcel.java:2083)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Bundle.unparcel(Bundle.java:208)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.os.Bundle.getInt(Bundle.java:900)
12-31 13:27:49.860: E/AndroidRuntime(9710): at com.a.example.MainActivity.onCreate(MainActivity.java:61)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
12-31 13:27:49.860: E/AndroidRuntime(9710): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1615)
12-31 13:27:49.860: E/AndroidRuntime(9710): ... 11 more
小部件代码:
// Create Intents to launch activity
PendingIntent[] pendingIntents=createIntents(context,favoriteContacts,4);
// Get the layout for the App Widget
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
// attach an on-click listener to the buttons
views.setOnClickPendingIntent(R.id.w_ContactImageButton1, pendingIntents[0]);
views.setOnClickPendingIntent(R.id.w_ContactImageButton2, pendingIntents[1]);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
这就是创建意图的作用:
Log.v("GABI","creating intent number:"+i);
intent=new Intent(context, MainActivity.class);
intent.setAction(i+"");
intent.putExtra(MainActivity.TAG_WIDGET_CHOSEN_ACTION,MainActivity.ACTION_CHOOSE_CONTACT);
intent.putExtra(MainActivity.TAG_WIDGET_CHOSEN_CONTACT,favoriteContacts.get(i));
Log.v("GABI","contact:"+favoriteContacts.get(i).getDisplayName());
intent.putExtra(MainActivity.TAG_WIDGET_CALLING_BUTTON,i);
Log.v("GABI","WIDGET- "+intent.getExtras().toString());
intents[i] = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_ONE_SHOT);
Log.v("GABI","intent data:"+intent.toString());
主应用的onCreate方法:
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int action=ACTION_NO_ACTION;
//if the appWidget started this activity get chosen object and go srtaight to action chooser
Intent intent=getIntent();
Bundle extras=intent.getExtras();
if (extras!=null)
{
Log.v("GABI", "widget activation");
//Log.v("GABI","extras:"+extras.keySet().toString());
Log.v("GABI","extras:"+extras.toString());//here the error happens before that it happened in the previous line...
action=extras.getInt(TAG_WIDGET_CHOSEN_ACTION);
int callingButton=extras.getInt(TAG_WIDGET_CALLING_BUTTON);
if (action==ACTION_CHOOSE_CONTACT)
{
ContactDisplay contact= extras.getParcelable(TAG_WIDGET_CHOSEN_CONTACT);
getSupportFragmentManager().beginTransaction()
.add(R.id.container, FragmentActionChooser.newInstance(contact),FRAGMENT_TAG_ACTION_CHOOSER)
.commit();
}
}
parcel 类构造函数:
/**
* Constractor for auto use in android while passing as a parcel
* @param in
*/
public Contact(Parcel in)
{
set_id(in.readLong());
set_firstName(in.readString());
set_lastName(in.readString());
set_phoneNumber(in.readString());
set_email(in.readString());
set_creationDate(in.readString());
set_lastUpdate(in.readString());
set_phones(in.readString());
set_idInPhone(in.readInt());
set_priority(in.readInt());
set_isMember(in.readByte() != 0);
set_numOfCalls(in.readInt());
}
写入包裹方法:
@Override
public void writeToParcel(Parcel dest, int flags)
{
dest.writeLong(get_id());
dest.writeString(get_firstName());
dest.writeString(get_lastName());
dest.writeString(get_phoneNumber());
dest.writeString(get_email());
dest.writeString(get_creationDate());
dest.writeString(get_lastUpdate());
dest.writeString(get_phones());
dest.writeLong(get_idInPhone());
dest.writeInt(get_priority());
dest.writeByte((byte) (is_isMember() ? 1 : 0)); //if is_isMember == true, byte == 1
dest.writeInt(get_numOfCalls());
}
创建者类:
public static final Parcelable.Creator<Contact> CREATOR
= new Parcelable.Creator<Contact>() {
public Contact createFromParcel(Parcel in) {
return new Contact(in);
}
public Contact[] newArray(int size) {
return new Contact[size];
}
};
【问题讨论】:
-
也发布该 bean 或核心类。
-
我认为问题出在那个 bean 类上。
-
@NoName 添加了课程并更新了问题
-
你在那个班上写成CREATOR?
-
有一个创建者,就像我说的我在主应用程序中使用 parcelable 没有问题,唯一的问题发生在我使用小部件时。
标签: android android-intent android-appwidget parcelable