Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment

Posted

技术标签:

【中文标题】Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment【英文标题】: 【发布时间】:2014-01-22 00:45:53 【问题描述】:

我正在使用NavigationDrawerDrawerLayout 开发应用程序并导航到不同的Fragments。当我调用Map_Fragment_Page 时,应用程序崩溃了,但不是第一次。它第一次正确显示Map,但之后当我导航不同的片段并再次来到Map_Fragment_Page 然后它崩溃并给出错误android.view.InflateException: Binary XML file line #8: Error inflating class fragment

我尝试了很多不同的解决方案,也搜索了Google,但仍然没有得到所需的解决方案。问题还没有解决。

howtoreach.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_>

    <fragment
        android:id="@+id/howtoreach_map"
        android:layout_
        android:layout_
        class="com.google.android.gms.maps.SupportMapFragment"/>

</RelativeLayout>

HowToReach.java

    package com.demo.map.howtoreach;

import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import android.support.v4.app.Fragment;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.maps.model.Polyline;
import com.google.android.gms.maps.model.PolylineOptions;
import com.demo.map.R;

import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Color;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.Handler;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class HowToReach extends Fragment

    public static final String TAG = "fragment_5";
    ProgressDialog dialog;

    GoogleMap googleMap;
    Marker marker;

    LocationManager locationManager;
    Location location;
    Criteria criteria;               
    String provider;

    double latitude, longitude;

    public HowToReach()

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

        final View v = inflater.inflate(R.layout.howtoreach, container, false);

        dialog = ProgressDialog.show(getActivity(),"","Loading",true,false);            

        int secondsDelayed = 4;
        new Handler().postDelayed(new Runnable()
                
                    public void run()
                       
            dialog.dismiss();
        
        , secondsDelayed * 1000);      

        try
        
            // Loading map                  

            if (googleMap == null)
            
                googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap();

                googleMap.setMyLocationEnabled(true);

                locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);              
                criteria = new Criteria();               
                provider = locationManager.getBestProvider(criteria, true); 
                location = locationManager.getLastKnownLocation(provider);

                latitude = location.getLatitude();
                longitude = location.getLongitude();

                // create marker
                marker = googleMap.addMarker(new MarkerOptions().position(
                            new LatLng(latitude, longitude)).title("You are Here"));                  
                marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
                marker.showInfoWindow(); 

                CameraPosition cameraPosition = new CameraPosition.Builder().target(
                        new LatLng(latitude, longitude)).zoom(15).build();

                googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));                         

                Polyline line = googleMap.addPolyline(new PolylineOptions()
                        .add(new LatLng(latitude, longitude), new LatLng(18.520897,73.772396))
                        .width(2).color(Color.RED).geodesic(true));

                marker = googleMap.addMarker(new MarkerOptions().position(
                            new LatLng(18.520897, 73.772396)).title("DSK Ranwara Road"));             
                marker.setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));

                // check if map is created successfully or not
                if (googleMap == null)
                
                    Toast.makeText(getActivity(),"Sorry! unable to create maps", Toast.LENGTH_SHORT).show();
                
            

        
        catch (Exception e)
        
            e.printStackTrace();
        

        return v;

    

【问题讨论】:

你在哪个版本上测试? 操作系统版本还是地图版本? 4.0.4 冰淇淋三明治。三星 S DUOS .. 我想这不是问题.. 因为地图是第一次加载,当我在导航其他片段后返回地图页面时,它会崩溃...... 你调试过你的代码吗???尝试在 onResume 方法中编写 // 加载地图代码。 是的..仍然无法正常工作.. :( 【参考方案1】:
Yes.. I want Map inside a Fragment.

你应该使用MapView

http://developer.android.com/reference/com/google/android/gms/maps/MapView.html

public class HowToReach  extends Fragment 
    MapView mapView;
    GoogleMap map;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) 
        View v = inflater.inflate(R.layout.fragment2, container, false);
        // Gets the MapView from the XML layout and creates it

        try 
            MapsInitializer.initialize(getActivity());
         catch (GooglePlayServicesNotAvailableException e) 
            Log.e("Address Map", "Could not initialize google play", e);
        

        switch (GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()) )
        
            case ConnectionResult.SUCCESS:
                Toast.makeText(getActivity(), "SUCCESS", Toast.LENGTH_SHORT).show();
                mapView = (MapView) v.findViewById(R.id.map);
                mapView.onCreate(savedInstanceState);
                // Gets to GoogleMap from the MapView and does initialization stuff
                if(mapView!=null)
                
                    map = mapView.getMap();
                    map.getUiSettings().setMyLocationButtonEnabled(false);
                    map.setMyLocationEnabled(true);
                    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
                    map.animateCamera(cameraUpdate);
                
                break;
            case ConnectionResult.SERVICE_MISSING: 
                Toast.makeText(getActivity(), "SERVICE MISSING", Toast.LENGTH_SHORT).show();
                break;
            case ConnectionResult.SERVICE_VERSION_UPDATE_REQUIRED: 
                Toast.makeText(getActivity(), "UPDATE REQUIRED", Toast.LENGTH_SHORT).show();
                break;
            default: Toast.makeText(getActivity(), GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity()), Toast.LENGTH_SHORT).show();
        




        // Updates the location and zoom of the MapView

        return v;
    

    @Override
    public void onResume() 
        mapView.onResume();
        super.onResume();
    
    @Override
    public void onDestroy() 
        super.onDestroy();
        mapView.onDestroy();
    
    @Override
    public void onLowMemory() 
        super.onLowMemory();
        mapView.onLowMemory();
    

