在活动启动时从小部件崩溃中发送带有可分配额外内容的意图

时间:2014-12-31 11:49:22

标签: android android-intent android-appwidget parcelable

我有一个包含几个按钮的小部件。 当按下每个按钮打开我的主应用程序并发送一个不同的对象。 对象作为可分配的额外内容传递下来。

然而,当活动启动时,任何尝试访问附加内容的方法(在这种情况下将其写入日志)都会使应用程序崩溃。

正确实现了对象(当使用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];
    }
};

1 个答案:

答案 0 :(得分:1)

对于构造函数中的id中的idInPhone,你正在以int

的形式阅读它
set_idInPhone(in.readInt());

但是在writeToParcel()方法中你可以编写它

dest.writeLong(get_idInPhone());

根据您的变量声明将任何一个更改为long或int ...