Java 在 Activity.onCreate() 中,为什么 Intent.getExtras() 有时会返回 null?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18153730/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 22:50:36  来源:igfitidea点击:

In Activity.onCreate(), why does Intent.getExtras() sometimes return null?

javaandroidandroid-intentandroid-activityandroid-lifecycle

提问by Ten-Young Guh

This was probably a false alarm, see my own answer. Original question below:

这可能是误报,请参阅我自己的回答。原问题如下:

An activity has a button that takes the user to another activity. To launch the new activity, we populate our Intent with extras, and onCreate(), the new activity reads from those extras via Intent.getExtras(). We assumed the returned bundle would be non-null, but as customer crash reports discovered, getExtras() sometimes returns null.

一个活动有一个按钮,可以将用户带到另一个活动。为了启动新活动,我们用额外内容填充我们的 Intent,然后在 onCreate() 中,新活动通过 Intent.getExtras() 从这些额外内容中读取。我们假设返回的包是非空的,但正如客户崩溃报告所发现的那样,getExtras() 有时会返回空值。

Null-guarding the extras, as this answer shows, is perfectly fine, but if you populate the intent's extras, then why would it ever return null later? Is there a better place (like onResume()) to read the extras?

空保护额外内容,正如这个答案所示,完全没问题,但是如果你填充了意图的额外内容,那么为什么以后它会返回 null 呢?有没有更好的地方(比如 onResume())来阅读额外内容?

EDIT: It may be because we are not following the name convention required for the keys:

编辑:这可能是因为我们没有遵循密钥所需的命名约定:

The name must include a package prefix, for example the app com.android.contacts would use names like "com.android.contacts.ShowAll".

该名称必须包含一个包前缀,例如应用程序 com.android.contacts 将使用诸如“com.android.contacts.ShowAll”之类的名称。

This is from the Intent.putExtras javadoc. What happens if you don't follow this name convention; is the behavior even defined?

这是来自Intent.putExtras javadoc。如果您不遵循此命名约定,会发生什么情况;甚至定义了行为吗?

Here's the relevant code:

这是相关的代码:

class FromActivity extends Activity {

    ImageButton button;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.from_view);

        button = (ImageButton)findViewById(R.id.button);
        button.setVisibility(View.VISIBLE);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent i = new Intent(FromActivity.this, ToActivity.class);
                i.putExtra(ToActivity.SERVER_PARAM, ...);
                i.putExtra(ToActivity.UUID_PARAM, ...);
                i.putExtra(ToActivity.TEMPLATE_PARAM, ...);
                startActivityForResult(i, 0); 
                overrideTransition(R.anim.slide_left_in, R.anim.slide_left_out);
            }
        });
    }

}

class ToActivity extends Activity {

    public static final String SERVER_PARAM = "server";
    public static final String UUID_PARAM = "uuid";
    public static final String TEMPLATE_PARAM = "template";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            finish();
            return;
        }

        // do stuff with extras
    }
}

Here is a sample stack trace of this problem:

这是此问题的示例堆栈跟踪:

java.lang.RuntimeException: Unable to start activity ComponentInfo{ToActivity}: java.lang.NullPointerException
    at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2355)
    at  android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
    at  android.app.ActivityThread.access0(ActivityThread.java:151)
    at  android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
    at  android.os.Handler.dispatchMessage(Handler.java:99)
    at  android.os.Looper.loop(Looper.java:155)
    at  android.app.ActivityThread.main(ActivityThread.java:5493)
    at  java.lang.reflect.Method.invokeNative(Native Method)
    at  java.lang.reflect.Method.invoke(Method.java:511)
    at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
    at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
    at  dalvik.system.NativeStart.main(Native Method)
     Caused by: java.lang.NullPointerException
    at  ToActivity.onCreate(SourceFile:49)
    at  android.app.Activity.performCreate(Activity.java:5066)
    at  android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
    at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
     ... 11 more
     java.lang.NullPointerException
    at  ToActivity.onCreate(SourceFile:49)
    at  android.app.Activity.performCreate(Activity.java:5066)
    at  android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1101)
    at  android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2311)
    at  android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2391)
    at  android.app.ActivityThread.access0(ActivityThread.java:151)
    at  android.app.ActivityThread$H.handleMessage(ActivityThread.java:1335)
    at  android.os.Handler.dispatchMessage(Handler.java:99)
    at  android.os.Looper.loop(Looper.java:155)
    at  android.app.ActivityThread.main(ActivityThread.java:5493)
    at  java.lang.reflect.Method.invokeNative(Native Method)
    at  java.lang.reflect.Method.invoke(Method.java:511)
    at  com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1028)
    at  com.android.internal.os.ZygoteInit.main(ZygoteInit.java:795)
    at  dalvik.system.NativeStart.main(Native Method)

采纳答案by Ten-Young Guh

This was probably a false alarm; it's more likely due to our own instance variable being null:

这可能是误报;更有可能是因为我们自己的实例变量为空:

class ToActivity extends Activity {

    public static final String SERVER_PARAM = "server";
    public static final String UUID_PARAM = "uuid";
    public static final String TEMPLATE_PARAM = "template";

    private State state;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        state = initializeState();
        // MISSING NULL CHECK HERE!

        Bundle extras = getIntent().getExtras();
        if (extras == null) {
            finish();
            return;
        }

        // do stuff with state and extras
    }
}

回答by tallen

theoretically, the Intent that starts your activity could come from anywhere, e.g. another program

从理论上讲,启动您的活动的 Intent 可以来自任何地方,例如另一个程序

回答by Martin Cazares

You can get it like this:

你可以这样得到它:

getIntent().getStringExtra(key);

Or:

或者:

getIntent().getExtras().getString(key)

And set it like this in "FromActivity":

并在“FromActivity”中这样设置:

Bundle extras = new Bundle();
extras.putString(key, value);
intent.putExtras(extras);
//And start your activity...

Or:

或者:

intent.putExtra(key, string);
//And start your activity...

Either way should work, Hope this helps...

无论哪种方式都应该有效,希望这会有所帮助......

Regards!

问候!

回答by Spark8006

You got a null pointer error, did you miss some initialization? And can you tell us which line of your code has this error. BTW, if you have many activities to handle, set a flag for your intent is a good idea.

你有一个空指针错误,你是否错过了一些初始化?你能告诉我们你的哪一行代码有这个错误。顺便说一句,如果你有很多活动要处理,为你的意图设置一个标志是个好主意。