18

Возможно, это была ложная тревога, см. my own answer. Оригинальный вопрос ниже:В Activity.onCreate(), почему Intent.getExtras() иногда возвращает null?

Активность имеет кнопку, которая переводит пользователя в другое действие. Чтобы начать новую деятельность, мы заполняем наш Intent дополнительными функциями и onCreate(), новый вид активности читается из этих дополнительных функций через Intent.getExtras(). Мы предположили, что возвращаемый пакет будет не нулевым, но по мере обнаружения отчетов о сбоях клиента getExtras() иногда возвращает null.

Null-guarding extras, как this answer shows, прекрасно, но если вы заполняете дополнительные возможности намерения, то почему бы ему когда-либо вернуть null позже? Есть ли лучшее место (например, onResume()) для чтения дополнительных предметов?

EDIT: Это может быть потому, что мы не следует название конвенции, необходимая для ключей:

Имя должно содержать префикс пакетов, например com.android.contacts приложения будет использовать имена, как " com.android.contacts.ShowAll».

Это Intent.putExtras javadoc. Что произойдет, если вы не согласны с этим соглашением о названии; поведение даже определено?

Вот соответствующий код:

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 
    } 
} 

Вот стопка образца след от этой проблемы:

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.access$600(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.access$600(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) 
+0

это ваш полный код. Вам не хватает 'setContetnView'. и post stacktrace. – Raghunandan

+0

Нет, это не полный код, просто соответствующий материал. –

+2

Вы не добавили 'extras' из того, что я вижу – codeMagic

ответ

3

Возможно, это была ложная тревога; это скорее связано с тем, что наша собственная переменная экземпляра равна нулю:

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 
    } 
} 
+1

Что значит «ложная тревога»? Стоп-тракт завершается в конструкторе, и там нет экземпляров var-ссылок. Я не понимаю, как это может быть принятым ответом. Что мне не хватает? ... thx – Rondo

+0

Проблема была там * была * переменной экземпляра; Я (ошибочно) думал, что это не имеет значения, и оставил это в моем первоначальном вопросе. Это мой собственный ответ; следовательно, принятый ответ. –

1

теоретически, Намерение, начинающимся вашей деятельности может прийти откуда угодно, например, другая программа

+2

Если активность неактивна, ОС убивает ее для памяти, и пользователь возвращается к ней, будет ли действие получать другое намерение или то же, что и началось? –

+0

@ Ten-YoungGuh Любопытно об этом. – theblang

16

Вы можете получить его, как это:

getIntent().getStringExtra(key); 

Или:

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

И установить его, как это в "FromActivity":

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

Или:

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

В любом случае это должно работать, надеюсь, это поможет ...

С уважением!

+1

Но почему бы, например, i.putExtra (TITLE_PARAM, «Title»), тогда extras.getString (TITLE_PARAM) работает (почти) все время? –

+0

Поскольку вы непосредственно ищете «лишнее» в своем намерении, а не в комплекте, в ToActivity вы пытаетесь получить объект «Bundle» из намерения, но вы никогда не устанавливали пакет, вы пошли прямо дополнительные ... –

+0

сэр, это сработало? –

0

У вас ошибка null-указателя, вы пропустили какую-то инициализацию? И можете ли вы сказать нам, какая строка вашего кода имеет эту ошибку. BTW, если у вас есть много действий для обработки, установите флаг для своих намерений - хорошая идея.

Смежные вопросы