18

To był prawdopodobnie fałszywy alarm, patrz my own answer. Oryginalne pytanie poniżej:W Activity.onCreate(), dlaczego funkcja Intent.getExtras() czasami zwraca wartość null?

Aktywność ma przycisk, który przenosi użytkownika do innej aktywności. Aby uruchomić nową aktywność, zapełniamy nasz Intent dodatkami, a onCreate(), nowe działanie czyta z tych dodatków poprzez Intent.getExtras(). Założono, że zwrócony pakiet będzie miał wartość inną niż null, ale jak odkryto raporty o awariach klientów, funkcja getExtras() czasami zwraca wartość null.

Null-strzeżenie dodatków, jako this answer shows, jest całkowicie w porządku, ale jeśli zapełnisz dodatki intencyjne, to dlaczego kiedykolwiek zwrócą one wartość zerową później? Czy istnieje lepsze miejsce (takie jak onResume()), aby przeczytać dodatki?

EDIT: Być może dlatego, że nie są po konwencję nazw wymaganego do kluczy:

Nazwa musi zawierać prefiks pakietów, na przykład com.android.contacts aplikacji będzie używać nazw takich jak " com.android.contacts.ShowAll ".

To jest z Intent.putExtras javadoc. Co się stanie, jeśli nie zastosujesz się do tej konwencji nazw; czy zachowanie jest nawet zdefiniowane?

Oto odpowiedni kod:

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

Oto próbka ślad stosu tego problemu:

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

czy to Twój kompletny kod Brakuje "setContetnView". i post stacktrace. – Raghunandan

+0

Nie, to nie jest kompletny kod, tylko odpowiednie rzeczy. –

+2

Nie dodałeś żadnych "dodatków" z tego, co widzę – codeMagic

Odpowiedz

3

To był prawdopodobnie fałszywy alarm; jest bardziej prawdopodobne, ponieważ nasza własna zmienna instancji jest pusta:

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

Co masz na myśli przez "fałszywy alarm"? Stacktrace kończy się w konstruktorze i tam nie ma tam żadnych odniesień var var. Nie rozumiem, jak to może być zaakceptowana odpowiedź. Czego mi brakuje? ... thx – Rondo

+0

Problem polegał na tym, że * była * zmienna instancji; Ja (niesłusznie) uznałem, że nie ma to znaczenia i pominięto to w moim pierwotnym pytaniu. To moja własna odpowiedź; stąd przyjęta odpowiedź. –

1

teoretycznie, Intent, który rozpoczyna swoją działalność może pochodzić z dowolnego miejsca, np inny program

+2

Jeśli aktywność stanie się nieaktywna, system operacyjny zabije ją dla pamięci, a użytkownik powróci do niej, czy aktywność zostanie zmieniona na inną lub taką samą, która została uruchomiona? –

+0

@ Ten-YoungGuh Ciekawe o tym. – theblang

16

można dostać to tak:

getIntent().getStringExtra(key); 

czyli

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

i ustawić go tak jak to w "FromActivity":

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

czyli

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

Tak czy inaczej powinno działać, mam nadzieję, że to pomoże ...

Pozdrawiam!

+1

Ale dlaczego, na przykład, i.putExtra (TITLE_PARAM, "Title"), a następnie extras.getString (TITLE_PARAM) pracował (prawie) cały czas wtedy? –

+0

Ponieważ bezpośrednio poszukujesz "ekstra" w zamiarze samym, a nie w pakiecie, w ToActivity próbujesz uzyskać obiekt "Pakiet" z intencji, ale nigdy nie ustawiłeś pakietu, poszedłeś bezpośrednio do dodatki ... –

+0

Panie, czy to zadziałało? –

0

Masz błąd wskaźnika pustego, brakowało Ci inicjalizacji? Czy możesz nam powiedzieć, która linia kodu ma ten błąd. BTW, jeśli masz wiele działań do wykonania, ustaw flagę dla swojego zamiaru jest dobrym pomysłem.

Powiązane problemy