每当我运行我的片段时,这行代码 mapFragment.setRetainInstance(true);正在崩溃我的应用程序? [关闭]
Posted
技术标签:
【中文标题】每当我运行我的片段时,这行代码 mapFragment.setRetainInstance(true);正在崩溃我的应用程序? [关闭]【英文标题】:whenever i run my fragment this line of code mapFragment.setRetainInstance(true); is crashing my app? [closed] 【发布时间】:2020-11-17 13:09:09 【问题描述】:所以我有一个地图活动,我将其更改为片段,因此我可以在我的视图页面上显示它,但是在将活动更改为片段后,这行代码 mapFragment.setRetainInstance(true);正在使应用程序崩溃。将 MapsActivity 更改为 Fragment 时是否遗漏了任何内容,将旧 MapsActivity 类和我更改为 Fragment 的类放在下面,以便大家看看。
我将 MapsActivity.java 更改为片段,以便我可以在 viewpager 上显示它:
public class MapsActivity extends Fragment
implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener,
com.google.android.gms.location.LocationListener
View view;
Context context;
public static boolean SAVE_LOCATION,SAVE_LOCATION_ADDRESS;
private static final String TAG = "Current Location";
GoogleMap mGoogleMap;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
Location mLastLocation;
private LatLng mDefaultLocation;
private static final int DEFAULT_ZOOM = 15;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private static final int PERMISSION_DATA_ACCESS_CODE = 2;
private boolean mLocationPermissionGranted;
String lat,long_;
SwitchCompat current_loction_switch,selected_location_switch;
ExpandableRelativeLayout expandable_layout;
TextView my_current_location;
TextView new_location_txt;
boolean isMaptouched=false;
private GeoDataClient mGeoDataClient;
private PlaceDetectionClient mPlaceDetectionClient;
// The entry point to the Fused Location Provider.
private FusedLocationProviderClient mFusedLocationProviderClient;
// A default location (Sydney, Australia) and default zoom to use when location permission is
// not granted.
private Location mLastKnownLocation;
private SupportMapFragment mapFragment;
private MapView mapView;
private SharedPreferences sPredMap;
private GoogleMap.OnCameraIdleListener onCameraIdleListener;
ImageView close_country;
TextView current_text_tv;
RelativeLayout current_address_div;
Button save_loc_div;
ImageButton arrow_down;
public MapsActivity()
// Required empty public constructor
@SuppressWarnings("deprecation")
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
context = getContext();
view = inflater.inflate(R.layout.activity_main_maps, container, false);
SharedPreferences sPredMap = this.getActivity().getSharedPreferences(Variables.pref_name,MODE_PRIVATE);
lat = sPredMap.getString(Variables.seleted_Lat,"");
long_ = sPredMap.getString(Variables.selected_Lon,"");
if(lat.isEmpty()&&long_.isEmpty())
lat = sPredMap.getString(Variables.current_Lat,"");
long_ =sPredMap.getString(Variables.current_Lon,"");
mDefaultLocation = new LatLng(Double.parseDouble(lat), Double.parseDouble(long_));
current_text_tv = view.findViewById(R.id.current_text_tv);
close_country = view.findViewById(R.id.close_country);
current_address_div = view.findViewById(R.id.current_address_div);
save_loc_div = view.findViewById(R.id.save_loc_div);
save_loc_div.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
SAVE_LOCATION = true;
SAVE_LOCATION_ADDRESS = true;
Intent data = new Intent();
data.putExtra("lat", String.valueOf(lat));
data.putExtra("lng", String.valueOf(long_));
data.putExtra("location_string",current_text_tv.getText());
getActivity().setResult(Activity.RESULT_OK, data);
//(RESULT_OK, data);
String latSearch = data.getStringExtra("lat");
String longSearch = data.getStringExtra("lng");
String location_string = data.getStringExtra("location_string");
new_location_txt.setText(location_string);
new_location_txt.setText(location_string);
selected_location_switch.setClickable(true);
current_loction_switch.setClickable(true);
selected_location_switch.setChecked(true);
MainMenuActivity.sharedPreferences.edit().putString(Variables.seleted_Lat,latSearch).commit();
MainMenuActivity.sharedPreferences.edit().putString(Variables.selected_Lon,longSearch).commit();
MainMenuActivity.sharedPreferences.edit().putString(Variables.selected_location_string,location_string).commit();
);
current_address_div.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
Intent i = new Intent(getActivity(), SearchPlaces.class);
startActivityForResult(i, PERMISSION_DATA_ACCESS_CODE);
);
close_country.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View view)
getActivity().finish();
);
mGeoDataClient = Places.getGeoDataClient(this.getActivity(), null);
// Construct a PlaceDetectionClient.
mPlaceDetectionClient = Places.getPlaceDetectionClient(this.getActivity(), null);
// Construct a FusedLocationProviderClient.
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this.getActivity());
setupMapIfNeeded();
configureCameraIdle();
mapFragment.setRetainInstance(true);
current_loction_switch = view.findViewById(R.id.current_loction_switch);
selected_location_switch=view.findViewById(R.id.selected_location_switch);
if(MainMenuActivity.sharedPreferences.getBoolean(Variables.is_seleted_location_selected,false))
selected_location_switch.setChecked(true);
else
current_loction_switch.setChecked(true);
current_loction_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
Variables.is_reload_users=true;
if(isChecked)
MainMenuActivity.sharedPreferences.edit().putBoolean(Variables.is_seleted_location_selected,false).commit();
selected_location_switch.setChecked(false);
else
MainMenuActivity.sharedPreferences.edit().putBoolean(Variables.is_seleted_location_selected,true).commit();
selected_location_switch.setChecked(true);
// my_current_location.setText(MainMenuActivity.sharedPreferences.getString(Variables.selected_location_string,""));
);
selected_location_switch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
Variables.is_reload_users=true;
if(isChecked)
MainMenuActivity.sharedPreferences.edit().putBoolean(Variables.is_seleted_location_selected,true).commit();
current_loction_switch.setChecked(false);
my_current_location.setText(MainMenuActivity.sharedPreferences.getString(Variables.selected_location_string,""));
else
MainMenuActivity.sharedPreferences.edit().putBoolean(Variables.is_seleted_location_selected,false).commit();
current_loction_switch.setChecked(true);
);
new_location_txt=view.findViewById(R.id.new_location_txt);
if(!MainMenuActivity.sharedPreferences.getString(Variables.selected_location_string,"").equals(""))
new_location_txt.setText(MainMenuActivity.sharedPreferences.getString(Variables.selected_location_string,""));
else
selected_location_switch.setClickable(false);
current_loction_switch.setClickable(false);
//below code is to collapse expanble view when arrow is clicked
expandable_layout=view.findViewById(R.id.expandable_layout);
arrow_down =view.findViewById(R.id.arrow_down);
arrow_down.setOnClickListener(new View.OnClickListener()
@Override
public void onClick(View v)
if(expandable_layout.isExpanded())
arrow_down.setRotation(90);
expandable_layout.collapse();
else
arrow_down.setRotation(270);
expandable_layout.expand();
);
return view;
@Override
public void onResume()
super.onResume();
setupMapIfNeeded();
@Override
public void onSaveInstanceState(Bundle outState)
super.onSaveInstanceState(outState);
@Override
public void onMapReady(GoogleMap googleMap)
mGoogleMap = googleMap;
updateLocationUI();
getDeviceLocation();
mGoogleMap.getUiSettings().setCompassEnabled(false);
MapStateManager mgr = new MapStateManager(this.getActivity());
CameraPosition position = mgr.getSavedCameraPosition();
if (position != null)
CameraUpdate update = CameraUpdateFactory.newCameraPosition(position);
mGoogleMap.moveCamera(update);
mGoogleMap.setMapType(mgr.getSavedMapType());
if (mGoogleMap != null)
mGoogleMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
if (ActivityCompat.checkSelfPermission(getApplicationContext()
, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getApplicationContext()
, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
return;
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
mGoogleMap.setOnCameraIdleListener(onCameraIdleListener);
@Override
public void onStart()
super.onStart();
private void updateLocationUI()
if (mGoogleMap == null)
return;
try
if (mLocationPermissionGranted)
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
else
mGoogleMap.setMyLocationEnabled(false);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
mLastKnownLocation = null;
getLocationPermission();
catch (SecurityException e)
Log.e("Exception: %s", e.getMessage());
private void getDeviceLocation()
try
if (mLocationPermissionGranted)
Task locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this.getActivity(), new OnCompleteListener()
@Override
public void onComplete(@NonNull Task task)
if (task.isSuccessful())
// Set the map's camera position to the current location of the device.
mLastKnownLocation = (Location) task.getResult();
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng(Double.parseDouble(lat), Double.parseDouble(long_)), DEFAULT_ZOOM));
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
SharedPreferences.Editor editor = sPredMap.edit();
editor.putString(Variables.current_Lat, String.valueOf(lat));
editor.putString(Variables.current_Lon, String.valueOf(long_));
editor.apply();
else
Log.d(TAG, "Current location is null. Using defaults.");
Log.e(TAG, "Exception: %s", task.getException());
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
);
catch(SecurityException e)
Log.e("Exception: %s", e.getMessage());
private void configureCameraIdle()
onCameraIdleListener = new GoogleMap.OnCameraIdleListener()
@Override
public void onCameraIdle()
LatLng latLng = mGoogleMap.getCameraPosition().target;
Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
try
List<Address> addressList = geocoder.getFromLocation(latLng.latitude, latLng.longitude, 1);
if (addressList != null && addressList.size() > 0)
String country = addressList.get(0).getCountryName();
lat = ""+latLng.latitude;
long_ = ""+latLng.longitude;
current_text_tv.setText(country);
catch (IOException e)
e.printStackTrace();
;
private void setupMapIfNeeded()
// Build the map.
if(mGoogleMap==null)
SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
@Override
public void onPause()
super.onPause();
MapStateManager mgr = new MapStateManager(this.getActivity());
mgr.saveMapState(mGoogleMap);
private void getLocationPermission()
/*
* Request location permission, so that we can get the location of the
* device. The result of the permission request is handled by a callback,
* onRequestPermissionsResult.
*/
if (ContextCompat.checkSelfPermission(this.getActivity().getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED)
mLocationPermissionGranted = true;
else
try
ActivityCompat.requestPermissions(getActivity(),
new String[]android.Manifest.permission.ACCESS_FINE_LOCATION,
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
catch (Exception e)
e.getMessage();
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PERMISSION_DATA_ACCESS_CODE)
if(resultCode == RESULT_OK)
String latSearch = data.getStringExtra("lat");
String longSearch = data.getStringExtra("lng");
lat = latSearch;
long_ = longSearch;
mDefaultLocation = new LatLng(Double.parseDouble(latSearch), Double.parseDouble(longSearch));
mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(mDefaultLocation, DEFAULT_ZOOM));
if (requestCode == 111)
if(resultCode == RESULT_OK)
String latSearch = data.getStringExtra("lat");
String longSearch = data.getStringExtra("lng");
String location_string = data.getStringExtra("location_string");
new_location_txt.setText(location_string);
new_location_txt.setText(location_string);
selected_location_switch.setClickable(true);
current_loction_switch.setClickable(true);
selected_location_switch.setChecked(true);
MainMenuActivity.sharedPreferences.edit().putString(Variables.seleted_Lat,latSearch).commit();
MainMenuActivity.sharedPreferences.edit().putString(Variables.selected_Lon,longSearch).commit();
MainMenuActivity.sharedPreferences.edit().putString(Variables.selected_location_string,location_string).commit();
@Override
public void onRequestPermissionsResult(int requestCode,
@NonNull String permissions[],
@NonNull int[] grantResults)
mLocationPermissionGranted = false;
switch (requestCode)
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED)
mLocationPermissionGranted = true;
updateLocationUI();
protected synchronized void buildGoogleApiClient()
mGoogleApiClient = new GoogleApiClient.Builder(this.getActivity())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
if (mGoogleApiClient != null)
mGoogleApiClient.connect();
@Override
public void onLocationChanged(Location location)
mLastLocation = location;
@Override
public void onStatusChanged(String s, int i, Bundle bundle)
@Override
public void onProviderEnabled(String s)
@Override
public void onProviderDisabled(String s)
@Override
public void onConnected(@Nullable Bundle bundle)
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(0);
mLocationRequest.setFastestInterval(0);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
@Override
public void onConnectionSuspended(int i)
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult)
private void getDriversAround()
DatabaseReference driversLocation = FirebaseDatabase.getInstance().getReference().child(("availableUsers"));
【问题讨论】:
【参考方案1】:mapFragment
是 null
。请确认您的layout
文件包含
<fragment
android:id="@+id/map"
android:layout_
android:layout_
class="com.google.android.gms.maps.SupportMapFragment" />
您正在膨胀正确的layout
文件。其次,你的函数setupMapIfNeeded
有错误的条件。您的条件应该在片段上,并且必须分配给全局变量mapFragment
setupMapIfNeeded
private void setupMapIfNeeded()
// Build the map.
if(mapFragment==null)
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
【讨论】:
以上是关于每当我运行我的片段时,这行代码 mapFragment.setRetainInstance(true);正在崩溃我的应用程序? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章
每当我尝试从 Fragment java 文件中更改片段的某些属性时,应用程序就会崩溃
android studio中片段内的RecyclerView使我的应用程序崩溃