Android 如何防止在等待加载google地图时冻结

Android 如何防止在等待加载google地图时冻结,android,google-maps,android-fragments,Android,Google Maps,Android Fragments,在这个例子中,我在一个片段中实现了一个谷歌地图。这个应用程序还有一个导航抽屉。导航抽屉中有一个列表视图,用作应用程序的菜单。菜单项为“映射”和“片段1”。当我从导航抽屉中选择“地图”时,屏幕会冻结大约两秒钟,然后导航抽屉会向后滑动并加载地图。这不利于用户体验。在这种情况下,有没有办法防止应用程序冻结?如何让导航抽屉正常工作并指示用户的地图仍在加载?代码如下: MainActivity.java public class MainActivity extends AppCompatActivity

在这个例子中,我在一个片段中实现了一个谷歌地图。这个应用程序还有一个导航抽屉。导航抽屉中有一个列表视图,用作应用程序的菜单。菜单项为“映射”和“片段1”。当我从导航抽屉中选择“地图”时,屏幕会冻结大约两秒钟,然后导航抽屉会向后滑动并加载地图。这不利于用户体验。在这种情况下,有没有办法防止应用程序冻结?如何让导航抽屉正常工作并指示用户的地图仍在加载?代码如下:

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private Toolbar toolbar;
    private DrawerLayout drawerLayout;
    private FrameLayout framlaout;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        this.initComponents();
    }

    public void initComponents(){
        toolbar = (Toolbar) findViewById(R.id.toolBar);
        drawerLayout = (DrawerLayout) findViewById(R.id.drawerLayout);
        framlaout = (FrameLayout) findViewById(R.id.container);

        toolbar.setTitle("example");
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowHomeEnabled(true);

        NavigationFragment navigationFragment = (NavigationFragment) getSupportFragmentManager()
                .findFragmentById(R.id.navigation_fragment);
        navigationFragment.setupNavigationProperty(R.id.navigation_fragment,drawerLayout,toolbar);
        FragmentManager fm = getSupportFragmentManager();
        fm.beginTransaction().replace(R.id.container,new BlankFragment()).commit();

    }
MapFragment.java

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private GoogleMap mMap;

    public MapFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}
public class NavigationFragment extends Fragment {


    private ListView listView;
    private ArrayList<String> menuItems;
    private View containerView;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;

    public NavigationFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_navigation, container, false);

        initComponents(view);
        onClickItemnListnener();

        return view;
    }

    public void initComponents(View view){
        menuItems = new ArrayList<>();
        menuItems.add("Fragment 1");
        menuItems.add("map");

        listView = (ListView) view.findViewById(R.id.menu);
        listView.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1,menuItems));
    }

    public void setupNavigationProperty(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar){
        containerView = getActivity().findViewById(fragmentId);
        this.drawerLayout = drawerLayout;
        drawerToggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar
                ,R.string.drawer_open,R.string.drawer_close);
        drawerLayout.addDrawerListener(drawerToggle);
        drawerLayout.post(new Runnable() {
            @Override
            public void run() {
                drawerToggle.syncState();
            }
        });
    }

    public void onClickItemnListnener(){
        final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (menuItems.get(position)){
                    case "Fragment 1":
                        fragmentManager.beginTransaction().replace(R.id.container,new BlankFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                    case "map":
                        fragmentManager.beginTransaction().replace(R.id.container,new MapFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                }
            }
        });
    }

    public void closeNavigationDrawer(DrawerLayout layout,View fragmentView){
        drawerLayout = layout;
        drawerLayout.closeDrawer(containerView);
    }
NavigationFragment.java

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private GoogleMap mMap;

    public MapFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}
public class NavigationFragment extends Fragment {


    private ListView listView;
    private ArrayList<String> menuItems;
    private View containerView;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;

    public NavigationFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_navigation, container, false);

        initComponents(view);
        onClickItemnListnener();

        return view;
    }

    public void initComponents(View view){
        menuItems = new ArrayList<>();
        menuItems.add("Fragment 1");
        menuItems.add("map");

        listView = (ListView) view.findViewById(R.id.menu);
        listView.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1,menuItems));
    }

    public void setupNavigationProperty(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar){
        containerView = getActivity().findViewById(fragmentId);
        this.drawerLayout = drawerLayout;
        drawerToggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar
                ,R.string.drawer_open,R.string.drawer_close);
        drawerLayout.addDrawerListener(drawerToggle);
        drawerLayout.post(new Runnable() {
            @Override
            public void run() {
                drawerToggle.syncState();
            }
        });
    }

    public void onClickItemnListnener(){
        final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (menuItems.get(position)){
                    case "Fragment 1":
                        fragmentManager.beginTransaction().replace(R.id.container,new BlankFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                    case "map":
                        fragmentManager.beginTransaction().replace(R.id.container,new MapFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                }
            }
        });
    }

    public void closeNavigationDrawer(DrawerLayout layout,View fragmentView){
        drawerLayout = layout;
        drawerLayout.closeDrawer(containerView);
    }

java

您可能应该直接使用MapView类,而不是使用SupportMapFragment。不幸的是,即使谷歌将地图的加载称为“异步”,它实际上也是在UI线程中运行的,这就是导致冻结的原因

public class MapFragment extends Fragment implements OnMapReadyCallback {

    private GoogleMap mMap;

    public MapFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_map, container, false);
        SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        return view;
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }
}
public class NavigationFragment extends Fragment {


    private ListView listView;
    private ArrayList<String> menuItems;
    private View containerView;
    private DrawerLayout drawerLayout;
    private ActionBarDrawerToggle drawerToggle;

    public NavigationFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.fragment_navigation, container, false);

        initComponents(view);
        onClickItemnListnener();

        return view;
    }

    public void initComponents(View view){
        menuItems = new ArrayList<>();
        menuItems.add("Fragment 1");
        menuItems.add("map");

        listView = (ListView) view.findViewById(R.id.menu);
        listView.setAdapter(new ArrayAdapter<String>(getContext(),android.R.layout.simple_list_item_1,menuItems));
    }

    public void setupNavigationProperty(int fragmentId, DrawerLayout drawerLayout, Toolbar toolbar){
        containerView = getActivity().findViewById(fragmentId);
        this.drawerLayout = drawerLayout;
        drawerToggle = new ActionBarDrawerToggle(getActivity(),drawerLayout,toolbar
                ,R.string.drawer_open,R.string.drawer_close);
        drawerLayout.addDrawerListener(drawerToggle);
        drawerLayout.post(new Runnable() {
            @Override
            public void run() {
                drawerToggle.syncState();
            }
        });
    }

    public void onClickItemnListnener(){
        final FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                switch (menuItems.get(position)){
                    case "Fragment 1":
                        fragmentManager.beginTransaction().replace(R.id.container,new BlankFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                    case "map":
                        fragmentManager.beginTransaction().replace(R.id.container,new MapFragment()).commit();
                        closeNavigationDrawer(drawerLayout,containerView);
                        break;
                }
            }
        });
    }

    public void closeNavigationDrawer(DrawerLayout layout,View fragmentView){
        drawerLayout = layout;
        drawerLayout.closeDrawer(containerView);
    }
帮助我的是,在应用程序第一次启动时在后台线程中运行它,它基本上预加载了mapview:

Runnable initMap = new Runnable() {
        @Override
        public void run() {
            MapView mapView = new MapView(YourActivity.this);
            mapView.onCreate(null);
        }
    };
    new Thread(initMap).start();

你没有改变什么吗?结果不一样。我不能调用getMapAsync(这个);在线程上。它必须在主线程中被调用。