每当我运行我的片段时,这行代码 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】:

mapFragmentnull。请确认您的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使我的应用程序崩溃

片段之间的共享元素转换

在 Android 片段中获取 Java.Lang.NullPointerException

使用选项卡式活动和片段时应用程序崩溃

每当我运行代码时,我的默认情况总是与其他情况一起运行(C ++)