fragment2.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_>

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

</RelativeLayout>

更新:

https://developers.google.com/android/reference/com/google/android/gms/maps/MapView#public-constructors

getMap() 已弃用。请改用getMapAsync(OnMapReadyCallback)。回调方法为您提供了一个保证为非空且可供使用的 GoogleMap 实例。

【讨论】:

在线错误:: mapView.onCreate(savedInstanceState); @Mitesh 我不是你的调试器。调试代码。但这是这样做的方式。休息由你来修改。 mapView 为空。它没有正确初始化 解决了......谢谢......实际上你是对的......但我很紧张......并且正在进行现场项目,所以正在寻求你的帮助...... :) @Raghunandan 加载地图需要花费大量时间。您是否遇到过此类问题?【参考方案2】:

所以如果它在第二次打开片段后崩溃。 在 OnDestroy 中你需要的就是这个

@Override
public void onDestroy() 
    super.onDestroy();
    getFragmentManager().beginTransaction().remove(mapfragmentnamehere).commit();

如果您正在使用支持片段,请进行您需要的更改

【讨论】:

它在删除方法上给出错误,因为它不能转换为 mapfragment。 这解决了我的问题,谢谢先生!代码 onDestroy: MapFragment mapFragment = (MapFragment)getFragmentManager().findFragmentById(R.id.map); getFragmentManager().beginTransaction().remove(mapFragment).commit();【参考方案3】:

我使用 xml-tag 添加的片段的经验

<fragment>...</fragment>.

这些片段通常是嵌套的,并且不会在父片段被销毁时销毁。一旦你尝试再次给它们充气,你就会得到一个基本上抱怨这个片段已经充气的异常。 因此,一旦父片段被破坏,我就会手动破坏我的嵌套片段。只需使用以下剪辑并根据您的需要进行调整。此代码驻留在以 xml-tag 形式嵌套片段的父片段中。

@Override
public void onDestroy() 
    super.onDestroy();
    final FragmentManager fragManager = this.getFragmentManager();
    final Fragment fragment = fragManager.findFragmentById(/*id of fragment*/);
    if(fragment!=null)
        fragManager.beginTransaction().remove(fragment).commit();
    

使用动态创建的片段完全没有问题。动态意味着:你没有使用 fragment-xml-tag

希望这会有所帮助!好编程!

【讨论】:

【参考方案4】:

我把它放在我的片段中

@Override
public void onPause() 
    super.onPause();

    getChildFragmentManager().beginTransaction()
            .remove(mMapFragment)
            .commit();

它可以在不替换 MapView 的情况下工作。

【讨论】:

【参考方案5】:

改一下

googleMap = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap();

googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.howtoreach_map)).getMap();

【讨论】:

为此,我需要扩展 FragmentActivity 而不是 Fragment。我不能使用 FragmentActivity,因为我从上一页调用这个 Fragment。 @Mitesh 您希望您的应用程序运行什么 api 级别。清单中的 min sdk 是什么?承载片段的活动必须扩展 FragmentActivity @Raghunandan 没有明白你的意思。在记录的地方,您可以发布链接。如果可能的话,为Fragment 提供一个很好的教程,谢谢:-) @user3110424 如果你的最小 sdk 是 11,你使用 SupportMapFragment 在这种情况下你的活动扩展了 FragmentActivity。您可以查看片段文档以及如何使用低于 api 级别 11 的片段 @Raghunandan 我的 minSDKVersion 是 14,我之前的课程是扩展 FragmentActivity,我从那个课程中调用 MapFragment..【参考方案6】:

