android.content.Context.getPackageName () 'на посилання на нульовий об’єкт


81

Я працюю з Fragments, який реалізує інтерфейс.

public class SigninFragment extends Fragment implements SigninInterface 

Реалізація методу інтерфейсу в класі фрагментів полягає в наступному.

@Override
public void afterSubmitClicked(String userId, Bundle bundle) {

    Log.d(TAG,"Calling time afterSubmitClicked called"+bundle);
    
    if(!userId.equals("-1")){
        //Logged in successfully
        //Move to MusicHome
        
        Intent mIntent = new Intent(getActivity(),MusicHome.class);
        mIntent.putExtra("SigninFragment.user_details", bundle);
        startActivity(mIntent);
        
    }else{
        //Logging in failed
        //show error dialog
    }
    
}

Цей метод викликається після виконання класу AsynchronousTask (що розширює AsyncTask).

Але я отримую крах. І з'являється повідомлення про помилку

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference

Logcat

   02-14 16:37:04.648: E/AndroidRuntime(28177): Process: com.raaga.android, PID: 28177
02-14 16:37:04.648: E/AndroidRuntime(28177): java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.content.ComponentName.<init>(ComponentName.java:77)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.content.Intent.<init>(Intent.java:3996)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.fragments.SigninFragment.afterSubmitClicked(SigninFragment.java:152)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.asynctask.SignInAsyncTask.onPostExecute(SignInAsyncTask.java:92)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.raaga.asynctask.SignInAsyncTask.onPostExecute(SignInAsyncTask.java:1)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask.finish(AsyncTask.java:632)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask.access$600(AsyncTask.java:177)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.Handler.dispatchMessage(Handler.java:102)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.os.Looper.loop(Looper.java:135)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at android.app.ActivityThread.main(ActivityThread.java:5221)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at java.lang.reflect.Method.invoke(Native Method)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at java.lang.reflect.Method.invoke(Method.java:372)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
02-14 16:37:04.648: E/AndroidRuntime(28177):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

Відповіді:


44

Я знайшов помилку в тому, що зробив. Нам потрібно отримати екземпляр активності з методу override OnAttach () Наприклад,

public MainActivity activity;

@Override
public void onAttach(Activity activity){
    this.activity = activity;
}

Потім передайте діяльність як контекст, як показано нижче.

Intent mIntent = new Intent(activity, MusicHome.class);

2
Мені здається помилкою для android, але приємна робота навколо мене вирішила проблему!
реактивний сердечник

5
onAttach припинено
Менна-Аллах Самі

6
@ Менна-АллахСамі onAttach(Context context)- ні.
старшийгод

3
@ Menna-AllahSami Той, хто приймає Activity як параметр, так. Той, хто бере контекст, ні.
старшийбог

2
Я не знаю, як це вирішує проблему, але це працює.
Рошана Пітігала,

40

Відповіді на це запитання допомогли мені знайти свою проблему, але моє джерело було іншим, тому, сподіваюся, це може пролити світло на когось, хто знайшов цю сторінку, шукаючи відповіді на випадковий збій контексту:

Я вказав об'єкт SharedPreferences і спробував створити його в оголошенні на рівні класу, наприклад:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref =
        PreferenceManager.getDefaultSharedPreferences(this);

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

Посилання thisдо onCreate призвели до помилки "java.lang.NullPointerException: Спроба викликати віртуальний метод 'java.lang.String android.content.Context.getPackageName ()' на посилання на нульовий об'єкт" для мене.

Екземпляр об'єкта всередині onCreate () вирішив мою проблему приблизно так:

