为什么 getcontext() 仅在一种方法中为 null?
Why is getcontext() null only in one method?
你好,我在 Android Studio 的抽屉 activity 中制作了一个地图应用程序,一切都很顺利,直到我开始玩片段,因为我在 android 我真的不知道发生了什么或问题的原因是什么。
我用地图布局替换了主布局,使其成为我的 "home" 布局。然后我添加了一个片段,我可以在其中更改名为 "Configuration" 的应用程序的语言,并在抽屉菜单中按下 "Configuration" 按钮时调用该片段。
我注意到即使配置片段替换了地图布局,地图片段中的一些定位方法在后台仍然处于活动状态,我知道这是因为每次应用程序检查权限或更改时都会显示 Toast 消息location 我这样做是为了视觉辅助,所以我知道它的工作原理。
有 2 种情况,我的应用程序因同一行代码中的相同错误而崩溃,而它恰好是我作为帮助而放在那里的祝酒词之一。这对我来说很奇怪,因为显示消息后所有其他吐司都工作正常但是当它在 onLocationChanged 方法到达特定吐司时显示下一个错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.widget.Toast.<init>(Toast.java:114)
at android.widget.Toast.makeText(Toast.java:277)
at android.widget.Toast.makeText(Toast.java:267)
at com.tesseract.psiclops.zerov2.mapFragment.onLocationChanged(mapFragment.java:172)
at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8)
at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
所以触发错误的两件事是:
1.- 当我按下后退按钮并且后台堆栈中没有片段(我想)所以它隐藏(关闭?最小化?)应用程序然后我再次打开它......它崩溃了。
2.- 当我进入配置片段并更改语言时。注意:我用来更改语言的方法会重新启动 activity,以便显示语言更改。
我想既然我关闭了应用程序,同时按下了后退按钮或调用了我的 languaje 方法,那么 getcontext() 在此之后变为 null 是有道理的,但为什么其他 toasts 显示消息并且只在那个时候崩溃具体路线?或具体方法?我该如何防止这种情况??
注意:当我注释掉 toast 时,一切正常,没有崩溃或任何问题 :S,我真的需要了解发生了什么,这样我就可以防止以后出现任何问题。
地图片段:
public class mapFragment extends Fragment implements OnMapReadyCallback, LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleMap mMap;
private GoogleApiClient mApiClient;
private Context mContext;
private OnFragmentInteractionListener mListener;
public mapFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
.findFragmentById(R.id.map1);
mapFragment.getMapAsync(this);
}
private void SetSancrisM(final GoogleMap mMap) {
// Add a marker in Sancris and move the camera
// LatLng sancris = new LatLng(16.736380, -92.638795);
LatLngBounds SanCris = new LatLngBounds(new LatLng(16.720215, -92.684189), new LatLng(16.749950, -92.596649));
//mMap.addMarker(new MarkerOptions().position(sancris).title("Marker in Sancris"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SanCris.getCenter(), 16));
//mMap.setLatLngBoundsForCameraTarget(SanCris);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.style_json));
if (!success) {
Toast.makeText(mContext, "Chido3", Toast.LENGTH_SHORT).show();
}
} catch (Resources.NotFoundException e) {
Toast.makeText(mContext, "No cargó el styla", Toast.LENGTH_SHORT).show();
}
//Calls the function that moves the cam to Sancris
SetSancrisM(mMap);
//Location permission conditions
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(mContext, "Failed to get location permission", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
return;
} else {
if (!mMap.isMyLocationEnabled()) {
mMap.setMyLocationEnabled(true);
Toast.makeText(mContext, "Chido", Toast.LENGTH_SHORT).show();
}
}
mApiClient = new GoogleApiClient.Builder(getContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mApiClient.connect();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 200: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(mContext, "Failed to get permission 2", Toast.LENGTH_SHORT).show();
} else {
mMap.setMyLocationEnabled(true);
Toast.makeText(mContext, "Chido2", Toast.LENGTH_SHORT).show();
}
}
}
}
}
@Override
public void onLocationChanged(Location location) {
if(location==null){
Toast.makeText(mContext, "No Location 4", Toast.LENGTH_SHORT).show();
}else{
LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
mMap.animateCamera(update);
Toast.makeText(mContext, "Chido4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
}
}
LocationRequest mLocReq;
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocReq = LocationRequest.create();
mLocReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocReq.setInterval(1000);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocReq, this);
Toast.makeText(mContext, "Chido5", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
//Este código tiene que ver con la comunicación entre fragmentos y actividades, osea déjalo para después
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
mContext=context;
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
在 onLocationChanged 方法中不起作用的 toast
@Override
public void onLocationChanged(Location location) {
if(location==null){
Toast.makeText(getContext(), "No Location 4", Toast.LENGTH_SHORT).show();
}else{
LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
mMap.animateCamera(update);
Toast.makeText(getContext(), "Good4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
}
}
mapfragment 方法中的所有其他 toast 工作正常。
如果您需要更多代码,请在这里询问我,我会为您添加。非常感谢您!!
在片段中声明上下文变量
private Context mContext;
从 onAttach() 初始化它
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
你的祝酒词是
Toast.makeText(mContext,getString(R.string.toast) , Toast.LENGTH_LONG).show();
getContext()
只有 returns 当片段附加到其包含 Activity 时的非空值 - 在 onAttach()
和 onDetach()
之间。如果您在这些事件之外发生了回调,那么您就没有适当地清理您的听众。
您最早应该在 onAttach()
.
中创建监听器(即调用 requestLocationUpdates()
)
然后您必须在 onDetach()
中注销您的侦听器(即调用 removeUpdates()
),以防止泄漏您的 LocationListener 和整个 Fragment。
通常,您应该只在您的片段在屏幕上可见时才请求更新。在这种情况下,您将在 onStart()
中注册并在 onStop()
中注销。
你好,我在 Android Studio 的抽屉 activity 中制作了一个地图应用程序,一切都很顺利,直到我开始玩片段,因为我在 android 我真的不知道发生了什么或问题的原因是什么。
我用地图布局替换了主布局,使其成为我的 "home" 布局。然后我添加了一个片段,我可以在其中更改名为 "Configuration" 的应用程序的语言,并在抽屉菜单中按下 "Configuration" 按钮时调用该片段。
我注意到即使配置片段替换了地图布局,地图片段中的一些定位方法在后台仍然处于活动状态,我知道这是因为每次应用程序检查权限或更改时都会显示 Toast 消息location 我这样做是为了视觉辅助,所以我知道它的工作原理。
有 2 种情况,我的应用程序因同一行代码中的相同错误而崩溃,而它恰好是我作为帮助而放在那里的祝酒词之一。这对我来说很奇怪,因为显示消息后所有其他吐司都工作正常但是当它在 onLocationChanged 方法到达特定吐司时显示下一个错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.widget.Toast.<init>(Toast.java:114)
at android.widget.Toast.makeText(Toast.java:277)
at android.widget.Toast.makeText(Toast.java:267)
at com.tesseract.psiclops.zerov2.mapFragment.onLocationChanged(mapFragment.java:172)
at com.google.android.gms.internal.location.zzay.notifyListener(Unknown Source:4)
at com.google.android.gms.common.api.internal.ListenerHolder.notifyListenerInternal(Unknown Source:8)
at com.google.android.gms.common.api.internal.ListenerHolder$zza.handleMessage(Unknown Source:16)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
所以触发错误的两件事是:
1.- 当我按下后退按钮并且后台堆栈中没有片段(我想)所以它隐藏(关闭?最小化?)应用程序然后我再次打开它......它崩溃了。
2.- 当我进入配置片段并更改语言时。注意:我用来更改语言的方法会重新启动 activity,以便显示语言更改。
我想既然我关闭了应用程序,同时按下了后退按钮或调用了我的 languaje 方法,那么 getcontext() 在此之后变为 null 是有道理的,但为什么其他 toasts 显示消息并且只在那个时候崩溃具体路线?或具体方法?我该如何防止这种情况??
注意:当我注释掉 toast 时,一切正常,没有崩溃或任何问题 :S,我真的需要了解发生了什么,这样我就可以防止以后出现任何问题。
地图片段:
public class mapFragment extends Fragment implements OnMapReadyCallback, LocationListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleMap mMap;
private GoogleApiClient mApiClient;
private Context mContext;
private OnFragmentInteractionListener mListener;
public mapFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment)getChildFragmentManager()
.findFragmentById(R.id.map1);
mapFragment.getMapAsync(this);
}
private void SetSancrisM(final GoogleMap mMap) {
// Add a marker in Sancris and move the camera
// LatLng sancris = new LatLng(16.736380, -92.638795);
LatLngBounds SanCris = new LatLngBounds(new LatLng(16.720215, -92.684189), new LatLng(16.749950, -92.596649));
//mMap.addMarker(new MarkerOptions().position(sancris).title("Marker in Sancris"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SanCris.getCenter(), 16));
//mMap.setLatLngBoundsForCameraTarget(SanCris);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.getUiSettings().setZoomControlsEnabled(true);
try {
// Customise the styling of the base map using a JSON object defined
// in a raw resource file.
boolean success = googleMap.setMapStyle(
MapStyleOptions.loadRawResourceStyle(getContext(), R.raw.style_json));
if (!success) {
Toast.makeText(mContext, "Chido3", Toast.LENGTH_SHORT).show();
}
} catch (Resources.NotFoundException e) {
Toast.makeText(mContext, "No cargó el styla", Toast.LENGTH_SHORT).show();
}
//Calls the function that moves the cam to Sancris
SetSancrisM(mMap);
//Location permission conditions
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(mContext, "Failed to get location permission", Toast.LENGTH_SHORT).show();
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
return;
} else {
if (!mMap.isMyLocationEnabled()) {
mMap.setMyLocationEnabled(true);
Toast.makeText(mContext, "Chido", Toast.LENGTH_SHORT).show();
}
}
mApiClient = new GoogleApiClient.Builder(getContext())
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mApiClient.connect();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case 200: {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(mContext, "Failed to get permission 2", Toast.LENGTH_SHORT).show();
} else {
mMap.setMyLocationEnabled(true);
Toast.makeText(mContext, "Chido2", Toast.LENGTH_SHORT).show();
}
}
}
}
}
@Override
public void onLocationChanged(Location location) {
if(location==null){
Toast.makeText(mContext, "No Location 4", Toast.LENGTH_SHORT).show();
}else{
LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
mMap.animateCamera(update);
Toast.makeText(mContext, "Chido4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
}
}
LocationRequest mLocReq;
@Override
public void onConnected(@Nullable Bundle bundle) {
mLocReq = LocationRequest.create();
mLocReq.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocReq.setInterval(1000);
if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 200);
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mApiClient, mLocReq, this);
Toast.makeText(mContext, "Chido5", Toast.LENGTH_SHORT).show();
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
//Este código tiene que ver con la comunicación entre fragmentos y actividades, osea déjalo para después
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnFragmentInteractionListener) {
mListener = (OnFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnFragmentInteractionListener");
}
mContext=context;
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}
在 onLocationChanged 方法中不起作用的 toast
@Override
public void onLocationChanged(Location location) {
if(location==null){
Toast.makeText(getContext(), "No Location 4", Toast.LENGTH_SHORT).show();
}else{
LatLng ll= new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate update= CameraUpdateFactory.newLatLngZoom(ll,mMap.getCameraPosition().zoom);
mMap.animateCamera(update);
Toast.makeText(getContext(), "Good4", Toast.LENGTH_SHORT).show(); //This one right here is the one not working
}
}
mapfragment 方法中的所有其他 toast 工作正常。
如果您需要更多代码,请在这里询问我,我会为您添加。非常感谢您!!
在片段中声明上下文变量
private Context mContext;
从 onAttach() 初始化它
@Override
public void onAttach(Context context) {
super.onAttach(context);
mContext = context;
}
你的祝酒词是
Toast.makeText(mContext,getString(R.string.toast) , Toast.LENGTH_LONG).show();
getContext()
只有 returns 当片段附加到其包含 Activity 时的非空值 - 在 onAttach()
和 onDetach()
之间。如果您在这些事件之外发生了回调,那么您就没有适当地清理您的听众。
您最早应该在 onAttach()
.
requestLocationUpdates()
)
然后您必须在 onDetach()
中注销您的侦听器(即调用 removeUpdates()
),以防止泄漏您的 LocationListener 和整个 Fragment。
通常,您应该只在您的片段在屏幕上可见时才请求更新。在这种情况下,您将在 onStart()
中注册并在 onStop()
中注销。