2014-05-23 10 views
23

Wiem, że istnieje wiele różnych przyczyn NPE ale mój jest nieco dziwne (przynajmniej dla mnie).NullPointerException na getActivity(). RunOnUiThread (nowa Runnable() {

Więc ja konwertowane mój Activities do Fragments pomyślnie , ale mój problem wydaje się pochodzić z funkcji, która wyświetla datę.Jeżeli aplikacja jest uruchomiona, wszystko działa dobrze.Ale jak tylko wciśniesz przycisk Wstecz Aplikacja działa, a następnie w dzienniku mówi " Otrzymałem NullPointerException w linii 102. Więc patrząc na kod, zrobiłem badania na ten temat, ale niestety nic nie dostałem

To jest linia, w której błąd i s pochodzący z naciśnięcia przycisku Wstecz.

getActivity().runOnUiThread(new Runnable(){ 

Próbowałem również wyłączenie przycisku Wstecz (ponieważ buduję program uruchamiający i nie jest potrzebny). Ale wydaje się, że nie działa.

Oto kod dla całej daty wyświetlającej metodę/funkcję.

// (Calendar) Date function - Displays dateview on Card 
final boolean keepRunning1 = true; 
Thread thread_two = new Thread(){ 
    @Override 
    public void run(){ 

     while(keepRunning1){ 

      // Make the thread wait half a second. If you want... 
      try { 
       Thread.sleep(500); 
      } catch (InterruptedException e) { 
       Toast.makeText(getActivity().getApplicationContext(), "Default Signature Fail", Toast.LENGTH_LONG).show(); 
       e.printStackTrace(); 
      } 

       getActivity().runOnUiThread(new Runnable(){ 
       @Override 
       public void run(){ 
        TextView date = (TextView) getView().findViewById(R.id.date); 
        date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)); 
       } 
      }); 
     } 
    } 
}; 

thread_two.start(); 

Dziękuję za poświęcony czas, miejmy nadzieję, że możesz rzucić trochę światła na to, co robię źle.

Logcat -

05-23 21:17:33.216: E/AndroidRuntime(6906): java.lang.NullPointerException: Attempt to invoke virtual method 'void android.support.v4.app.FragmentActivity.runOnUiThread(java.lang.Runnable)' on a null object reference 
05-23 21:17:33.216: E/AndroidRuntime(6906):  at com.activelauncher.fragments.UtilsFragment$2.run(UtilsFragment.java:102) 
+2

Możliwe, że "Czynność" jest zamykana po kliknięciu przycisku Wstecz, a zatem otrzymujesz 'getActivity()' jako wartość null – Apoorv

+0

@Apoorv, w jaki sposób mogę powstrzymać działanie przed kliknięciem przycisku zamknięcia? – Robin

Odpowiedz

45

Jestem prawie pewien, że jest to spowodowane, gdy wątek zakończy swoją pracę, ale aktywność nie jest już widoczny.

Należy sprawdzić, czy w zamian getActivity() połączeń zerowej i ...

Aby zastosować korekty na kodzie, spójrz na to:

// (Calendar) Date function - Displays dateview on Card 
final boolean keepRunning1 = true; 
Thread thread_two = new Thread(){ 

@Override 
public void run(){ 

    while(keepRunning1){ 

     // Make the thread wait half a second. If you want... 
     try { 
      Thread.sleep(500); 
     } catch (InterruptedException e) { 
      Toast.makeText(getActivity().getApplicationContext(), "Default Signature       Fail", Toast.LENGTH_LONG).show(); 
      e.printStackTrace(); 
     } 

     // here you check the value of getActivity() and break up if needed 
     if(getActivity() == null) 
      return; 

     getActivity().runOnUiThread(new Runnable(){ 
     @Override 
     public void run(){ 
      TextView date = (TextView) getView().findViewById(R.id.date); 
      date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)); 
      } 
     }); 
    } 
} 
};thread_two.start(); 
+0

@FaroukTouzi Chcę wykonać kod wewnątrz 'runOnUiThread' tak czy inaczej. Jeśli to zrobię, kod w nim nie zostanie w pełni zrealizowany? – Jas

+1

Tak jak powiedziałem powyżej, jeśli główne działanie nie jest już widoczne, kod wewnątrz runOnUiThread nie zostanie wykonany. Dlatego zawsze należy sprawdzić widoczność głównej aktywności, aby uniknąć awarii aplikacji. –

4

Spróbuj ten

TextView date = (TextView) getView().findViewById(R.id.date); 

jest data jest null lub nie sprawdzić

if(date !=null){ 
        date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)); 
} 
10

Po naciśnięciu powrotem, Twój wątek tła jest jeszcze uruchomiony. Do czasu, gdy wątek osiągnie kod getActivityrunOnUiThread(), działanie już nie istnieje. Sprawdź, czy aktywność nadal istnieje likeso:

if (getActivity()!=null) { 
     getActivity().runOnUiThread(new Runnable(){ 
       @Override 
       public void run(){ 
        TextView date = (TextView) getView().findViewById(R.id.date); 
        date.setText(DateUtils.formatDateTime(getActivity().getBaseContext(), System.currentTimeMillis(),DateUtils.FORMAT_SHOW_WEEKDAY | DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_YEAR)); 
      } 
     }); 
} 
8

Powodem jest to, że NPE wątek nie jest związany z cyklem życia fragmentu. Gdy fragment zostanie odłączony od działania hostingu, zwraca wartość null.

Jako rozwiązanie rozważ całkowite usunięcie wątku i po prostu użyj postDelayed() na Handler w wątku UI, aby opublikować Runnable s, które wykonają aktualizacje, które chcesz po opóźnieniu.

+0

Wewnątrz PostDelayed metody Handler dostał getActivity() jako null :( – developer1011

8

Put

if(getActivity() == null) 
     return; 

przed getActivity().runOnUiThread(new Runnable(){ tamtędy po naciśnięciu przycisku wstecz jest zamknięty a Thread nadal działa to sprawdzić, czy wywołanie Activity nadal istnieje.

Jeśli nie, będzie to return.

+0

Ale co z operacją, która miała mieć miejsce? Zwróć 'jeśli' getActivity() 'ma wartość null, ale wtedy coś musi ponownie wywołać metodę, więc może zakończyć się, gdy 'getActivity()' nie ma wartości NULL ... –