【问题标题】:NullPointerException : Get Parcelable data from intentNullPointerException : 从意图获取 Parcelable 数据
【发布时间】:2014-09-15 17:43:08
【问题描述】:

我有一个处理通知的服务。当我点击通知时,我正在向 Activity (NotificationActivity) 发送 Parcelable 对象:

服务:

Intent destIntent = new Intent (this, NotificationActivity.class);
destIntent.putExtra ("notificationData", new ParcelableObject (mes));

PendingIntent contentIntent = PendingIntent.getActivity (this, 0, destIntent, 0);

NotificationActivity.java

public class NotificationActivity extends Activity {

    @Override
    protected void onCreate (Bundle savedInstanceState) {
        super.onCreate (savedInstanceState);
        setContentView (R.layout.activity_notification);

        // Always NullPointerException
        ParcelableObject model = (ParcelableObject) (savedInstanceState.getParcelable ("notificationData"));

        TextView content = (TextView)findViewById(R.id.content);
        if (model == null) {
            content.setText ("NULL"); 
        } else {
            content.setText (String.valueOf (model.dump ()));
        }
    }
}

但我在检索对象时一直出现 NullPointerException..

编辑: 遵循提供的答案后,我编辑了活动的代码,例如:

@Override
protected void onCreate (Bundle savedInstanceState) {
    super.onCreate (savedInstanceState);
    setContentView (R.layout.activity_notification);
}

@Override
protected void onNewIntent (Intent intent) {
    super.onNewIntent (intent);

    setIntent (intent);

    // Code not executed here
    // Needed to move it to onResume () 
    // since according to the doc it comes after onNewIntent ()
}

@Override
protected void onResume () {
    super.onResume ();

    ParcelableObject model = (ParcelableObject) (getIntent ().getParcelableExtra ("notificationData"));

    Log.v ("MODEL :: ", model.dump().toString()); // NullPointerException

    TextView content = (TextView)findViewById(R.id.content);
    if (model == null) {
        content.setText ("NULL"); 
    } else {
        content.setText (String.valueOf (model.dump ()));
    }
}

有什么建议吗?谢谢。

【问题讨论】:

    标签: android nullpointerexception parcelable


    【解决方案1】:

    除了 tyczj 所说的,你应该尝试这样的方法来检查它是否为空:

    public class NotificationActivity extends Activity {
    
        @Override
        protected void onCreate (Bundle savedInstanceState) {
            super.onCreate (savedInstanceState);
            setContentView (R.layout.activity_notification);
    
            // Get from Intent if savedInstanceState is null, otherwise use saved state
            ParcelableObject model = (ParcelableObject) (savedInstanceState == null ? getIntent().getParcelableExtra("notificationData") : savedInstanceState.getParcelable("notificationData"));
    
            TextView content = (TextView)findViewById(R.id.content);
            if (model == null) content.setText ("NULL"); 
            else content.setText (String.valueOf (model.dump()));
        }
    }
    

    正如他上面提到的,您的onSaveInstance/onRestoreInstance 并不总是被调用,因此依赖这些方法并不是一个好主意。相反,您可能需要考虑将数据保存在 onPause() 中,并在 Activity 恢复时恢复它。

    另外,如果Activity 已经存在并且您只是用新的Intent 打开它,您需要确保在活动中覆盖onNewInent(Intent) 以强制它使用新的Intent's 数据,否则您的新数据将无法访问。为此,只需将其添加到您的 onCreate() 方法下方即可:

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
    }
    

    这将确保Activity 将使用最新的Intent's 数据。

    【讨论】:

    • 谢谢 :) 请检查我的编辑,我按照你说的做,仍然得到 NullPointerException..
    • 你可以尝试添加 destIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);在为 Activity 创建 Intent 时,确保它传递新值?
    • 你是对的!! :D 已经投票了,但我肯定会接受你的回答 :) 你介意解释一下为什么这解决了这个问题吗?还有为什么onNewIntent () 上的代码除了setIntent ()onResume () 之外的所有代码都在执行?谢谢。
    • 当然,谢谢~至于解释:添加 FLAG_ACTIVITY_NEW_TASK 告诉系统将被调用的 Activity 设置为新任务的开始,然后实际上在被调用的 Activity 中覆盖 onNewIntent() 允许您设置Activity 的当前 Intent 是最近调用 Intent 的 Intent。 onNewIntent() 只会在 Activity 已经存在于堆栈中但使用 FLAG_ACTIVITY_NEW_TASK 被带回前面时调用。您的问题是它已经存在,但没有被明确告知使用您最新的 Intent 数据
    • 谢谢你解释得很好! :)
    【解决方案2】:

    保存的实例状态仅在设备旋转或仅当您的活动暂时暂停然后重新创建的那些行时使用,以便在您启动活动时使用不会做任何事情。

    你需要使用getIntent()来获取对象

    【讨论】:

    • 感谢您的回答。你介意检查我编辑的问题吗?我使用了getIntent (),但仍有NullPointerException
    • @Mehdi 请指出异常发生的位置
    • Log.v ("MODEL :: ", model.dump().toString()); 在 OnResume 中
    • 好的,所以modelmodel.dump 为空,找出哪个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-15
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多