Google Maps v2 lag after popping their fragment back from stack

后端 未结 3 1619
挽巷
挽巷 2021-01-05 04:07

I have an Activity with a MapFragment that I add to the Activity programmatically using a FragmentTransaction:

         


        
相关标签:
3条回答
  • 2021-01-05 04:40

    it only lag if you press the back button?

    if thats the problem try to block the back button or make it exit the app try this code:

        @Override
    public void onBackPressed(){
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setMessage("You wanna leave the aplication?").setPositiveButton("Yes", dialogClickListener)
                .setNegativeButton("No", dialogClickListener).show();
    
    }
    

    or try this code its a way to put a map fragment inside another fragment (nested Map Fragment) it worked for me a weeks ago:

    Java Class:

    public class Yourfragment extends Fragment {
    
        private MapView mMapView;
        private GoogleMap mMap;
        private Bundle mBundle;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
    
            try {
                MapsInitializer.initialize(getActivity());
            } catch (GooglePlayServicesNotAvailableException e) {
                // TODO handle this situation
            }
    
            mMapView = (MapView) inflatedView.findViewById(R.id.map);
            mMapView.onCreate(mBundle);
            setUpMapIfNeeded(inflatedView);
    
            return inflatedView;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            mBundle = savedInstanceState;
        }
    
        private void setUpMapIfNeeded(View inflatedView) {
            if (mMap == null) {
                mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
                if (mMap != null) {
                    setUpMap();
                }
            }
        }
    
        private void setUpMap() {
            mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
        }
    
        @Override
        public void onResume() {
            super.onResume();
            mMapView.onResume();
        }
    
        @Override
        public void onPause() {
            super.onPause();
            mMapView.onPause();
        }
    
        @Override
        public void onDestroy() {
            mMapView.onDestroy();
            super.onDestroy();
        }
    }
    

    XML:

    <com.google.android.gms.maps.MapView
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />
    

    put this code on post execute:

    View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
    
    try {
        MapsInitializer.initialize(getActivity());
    } catch (GooglePlayServicesNotAvailableException e) {
        // TODO handle this situation
    }
    
    mMapView = (MapView) inflatedView.findViewById(R.id.map);
    mMapView.onCreate(mBundle);
    setUpMapIfNeeded(inflatedView);
    
    return inflatedView;
    

    and call the assynctask on oncreateview

    Try this:

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        //Call assyncTask
    }
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mBundle = savedInstanceState;
    }
    
    private void setUpMapIfNeeded(View inflatedView) {
        if (mMap == null) {
            mMap = ((MapView) inflatedView.findViewById(R.id.map)).getMap();
            if (mMap != null) {
                setUpMap();
            }
        }
    }
    
    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }
    
    @Override
    public void onResume() {
        super.onResume();
        mMapView.onResume();
    }
    
    @Override
    public void onPause() {
        super.onPause();
        mMapView.onPause();
    }
    
    @Override
    public void onDestroy() {
        mMapView.onDestroy();
        super.onDestroy();
    }
    private class GetFlightsTask extends AsyncTask<Double, Void, String> {
    
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        // if I remove the next line, everything gets fixed
        loadingFlightsSpinner.show();
    }
    
    @Override
    protected String doInBackground(Double... params) {
        // some pretty long remote API call
        // (loading a JSON file from http://some.website.com/flights?...)
        // works fine
        String flightsJSON = loadJSON("flights?flyFrom=CZ&to=...");
    }
    
    @Override
    protected void onPostExecute(String flightsJSON) {
        super.onPostExecute(flightsJSON);
        loadingFlightsSpinner.dismiss();
        // here I do stuff with the JSON and then replace the fragment
        dohardwork()
    }
    public view dohardwork(){
        View inflatedView = inflater.inflate(R.layout.map_fragment, container, false);
    
        try {
            MapsInitializer.initialize(getActivity());
        } catch (GooglePlayServicesNotAvailableException e) {
            // TODO handle this situation
        }
    
        mMapView = (MapView) inflatedView.findViewById(R.id.map);
        mMapView.onCreate(mBundle);
        setUpMapIfNeeded(inflatedView);
    
        return inflatedView;
    }
    
    0 讨论(0)
  • 2021-01-05 04:41

    I have fixed it by dismissing the ProgressDialog already at the end of the AsyncTask's doInBackground() method rather than at the beginning of the onPostExecute() method.

    Which is a bit weird because I actually thought I shouldn't touch things from the UI in the doInBackground() method... If someone wants to elaborate on it a bit, I would be glad to learn why it works like this.

    0 讨论(0)
  • 2021-01-05 04:56

    I have run a simple test:

    public class MapFragmentOnBackStackExample extends FragmentActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.map_fragment_on_back_stack_example);
    
            FragmentManager fm = getSupportFragmentManager();
            Fragment f = fm.findFragmentById(R.id.fragment_container);
            if (f == null) {
                f = SupportMapFragment.newInstance();
                FragmentTransaction transaction = fm.beginTransaction();
                transaction.add(R.id.fragment_container, f);
                transaction.commit();
            }
        }
    
        public void onAddFragmentClick(View view) {
            FragmentManager fm = getSupportFragmentManager();
            FragmentTransaction transaction = fm.beginTransaction();
            transaction.replace(R.id.fragment_container, new MyFragment());
            transaction.addToBackStack(null);
            transaction.commit();
        }
    
        public static class MyFragment extends Fragment {
    
            @Override
            public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
                TextView textView = new TextView(getActivity());
                textView.setText("MyFragment: " + hashCode());
                return textView;
            }
        }
    }
    

    and can't see any problems.

    I could see the problem when commented if (f == null) { leaving it to always create new fragment on rotation, which is obviously wrong, but that brings some suspicions.

    Can you see more than 1 MapFragment in memory at the same time? Try using Eclipse Memory Analyzer (MAT).

    0 讨论(0)
提交回复
热议问题