简体   繁体   English

在主线程上加载SupportMapFragment并冻结接口(忽略getMapAsync)

[英]SupportMapFragment loading on the main thread and freezing the interface (getMapAsync ignored)

In a default SupportMapFragment the MapView is being loaded and created when the Fragment is instantied thus doing the heavy work on the Main Thread. 在默认的SupportMapFragment中,在实例化Fragment时将加载并创建MapView,从而在主线程上进行了大量工作。

The log below happens before getMapAsync(this); 下面的日志发生在getMapAsync(this);之前getMapAsync(this); is called and it is the moment when the Main Thread freezes for about 2 seconds. 被调用,这是主线程冻结大约2秒钟的时刻。 The log proves somehow that everything is being created before getMapAsync() . 该日志以某种方式证明了在getMapAsync()之前已创建了所有内容

Isn't the map supposed to load ONLY when getMapAsync() is called? 调用getMapAsync()时,地图不应该只加载吗?

I/OpenGLRenderer: Initialized EGL, version 1.4
D/OpenGLRenderer: Enabling debug mode 0
D/OpenGLRenderer: endAllActiveAnimators on 0xb7966f90 (RippleDrawable) with handle 0xb7988688
I/AppCompatViewInflater: app:theme is now deprecated. Please move to using android:theme instead.
I/zzy: Making Creator dynamically
W/ResourcesManager: Asset path '/system/framework/com.android.media.remotedisplay.jar' does not exist or contains no resources.
W/ResourcesManager: Asset path '/system/framework/com.android.location.provider.jar' does not exist or contains no resources.
W/art: Suspending all threads took: 5.704ms
D/ChimeraCfgMgr: Loading module com.google.android.gms.maps from APK /data/data/com.google.android.gms/app_chimera/chimera-module-root/module-fcfb08c37b9ca44c48d9936b0e1895ef8b9cffe0/MapsModule.apk
D/ChimeraModuleLdr: Loading module APK /data/data/com.google.android.gms/app_chimera/chimera-module-root/module-fcfb08c37b9ca44c48d9936b0e1895ef8b9cffe0/MapsModule.apk
D/ChimeraFileApk: Primary ABI of requesting process is armeabi-v7a
D/ChimeraFileApk: Classloading successful. Optimized code found.
I/Google Maps Android API: Google Play services client version: 7895000
I/Google Maps Android API: Google Play services package version: 8115236
I/e: Token loaded from file. Expires in: 393978062 ms.
I/e: Scheduling next attempt in 393678 seconds.
I/Choreographer: Skipped 44 frames!  The application may be doing too much work on its main thread.

This is the fragment: 这是片段:

public class StoreMapFragment extends SupportMapFragment
        implements OnMapReadyCallback {

    private GoogleMap mMap;

    public static StoreMapFragment newInstance() {
        StoreMapFragment fragment = new StoreMapFragment();
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;
        loadStores();
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setRetainInstance(true);
    }

    public void loadStores() {
        if(mMap == null)
            return;

        // Add markers
    }
}

Related: 有关:

Solved by delaying the fragment instantiation. 通过延迟片段实例化来解决。

First, I added the SupportMapFragment inside another Fragment, and then I delayed the SupportMapFragment instantiation as suggested here . 首先,我在另一个Fragment中添加了SupportMapFragment,然后按照此处的建议延迟了SupportMapFragment实例化。

StoreMapFragment.java StoreMapFragment.java

public class StoreMapFragment extends Fragment
        implements OnMapReadyCallback {

    SupportMapFragment mMapFragment;
    private GoogleMap mMap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.fragment_map, container, false);

        if (mMap == null) {
            final OnMapReadyCallback listener = this;
            new Handler().postDelayed(new Runnable() {

                @Override
                public void run() {
                    if (isAdded()) {
                        mMapFragment = new SupportMapFragment();
                        FragmentManager fm = getChildFragmentManager();
                        fm.beginTransaction()
                                .replace(R.id.map, mMapFragment).commit();
                        mMapFragment.getMapAsync(listener);
                    }
                }
            }, 1000);
        }

        return view;
    }

    @Override
    public void onMapReady(GoogleMap map) {
        mMap = map;
        loadStores();
    }
}

fragment_map.xml fragment_map.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent" />

You should get your map in onViewCreated() method: 您应该使用onViewCreated()方法获取地图:

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mMap = (SupportMapFragment) getChildFragmentManager().
            findFragmentById(R.id.map);
    mMap.getMapAsync(this);
}

This would not cause any delay in loading your map. 这不会导致加载地图的任何延迟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM