Android Google地图在某些设备上崩溃

时间:2017-07-05 09:09:07

标签: android api google-maps

有时,在使用Google Maps v2 API时,某些设备中的应用会崩溃,但以下情况除外:

Fatal Exception: android.view.InflateException: Binary XML file line #10: Binary XML file line #10: Error inflating class fragment
       at android.view.LayoutInflater.inflate(LayoutInflater.java:543)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
       at com.makovsky.geo.ui.screens.map.MapFragment.onCreateView(MapFragment.java:75)
       at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
       at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
       at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
       at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
       at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
       at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5441)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
Caused by android.view.InflateException: Binary XML file line #10: Error inflating class fragment
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:786)
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:708)
       at android.view.LayoutInflater.rInflate(LayoutInflater.java:839)
       at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:802)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:519)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
       at com.makovsky.geo.ui.screens.map.MapFragment.onCreateView(MapFragment.java:75)
       at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
       at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
       at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
       at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
       at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
       at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5441)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)
Caused by java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources com.google.maps.api.android.lib6.impl.aq.e()' on a null object reference
       at com.google.maps.api.android.lib6.gmm6.vector.ah.getResources(:com.google.android.gms.DynamiteModulesB:340)
       at android.util.ResolutionOverride.<init>(ResolutionOverride.java:56)
       at android.view.SurfaceView.init(SurfaceView.java:207)
       at android.view.SurfaceView.<init>(SurfaceView.java:187)
       at com.google.maps.api.android.lib6.gmm6.vector.am.<init>(:com.google.android.gms.DynamiteModulesB:1)
       at com.google.maps.api.android.lib6.gmm6.vector.ah.<init>(:com.google.android.gms.DynamiteModulesB:3)
       at com.google.maps.api.android.lib6.gmm6.api.am.<init>(:com.google.android.gms.DynamiteModulesB:53)
       at com.google.maps.api.android.lib6.gmm6.api.am.a(:com.google.android.gms.DynamiteModulesB:49)
       at com.google.android.gms.maps.internal.bv.a(:com.google.android.gms.DynamiteModulesB:38)
       at com.google.maps.api.android.lib6.impl.az.a(:com.google.android.gms.DynamiteModulesB:80)
       at com.google.maps.api.android.lib6.impl.az.a(:com.google.android.gms.DynamiteModulesB:1)
       at com.google.maps.api.android.lib6.impl.cl.a(:com.google.android.gms.DynamiteModulesB:24)
       at com.google.android.gms.maps.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:58)
       at android.os.Binder.transact(Binder.java:387)
       at com.google.android.gms.maps.internal.IMapFragmentDelegate$zza$zza.onCreateView(Unknown Source)
       at com.google.android.gms.maps.SupportMapFragment$zza.onCreateView(Unknown Source)
       at com.google.android.gms.dynamic.zza$4.zzb(Unknown Source)
       at com.google.android.gms.dynamic.zza.zza(Unknown Source)
       at com.google.android.gms.dynamic.zza.onCreateView(Unknown Source)
       at com.google.android.gms.maps.SupportMapFragment.onCreateView(Unknown Source)
       at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1255)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1472)
       at android.support.v4.app.FragmentManagerImpl.addFragment(FragmentManager.java:1691)
       at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:3440)
       at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:47)
       at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:186)
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:750)
       at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:708)
       at android.view.LayoutInflater.rInflate(LayoutInflater.java:839)
       at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:802)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:519)
       at android.view.LayoutInflater.inflate(LayoutInflater.java:427)
       at com.makovsky.geo.ui.screens.map.MapFragment.onCreateView(MapFragment.java:75)
       at android.support.v4.app.Fragment.performCreateView(Fragment.java:2192)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1299)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
       at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
       at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
       at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
       at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
       at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:148)
       at android.app.ActivityThread.main(ActivityThread.java:5441)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)