在你的课堂上


    View mTrackView = inflater.inflate(R.layout.mylayout, container, false);
    SupportMapFragment mSupportMapFragment = SupportMapFragment.newInstance();
    FragmentTransaction fragmentTransaction = getChildFragmentManager().beginTransaction();
    fragmentTransaction.add(R.id.mapwhere, mSupportMapFragment);
    fragmentTransaction.commit();

    if(mSupportMapFragment!=null)

        googleMap = mSupportMapFragment.getMap();
        if(googleMap!=null)
        googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
        googleMap.getUiSettings().setMyLocationButtonEnabled(false);
        googleMap.setMyLocationEnabled(false);
        if (mgpr_tracker.canGetLocation())
            CURREN_POSITION = new LatLng(mgpr_tracker.getLatitude(),
                    mgpr_tracker.getLongitude());

        CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
                CURREN_POSITION, ZOOM_LEVEL);
        googleMap.animateCamera(cameraUpdate);
          
        

mylayout.xml


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:layout_
    android:layout_
    android:gravity="center"
    android:orientation="vertical" >
 <FrameLayout
   android:layout_
   android:layout_
   android:layout_weight="1.03"

   android:id="@+id/mapwhere" />


  <TextView
   android:layout_
   android:layout_/>

</LinearLayout>

【讨论】:

getChildFragmentManager() 无法解析到 type ,还升级 api 到 17.. wts 解决方案?【参考方案7】:

正如您第一次告诉您的代码正在运行,所以我认为当您再次调用您的地图时,您的 googlemap 对象不是 null 并且您没有正确处理它尝试在您的代码中像这样实现

if (googleMap == null) 
// Your code 
 else if(googleMap != null) 
     marker = googleMap.addMarker(new MarkerOptions().position(new LatLng(18.520897, 73.772396)).title("DSK Ranwara Road"));

【讨论】:

不......同样的错误......在java文件的第52行......即final View v = inflater.inflate(R.layout.howtoreach, container, false); ***.com/questions/14825331/… 请参考这个.... 对不起,哥们...没有解决方案..地图第一次加载,然后它就崩溃了..您给出的解决方案是“当地图第一次崩溃时”。 你的 Fragment 中有没有使用构造函数????请密切关注我提供的链接。【参考方案8】:

检查您是否拥有确切的清单权限。我没有在清单中包含以下权限,它给出了这个错误。

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

请在您的清单文件中包含以下一些权限

<!-- - THIS IS THE USER PERMISSION FOR GETTING LATITUDE AND LONGTITUDE FROM INTERNET -->      
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" /> 
 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
 <uses-permission android:name="android.permission.GET_ACCOUNTS" /> 
 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 <uses-permission android:name="android.permission.UPDATE_DEVICE_STATS"/>
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

【讨论】:

【参考方案9】:

当我有一个 viewpager 时,我把它放在我的片段中:

@Override
public void onPause() 
    Fragment fragment = (getChildFragmentManager().findFragmentById(R.id.fragment_map_map));
    FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
    ft.remove(fragment);
    ft.commit();
    super.onPause();

【讨论】:

【参考方案10】:

要使 Google API v2 正常工作(我也在使用 SupportMapFragment),您必须包含这些权限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-feature android:glEsVersion="0x00020000" android:required="true"/>

希望对大家有所帮助。

P.S 我使用这些权限在我的应用程序中添加了一个简单的地图。 this link 还建议了某些其他权限。

【讨论】:

【参考方案11】:

我得到了同样的错误信息:

对我来说原因很简单:重新创建视图

public View onCreateView(
        LayoutInflater inflater,
        ViewGroup container,
        Bundle savedInstanceState)
    super.onCreateView(inflater,container,savedInstanceState);
    self_view=inflater.inflate(R.layout.fragment_player,container,false);
    return self_view;
    

onCreateView 可能会被多次调用。

当这种情况发生时,上面的代码会为片段创建一个新视图,而旧视图仍然存在。

某些适配器会弹出错误,而另一个则不会;在我的例子中,FragmentStatePagerAdapter 很高兴,而 FragmentPagerAdapter 很杀气,因为前者破坏了它的碎片,而后者又重用了它们。

【讨论】:

【参考方案12】:

我如何在搜索后解决我的问题,将这些行放在片段 onPause 方法中。

@Override
public void onPause() 
    super.onPause();

    final FragmentManager fragManager = this.getChildFragmentManager();
    final Fragment fragment = fragManager.findFragmentById(R.id.map);
    if(fragment!=null)
        fragManager.beginTransaction().remove(fragment).commit();
        googleMap=null;
    

必须将 googlemap 设为空。 不用MapView,不用MapView也可以

【讨论】:

以上是关于Android - android.view.InflateException: Binary XML file line #8: Error inflating class fragment的主要内容,如果未能解决你的问题,请参考以下文章

Android逆向系列文章— Android基础逆向

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

Android 逆向Android 权限 ( Android 逆向中使用的 android.permission 权限 | Android 系统中的 Linux 用户权限 )

android 21 是啥版本

Android逆向-Android基础逆向(2-2)

【Android笔记】android Toast