android.content.Context.getPackageName()' 在空对象引用上
android.content.Context.getPackageName()' on a null object reference
我正在使用实现接口的片段。
public class SigninFragment extends Fragment implements SigninInterface
片段class中接口的方法实现如下
@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)后调用 class。
但是我崩溃了。
并且错误信息显示
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.access0(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)
我发现我做的错误了。
我们需要从覆盖方法 OnAttach() 中获取 activity 实例
例如,
public MainActivity activity;
@Override
public void onAttach(Activity activity){
this.activity = activity;
}
然后将 activity 作为上下文传递,如下所示。
Intent mIntent = new Intent(activity, MusicHome.class);
您只需要这样做:
Intent myIntent = new Intent(MainActivity.this, nextActivity.class);
这个问题的答案帮助我找到了我的问题,但我的来源不同,所以希望这可以帮助找到此页面的人寻找 'random' 上下文崩溃的答案:
我指定了一个 SharedPreferences 对象,并试图在它的 class 级声明中实例化它,如下所示:
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);
希望对您有所帮助。
android API 23级.
使用
getContext()
而不是
getActivity()
getActivity() 给父 Activity,一个 Context 对象
在这里你可以使用
MyActivity.this
而不是
getActivity() / getApplicationContext()
对我来说,问题是我将 Activity 传递给构造函数,而不是 Context
public Adapter(Activity activity, List<MediaItem> items, boolean can) {
mItems = items;
canEdit = can;
mActivity = activity;
}
并使用此 activity 到 getDefaultSharedPreferences(),所以我将 Activity 更改为 Context 并且我仍在使用 MainActivity.this
调用 Adapter 构造函数
在我的例子中,错误发生在 Fragment
这一行:
Intent intent = new Intent(getActivity(), SecondaryActivity.class);
当我双击一个触发上述代码的项目时发生这种情况,因此同时启动了两个 SecondaryActivity.class
活动,一个在另一个之上。我通过按下后退按钮关闭了顶部 SecondaryActivity.class
activity ,这触发了对 SecondaryActivity.class
中 getActivity()
的调用,它来到前台。对 getActivity()
的调用返回了 null
。
这是某种奇怪的 Android 错误,所以它通常不应该发生。
您可以在用户点击一次后阻止点击。
您通过 try/catch 解决了问题。
当用户在启动意图之前关闭应用程序时会发生此崩溃。
try
{
Intent mIntent = new Intent(getActivity(),MusicHome.class);
mIntent.putExtra("SigninFragment.user_details", bundle);
startActivity(mIntent);
}
catch (Exception e) {
e.printStackTrace();
}
我的 class 没有扩展到 Activiti。
我是这样解决问题的。
class MyOnBindViewHolder : LogicViewAdapterModel.LogicAdapter {
...
holder.title.setOnClickListener({v->
v.context.startActivity(Intent(context, HomeActivity::class.java))
})
...
}
我在尝试在片段中显示 Toast 时遇到了同样的问题。
经过一些调试,我发现我在调用之前删除了片段:
Toast.makeText(getContext(), "text", Toast.LENGTH_SHORT).show();
由于片段已被删除,上下文变为空,导致异常。
简单的解决方案:在删除 片段之前调用getContext()
。
您可以轻松解决您的问题并在 activity 中的任何地方使用您的 activity,只需像这样存储 activity:
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);
}
}
将片段名称放在 activity
之前
Intent mIntent = new Intent(SigninFragment.this.getActivity(),MusicHome.class);
在我的例子中,我在 recyclerview 适配器中有一个 onCLick 方法,Context 上下文;在开头。
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);
}
});
由于 onAttach
在 API23 及更高版本中已弃用...
在我的片段中,每次进入片段时,我都会预先声明并设置 parentActivity
。最有可能发生的原因是当我们按下后退按钮时导致上下文变为空。因此下面是我的解决方案。
private Activity parentActivity;
public void onStart(){
super.onStart();
parentActivity = getActivity();
//...
}
public MessageAdapter(Context context, List<Messages> mMessageList) {
this.mContext = context;
this.mMessageList = mMessageList;
}
使用可以在全球使用
Context context;
并创建构造函数并传递上下文。
LoginClass 是 class
的名称
LoginClass(Context context)
{this.context=context;}
并且当我们调用 class 然后使用 getApplicationContext
像
LoginClass lclass = new LoginClass(getApplicationContext)
就是这样。
在科特林
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;
}
有时 startActivity
方法会抛出异常,尤其是 Fragments
:
从 Activity
上下文外部调用 startActivity()
需要 FLAG_ACTIVITY_NEW_TASK
标志。这真的是你想要的吗?
所以你应该intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
方法
我正在使用实现接口的片段。
public class SigninFragment extends Fragment implements SigninInterface
片段class中接口的方法实现如下
@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)后调用 class。
但是我崩溃了。 并且错误信息显示
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.access0(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)
我发现我做的错误了。 我们需要从覆盖方法 OnAttach() 中获取 activity 实例 例如,
public MainActivity activity;
@Override
public void onAttach(Activity activity){
this.activity = activity;
}
然后将 activity 作为上下文传递,如下所示。
Intent mIntent = new Intent(activity, MusicHome.class);
您只需要这样做:
Intent myIntent = new Intent(MainActivity.this, nextActivity.class);
这个问题的答案帮助我找到了我的问题,但我的来源不同,所以希望这可以帮助找到此页面的人寻找 'random' 上下文崩溃的答案:
我指定了一个 SharedPreferences 对象,并试图在它的 class 级声明中实例化它,如下所示:
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);
希望对您有所帮助。
android API 23级.
使用
getContext()
而不是
getActivity()
getActivity() 给父 Activity,一个 Context 对象
在这里你可以使用
MyActivity.this
而不是
getActivity() / getApplicationContext()
对我来说,问题是我将 Activity 传递给构造函数,而不是 Context
public Adapter(Activity activity, List<MediaItem> items, boolean can) {
mItems = items;
canEdit = can;
mActivity = activity;
}
并使用此 activity 到 getDefaultSharedPreferences(),所以我将 Activity 更改为 Context 并且我仍在使用 MainActivity.this
调用 Adapter 构造函数在我的例子中,错误发生在 Fragment
这一行:
Intent intent = new Intent(getActivity(), SecondaryActivity.class);
当我双击一个触发上述代码的项目时发生这种情况,因此同时启动了两个 SecondaryActivity.class
活动,一个在另一个之上。我通过按下后退按钮关闭了顶部 SecondaryActivity.class
activity ,这触发了对 SecondaryActivity.class
中 getActivity()
的调用,它来到前台。对 getActivity()
的调用返回了 null
。
这是某种奇怪的 Android 错误,所以它通常不应该发生。
您可以在用户点击一次后阻止点击。
您通过 try/catch 解决了问题。 当用户在启动意图之前关闭应用程序时会发生此崩溃。
try
{
Intent mIntent = new Intent(getActivity(),MusicHome.class);
mIntent.putExtra("SigninFragment.user_details", bundle);
startActivity(mIntent);
}
catch (Exception e) {
e.printStackTrace();
}
我的 class 没有扩展到 Activiti。 我是这样解决问题的。
class MyOnBindViewHolder : LogicViewAdapterModel.LogicAdapter {
...
holder.title.setOnClickListener({v->
v.context.startActivity(Intent(context, HomeActivity::class.java))
})
...
}
我在尝试在片段中显示 Toast 时遇到了同样的问题。
经过一些调试,我发现我在调用之前删除了片段:
Toast.makeText(getContext(), "text", Toast.LENGTH_SHORT).show();
由于片段已被删除,上下文变为空,导致异常。
简单的解决方案:在删除 片段之前调用getContext()
。
您可以轻松解决您的问题并在 activity 中的任何地方使用您的 activity,只需像这样存储 activity:
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);
}
}
将片段名称放在 activity
之前Intent mIntent = new Intent(SigninFragment.this.getActivity(),MusicHome.class);
在我的例子中,我在 recyclerview 适配器中有一个 onCLick 方法,Context 上下文;在开头。
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);
}
});
由于 onAttach
在 API23 及更高版本中已弃用...
在我的片段中,每次进入片段时,我都会预先声明并设置 parentActivity
。最有可能发生的原因是当我们按下后退按钮时导致上下文变为空。因此下面是我的解决方案。
private Activity parentActivity;
public void onStart(){
super.onStart();
parentActivity = getActivity();
//...
}
public MessageAdapter(Context context, List<Messages> mMessageList) {
this.mContext = context;
this.mMessageList = mMessageList;
}
使用可以在全球使用
Context context;
并创建构造函数并传递上下文。 LoginClass 是 class
的名称LoginClass(Context context)
{this.context=context;}
并且当我们调用 class 然后使用 getApplicationContext
像
LoginClass lclass = new LoginClass(getApplicationContext)
就是这样。
在科特林
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;
}
有时 startActivity
方法会抛出异常,尤其是 Fragments
:
从 Activity
上下文外部调用 startActivity()
需要 FLAG_ACTIVITY_NEW_TASK
标志。这真的是你想要的吗?
所以你应该intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
方法