Fatal Exception: java.lang.NullPointerException: Attempt to invoke interface method 'void com.google.maps.api.android.lib6.impl.bn.v()' on a null object reference
       at com.google.maps.api.android.lib6.impl.cl.i(:com.google.android.gms.DynamiteModulesB:44)
       at com.google.android.gms.maps.internal.q.onTransact(:com.google.android.gms.DynamiteModulesB:122)
       at android.os.Binder.transact(Binder.java:387)
       at com.google.android.gms.internal.zzed.zzb(Unknown Source)
       at com.google.android.gms.maps.internal.zzj.onStart(Unknown Source)
       at com.google.android.gms.maps.SupportMapFragment$zza.onStart(Unknown Source)
       at com.google.android.gms.dynamic.zzg.zzb(Unknown Source)
       at com.google.android.gms.dynamic.zza.zza(Unknown Source)
       at com.google.android.gms.dynamic.zza.onStart(Unknown Source)
       at com.google.android.gms.maps.SupportMapFragment.onStart(Unknown Source)
       at android.support.v4.app.Fragment.performStart(Fragment.java:2218)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1340)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
       at android.support.v4.app.FragmentManagerImpl.dispatchStart(FragmentManager.java:2907)
       at android.support.v4.app.Fragment.performStart(Fragment.java:2224)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1340)
       at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1528)
       at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1595)
       at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:758)
       at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2363)
       at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2149)
       at android.support.v4.app.FragmentManagerImpl.optimizeAndExecuteOps(FragmentManager.java:2103)
       at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2013)
       at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:710)
       at android.os.Handler.handleCallback(Handler.java:742)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:154)
       at android.app.ActivityThread.main(ActivityThread.java:5523)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:739)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:629)

在大多数设备中,一切正常,但在某些设备中会发生这种崩溃。我看到了一些类似的主题,我不知道确定这是mu代码有问题还是Google Maps API的错误。我在v4.Fragment中使用Google Maps API。

XML代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <include layout="@layout/toolbar_default"/>

    <fragment
        android:id="@+id/mapFragmentMapView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.google.android.gms.maps.SupportMapFragment" />

</LinearLayout>

Java代码

