【问题标题】:android.content.Context.getPackageName()' on a null object referenceandroid.content.Context.getPackageName()' 在空对象引用上
【发布时间】:2015-04-15 09:45:58
【问题描述】:

我正在使用实现接口的片段。

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)

【问题讨论】:

    标签: android android-fragments fragment


    【解决方案1】:

    我发现了我所做的错误。 我们需要从覆盖方法 OnAttach() 中获取活动实例 例如,

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

    然后将活动作为上下文传递,如下所示。

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

    【讨论】:

    • 对我来说似乎是一个 android bug,但很好的解决方法,为我解决了问题!
    • onAttach 已弃用
    • @Menna-AllahSami onAttach(Context context) 不是。
    • @Menna-AllahSami 以活动为参数的那个,是的。有上下文的不是。
    • 我不知道这是如何解决问题的,但它确实有效。
    【解决方案2】:

    这个问题的答案帮助我找到了我的问题,但我的来源不同,所以希望这可以帮助人们找到这个页面来寻找“随机”上下文崩溃的答案:

    我指定了一个 SharedPreferences 对象,并尝试在它的类级声明中实例化它,如下所示:

    public class MyFragment extends FragmentActivity {
        private SharedPreferences sharedPref =
            PreferenceManager.getDefaultSharedPreferences(this);
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //...
    

    在onCreate之前引用this导致“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);
    

    希望对您有所帮助。

    【讨论】:

    • 我在从 Application 类构造函数(公共类 MyApplication 扩展 Application)调用 getDefaultSharedPreferences() 时遇到了同样的问题。您的消息有助于看到我应该将其移至 onCreate 方法。
    • 不错的提示,对我帮助很大
    【解决方案3】:

    android API 级别 23。

    使用

    getContext()

    而不是

    getActivity()

    getActivity() 给父Activity,一个Context对象

    这里可以使用

    MyActivity.this

    而不是

    getActivity()/getApplicationContext()

    【讨论】:

    • 我使用 getContext() 得到了相同的 NPE
    • 一些手机通过 MyActivity.this 获得 NPE(例如一加和联想)
    • @DagnogoJean-François 如何解决这些手机的问题?
    • 可能为他人工作,但不为我工作。我使用的是Fragment
    【解决方案4】:

    我在尝试在片段中显示 Toast 时遇到了同样的问题。

    经过一些调试,我发现我在调用之前删除了片段:

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

    由于片段已被移除,上下文变为空,导致异常。

    简单的解决方案:调用getContext() 在删除之前片段。

    【讨论】:

      【解决方案5】:

      在我的情况下,错误发生在这一行的 Fragment 内:

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

      当我双击触发上述代码的项目时发生了这种情况,因此同时启动了两个 SecondaryActivity.class 活动,一个在另一个之上。我通过按下后退按钮关闭了顶部的SecondaryActivity.class 活动,该按钮触发了对SecondaryActivity.class 中的getActivity() 的调用,该调用进入了前台。对getActivity() 的调用返回null。 这是某种奇怪的 Android 错误,因此通常不应该发生。 您可以在用户点击一次后阻止点击。

      【讨论】:

        【解决方案6】:

        在我的例子中,我在 recyclerview 适配器上下文上下文中有一个 onCLick 方法;一开始。

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

        【讨论】:

          【解决方案7】:

          对我来说,问题是我将 Activity 传递给构造函数,而不是 Context

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

          并使用此活动来获取默认共享偏好(),所以我将活动更改为上下文,我仍然使用 MainActivity.this 调用适配器构造函数

          【讨论】:

            【解决方案8】:

            你只需要这样做:

            Intent myIntent = new Intent(MainActivity.this, nextActivity.class);
            

            【讨论】:

            • 在片段中?
            【解决方案9】:

            我的课程没有扩展到 Activiti。 我就是这样解决问题的。

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

            【讨论】:

              【解决方案10】:

              将片段名称放在活动之前

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

              【讨论】:

                【解决方案11】:

                你用 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() 将不再工作。这对于用户离开活动后未关闭的线程也很有用。非常感谢!
                【解决方案12】:

                您可以轻松解决您的问题并在活动中的任何位置使用您的活动,只需像这样存储活动:

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

                【讨论】:

                  【解决方案13】:

                  由于onAttach 在 API23 及更高版本中已弃用... 在我的 Fragment 中,我每次进入 Fragment 时都会事先声明并设置parentActivity。很可能是因为当我们按下返回按钮时导致上下文变为空。因此下面是我的解决方案。

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

                  【讨论】:

                    【解决方案14】:
                      public MessageAdapter(Context context, List<Messages> mMessageList) {
                    
                        this.mContext = context;
                        this.mMessageList = mMessageList;
                    
                      }
                    

                    【讨论】:

                      【解决方案15】:

                      使用可以在全局中使用

                      Context context;
                      

                      并创建一个构造函数并传递上下文。 LoginClass 是类的名称

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

                      当我们调用类时,使用getApplicationContext 喜欢 LoginClass lclass = new LoginClass(getApplicationContext) 就是这样。

                      【讨论】:

                        【解决方案16】:

                        有时startActivity 方法会抛出异常,尤其是在Fragments

                        Activity 上下文外部调用startActivity() 需要FLAG_ACTIVITY_NEW_TASK 标志。这真的是你想要的吗?

                        所以你应该intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)方法

                        【讨论】:

                          【解决方案17】:

                          在科特林

                          lateinit var views:View?
                          override fun onCreateView(
                              inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?
                          ): View? {
                              // Inflate the layout for this fragment
                               views=inflater.inflate(R.layout.fragment_dashboard, container, false)
                             Toast.makeText(views.context ,"hello",Toast.LENGTH_LONG).show()
                             return views;
                          }
                          

                          【讨论】:

                            猜你喜欢
                            • 2018-10-29
                            • 1970-01-01
                            • 1970-01-01
                            • 2017-09-01
                            • 1970-01-01
                            • 2021-07-01
                            • 1970-01-01
                            • 2017-01-09
                            相关资源
                            最近更新 更多