【问题标题】:sending intent with a parcelable extra from widget crashes on activity startup在活动启动时从小部件崩溃中发送带有可打包额外内容的意图
【发布时间】: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


【解决方案1】:

对于构造函数中电话中的 idInPhone,您将其读取为 int

set_idInPhone(in.readInt());

但是在 writeToParcel() 方法中,你写的很长

dest.writeLong(get_idInPhone());

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

【讨论】:

  • 谢谢你说得对,我的错,但是为什么这该死的非生产性错误消息花了我 2 天时间
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多