public class MyFragment extends FragmentActivity {
    private SharedPreferences sharedPref;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
        sharedPref = PreferenceManager.getDefaultSharedPreferences(this);

Сподіваюся, що це допомагає.


1
У мене була та ж проблема під час виклику getDefaultSharedPreferences () з конструктора класу Application (відкритий клас MyApplication розширює Application). Ваше повідомлення допомогло зрозуміти, що я повинен перемістити його до методу onCreate.
OlivierGrenoble

1
Приємна порада, мені дуже допомогло
Allexandre S.

23

android API рівень 23.

Використовуйте

getContext ()

замість

getActivity ()

getActivity () дає батьківський Activity, Context об'єкт

Тут Ви можете використовувати

MyActivity. Це

замість

getActivity () / getApplicationContext ()


3
Я отримую той самий NPE за допомогою getContext ()
Рікардо

деякі телефони отримують NPE з MyActivity.this (один плюс і lenovo, наприклад)
Dagnogo Jean-François

@ DagnogoJean-François, як це вирішити для цих телефонів?
Сагар Пуджарі,

Може працювати на інших, але не на мене. Я використовував Fragment.
VikaS GuttE

8

У мене була та ж проблема, коли я намагався показати тост фрагментом.

Після деякої налагодження я дізнався, що видаляю фрагмент перед викликом:

Toast.makeText(getContext(), "text", Toast.LENGTH_SHORT).show();

Оскільки фрагмент було видалено , контекст став нульовим, що спричинило виняток.

Просте рішення: зателефонуйте getContext() перед тим, як видалити фрагмент.


7

У моєму випадку помилка сталася всередині a Fragmentна цьому рядку:

Intent intent = new Intent(getActivity(), SecondaryActivity.class);

Це трапилося, коли я двічі клацнув на елементі, який спричинив код вище, тому SecondaryActivity.classодночасно було запущено дві дії, одну поверх іншої. Я закрив верхню SecondaryActivity.classактивність, натиснувши кнопку "Назад", яка викликала дзвінок, який вийшов на getActivity()перший SecondaryActivity.classплан. Заклик до getActivity()повернувся null. Це якась дивна помилка Android, тому зазвичай вона не повинна траплятися. Ви можете заблокувати кліки після того, як користувач клацнув один раз.



4

Для мене проблема полягала в тому, що я передавав Activity конструктору, а не Context

public Adapter(Activity activity, List<MediaItem> items, boolean can) {
    mItems = items;
    canEdit = can;
    mActivity = activity;
}

і використовуючи цю активність для getDefaultSharedPreferences (), тому я змінив Activity на Context і все ще викликав конструктор Adapter з MainActivity.this


4

У моєму випадку у мене був метод onCLick в адаптері reciclerview, контекст контексту; на початку.

 holder.cTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(context, StoryActivity.class);
                    intent.putExtra("STORY", mComments.get(position));
                    context.startActivity(intent);
                }
            });

І я змінився, щоб отримати контекст із поточного подання

 holder.cTextView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(v.getContext(), StoryActivity.class);
                    intent.putExtra("STORY", mComments.get(position));
                    v.getContext().startActivity(intent);
                }
            });

1

Мій клас не поширюється на Activiti. Я вирішив проблему таким чином.

class MyOnBindViewHolder : LogicViewAdapterModel.LogicAdapter {
          ...
 holder.title.setOnClickListener({v->
                v.context.startActivity(Intent(context,  HomeActivity::class.java))
            })
          ...
    }

1

Поставте ім'я фрагмента перед активністю

Intent mIntent = new Intent(SigninFragment.this.getActivity(),MusicHome.class);

0

Ви вирішуєте проблему за допомогою try / catch. Цей збій трапляється, коли користувач закриває програму до початку наміру.

try
{
    Intent mIntent = new Intent(getActivity(),MusicHome.class);
    mIntent.putExtra("SigninFragment.user_details", bundle);
    startActivity(mIntent);
}
catch (Exception e) {
    e.printStackTrace();
}

Чудова відповідь. Це саме те, що відбувалося зі мною. У мене був відлік часу, який створював намір у onFinishметоді. Але якби користувач натиснув кнопку "Назад", щоб перейти до попередньої активності, де таймер не був створений, я отримав би посилання на нульовий об'єкт, оскільки getActivity () більше не працював. Це також може бути корисно для потоків, які не були закриті після того, як користувач залишив діяльність. Спасибі купу!
Кріс Гонг

0

Ви можете легко вирішити свою проблему і використовувати свою діяльність в будь-якому місці, просто зберігайте активність, як це:

public class MainActivity extends AppCompatActivity{
      Context context = this;

      protected void onCreate(Bundle savedInstanceState) {....}

      AnotherClass {
          Intent intent = new Intent(context, ExampleActivity.class);
          intent.putExtra("key", "value");
          startActivity(intent);
      }

}

0

Через onAttach, що застаріло в API23 та новіших версіях ... У своєму фрагменті я декларую та встановлюю parentActivityперед врученням кожного разу, коли заходжу у фрагмент. Швидше за все, це сталося через те, що коли ми натискали кнопку назад, контекст ставав нульовим. Тому нижче - моє рішення.

private Activity parentActivity;

public void onStart(){
        super.onStart();
        parentActivity = getActivity();
//...

}


0

Використання може використовувати в глобальному

Context context;

і створити конструктор і передаючи контекст. LoginClass - це назва класу

LoginClass(Context context)
{this.context=context;}

а також, коли ми викликаємо клас, тоді використовуємо getApplicationContext як LoginClass lclass = new LoginClass(getApplicationContext) це.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.