public class GlobalMapFragment extends MVPFragment<MapPresenter> implements MapView,
        OnMapReadyCallback,
        GoogleMap.OnCameraMoveStartedListener {

    @Inject
    MapPresenter mapPresenter;

    @BindView(R.id.default_toolbar)
    Toolbar vToolbar;
    @BindView(R.id.default_toolbar_title)
    TextView vToolbarTitle;

    private SupportMapFragment vMapFragment;
    private GoogleMap googleMap;
    private ClusterManager<BaseMarker> clusterManager;
    private MarkerCustomRenderer markerCustomRenderer;
    private MaterialDialog materialDialog;
    private Map<String, BaseMarker> markers = new HashMap<>();

    public static final int ACCESS_LOCATION_PERMISSION_REQUEST_CODE = 10823;

    public static GlobalMapFragment newInstance() {
        return new GlobalMapFragment();
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setupDagger();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        try {
            /* View inflating */
            View view = inflater.inflate(R.layout.fragment_map, container, false);
            ButterKnife.bind(this, view);

            /* Toolbar setup */
            vToolbarTitle.setText(getString(R.string.drawer_menu_item_map));
            setupToolbar(vToolbar, null, R.drawable.ic_menu, v -> getPresenter().onHomeButtonClicked());

            /* Views initializing */
            vMapFragment = (SupportMapFragment) getChildFragmentManager()
                    .findFragmentById(R.id.mapFragmentMapView);

            return view;

        } catch (Exception e) {
            View errorView = inflater.inflate(R.layout.fragment_critical_error, container, false);
            ButterKnife.bind(this, errorView);

            vToolbarTitle.setText(getString(R.string.drawer_menu_item_map));
            setupToolbar(vToolbar, null, R.drawable.ic_menu, v -> getPresenter().onHomeButtonClicked());

            TextView errorTextView = ButterKnife.findById(
                    errorView, R.id.errorTextView);
            errorTextView.setText(
                    getString(R.string.map_api_error_text));

            return errorView;
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        attachMVP();
    }

    @Override
    public void onStop() {
        super.onStop();
        detachMVP();
    }

    @Override
    public void requestLocationPermissions() {
        PermissionsUtils.requestPermissions(
                getBaseActivity(),
                ACCESS_LOCATION_PERMISSION_REQUEST_CODE,
                PermissionsUtils.LOCATION_PERMISSION);
    }

    @Override
    public void getMap() {
        if (vMapFragment != null) {
            vMapFragment.getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        if (this.googleMap != null) {
            return;
        }

        if (PermissionsUtils.isPermissionsGranted(
                getBaseActivity().getApplicationContext(),
                PermissionsUtils.LOCATION_PERMISSION)) {
            this.googleMap = googleMap;
            this.googleMap.getUiSettings().setCompassEnabled(true);
            this.googleMap.getUiSettings().setMyLocationButtonEnabled(true);
            this.googleMap.getUiSettings().setZoomControlsEnabled(true);
            this.googleMap.getUiSettings().setAllGesturesEnabled(true);
            this.googleMap.setMyLocationEnabled(true);
        }

        this.clusterManager = new ClusterManager<>(
                getBaseActivity(), this.googleMap);
        this.clusterManager.setOnClusterClickListener(cluster -> {
            googleMap.animateCamera(
                    CameraUpdateFactory.newLatLngZoom(
                            cluster.getPosition(),
                            (float) Math.floor(googleMap.getCameraPosition().zoom + 1)),
                    300, null);

            return true;
        });
        this.clusterManager.setOnClusterItemClickListener(baseMarker -> {
            for (Map.Entry<String, BaseMarker> entry : markers.entrySet()) {
                if (!entry.getValue().equals(baseMarker)) {
                    continue;
                }

                getPresenter().onMarkerClicked(
                        entry.getKey(),
                        baseMarker.getPosition().latitude,
                        baseMarker.getPosition().longitude);
            }

            return false;
        });

        this.markerCustomRenderer = new MarkerCustomRenderer(
                getBaseActivity(), this.googleMap, this.clusterManager);
        this.clusterManager.setRenderer(this.markerCustomRenderer);

        this.googleMap.setOnCameraIdleListener(this.clusterManager);
        this.googleMap.setOnMarkerClickListener(this.clusterManager);

        getPresenter().onMapReady();
    }

    @Override
    public void onCameraMoveStarted(int reason) {
        if (reason == GoogleMap.OnCameraMoveStartedListener.REASON_GESTURE) {
            getPresenter().onMapGestured(googleMap.getCameraPosition().zoom);
        }
    }

    @Override
    public void setTradersMarkers(List<BaseTraderDvo> traders) {
        new MarkersTask(clusterManager, markers, traders)
                .execute();
    }

    @Override
    public void moveCameraToLocation(double lat, double lng, float zoom) {
        LatLng coordinates = new LatLng(lat, lng);
        googleMap.moveCamera(
                CameraUpdateFactory.newLatLngZoom(
                        coordinates, zoom));
    }

    @Override
    public void showTraderInfoView(TraderInfoDvo trader) {
        dismissMaterialDialog();

        View dialogView = LayoutInflater
                .from(getBaseActivity())
                .inflate(R.layout.dialog_view_trader_info, null, false);

        TextView nameTextView = ButterKnife.findById(
                dialogView,
                R.id.traderInfoDialogNameTextView);
        TextView addressTextView = ButterKnife.findById(
                dialogView,
                R.id.traderInfoDialogAddressTextView);
        ImageView avatarImageView = ButterKnife.findById(
                dialogView,
                R.id.traderInfoDialogAvatarImageView);
        TextView aboutTextView = ButterKnife.findById(
                dialogView,
                R.id.traderInfoDialogAboutTextView);
        TextView amountTextView = ButterKnife.findById(
                dialogView,
                R.id.traderInfoDialogAmountTextView);

        nameTextView.setText(
                trader.getUsername());

        try {
            double lat;
            double lng;

            lat = Double.parseDouble(
                    trader.getLocation().getLatitude());
            lng = Double.parseDouble(
                    trader.getLocation().getLongitude());

            String address = GeocoderHelper.getAddressFromCoordinates(
                    getBaseActivity().getApplicationContext(),
                    lat, lng);

            if (!StringUtils.isNullEmpty(address)) {
                addressTextView.setText(address);
                addressTextView.setVisibility(View.VISIBLE);

            } else {
                addressTextView.setVisibility(View.GONE);
            }

        } catch (Exception e) {
            addressTextView.setVisibility(View.GONE);
        }

        PicassoLoader.load(
                avatarImageView,
                trader.getAvatarUrl());

        if (!StringUtils.isNullEmpty(trader.getDescription())) {
            aboutTextView.setText(trader.getDescription());
            aboutTextView.setVisibility(View.VISIBLE);

        } else {
            aboutTextView.setVisibility(View.GONE);
        }

        amountTextView.setText(
                trader.getMaxTransactionAmount() +
                        " " + getString(R.string.uah_text));

        materialDialog = new MaterialDialog.Builder(getBaseActivity())
                .customView(dialogView, false)
                .positiveText(getString(R.string.close_dialog_text))
                .negativeText(getString(R.string.map_show_profile_text))
                .onNegative((dialog, which) ->
                        UserProfileActivity.start(
                                getBaseActivity(), trader.getHashId()))
                .show();
    }

    @Override
    public void showProgressDialog(String title, String message) {
        dismissMaterialDialog();

        materialDialog = new MaterialDialog.Builder(getBaseActivity())
                .title(title)
                .content(message)
                .widgetColorRes(R.color.material_indigo_600)
                .progress(true, 0)
                .cancelable(false)
                .show();
    }

    @Override
    public void showAlertDialog(String title, String message) {
        dismissMaterialDialog();

        materialDialog = new MaterialDialog.Builder(getBaseActivity())
                .title(title)
                .content(message)
                .positiveText(getString(R.string.close_dialog_text))
                .widgetColorRes(R.color.material_indigo_600)
                .show();
    }

    @Override
    public void dismissMaterialDialog() {
        if (materialDialog != null && materialDialog.isShowing()) {
            materialDialog.dismiss();
        }
    }

    private void setupDagger() {
        App.getApp(getBaseActivity())
                .getAppComponent()
                .plus(new MapComponent.Module())
                .inject(this);
    }

    private void attachMVP() {
        if (getPresenter() == null) {
            attachPresenter(mapPresenter);
        }

        if (getPresenter() != null) {
            if (getPresenter().getView() == null) {
                getPresenter().attachView(this);
            }
        }
    }

    private void detachMVP() {
        if (getPresenter() != null) {
            getPresenter().detachView();
        }
    }

    private class MarkersTask extends AsyncTask<Void, Void, Void> {

        private ClusterManager<BaseMarker> clusterManager;
        private Map<String, BaseMarker> markers;
        private List<BaseTraderDvo> traders;

        public MarkersTask(ClusterManager<BaseMarker> clusterManager,
                           Map<String, BaseMarker> markers, List<BaseTraderDvo> traders) {
            this.clusterManager = clusterManager;
            this.markers = markers;
            this.traders = traders;
        }

        @Override
        protected Void doInBackground(Void... params) {
            for (BaseTraderDvo trader : traders) {

                double lat;
                double lng;
                try {
                    lat = Double.parseDouble(
                            trader.getLocation().getLatitude());
                    lng = Double.parseDouble(
                            trader.getLocation().getLongitude());

                } catch (Exception e) {
                    Crashlytics.logException(e);
                    continue;
                }

                try {
                    if (trader == null) {
                        continue;
                    }

                    if (getBaseActivity() == null || getBaseActivity().getApplicationContext() == null) {
                        break;
                    }

                    Bitmap markerBitmap = BitmapHelper.mapMarkerFromLayout(
                            getBaseActivity().getApplicationContext(),
                            trader.getAvatarUrl());
                    BitmapDescriptor markerIcon = BitmapDescriptorFactory
                            .fromBitmap(markerBitmap);
                    TraderMarker marker = new TraderMarker(lat, lng)
                            .setIcon(markerIcon);

                    markers.put(
                            trader.getHashId(), marker);

                } catch (Exception e) {
                    Crashlytics.logException(e);
                }
            }

            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            for (Map.Entry<String, BaseMarker> entry : markers.entrySet()) {
                clusterManager.addItem(
                        entry.getValue());
            }

            clusterManager.cluster();
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我遇到了完全相同的问题。在我的情况下,这恰好发生在Android 6.0设备上。

我在 AndroidManifest.xml

中添加android:hardwareAccelerated="true"application标记解决了