加载第二次时Android Java Google Map错误

时间:2018-04-07 08:30:42

标签: java android

MapPage.java类

    package com.example.cheng.freequeue;
    import android.app.Fragment;
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.support.annotation.Nullable;
    import android.util.Log;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;

    import com.google.android.gms.maps.CameraUpdateFactory;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.gms.maps.MapFragment;
    import com.google.android.gms.maps.OnMapReadyCallback;
    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 org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    import java.io.BufferedReader;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.ArrayList;

    public class MapPage extends Fragment implements GoogleMap.OnMarkerClickListener,OnMapReadyCallback {
        private GoogleMap mGoogleMap;
        private String address="myphpadress";
        private InputStream is=null;
        private String lat;
        private String lng;
        private String name;
        private Marker data;
        View myView;
        ArrayList<returnLatLng> list = null;
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
            myView = inflater.inflate(R.layout.activity_map_page, container, false);
            init();
            getJSON(address);
            list = new ArrayList<returnLatLng>();
            return myView;
}
public void init()
{
    MapFragment mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
    mapFragment.getMapAsync(this);
}
/** Called when the map is ready. */
@Override
public void onMapReady(GoogleMap map) {
    mGoogleMap = map;
    mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(3.4496739,102.6010782),8.0f));



    // Set a listener for marker click.
    mGoogleMap.setOnMarkerClickListener(this);
}

/** Called when the user clicks a marker. */
@Override
public boolean onMarkerClick(final Marker marker) {

    // Retrieve the data from the marker.
    Integer clickCount = (Integer) marker.getTag();

    // Check if a click count was set, then display the click count.
    if (clickCount != null) {
        clickCount = clickCount + 1;
        marker.setTag(clickCount);
        //Toast.makeText(getActivity(), "Click!", Toast.LENGTH_SHORT).show();

    }

    // Return false to indicate that we have not consumed the event and that we wish
    // for the default behavior to occur (which is for the camera to move such that the
    // marker is centered and for the marker's info window to open, if it has one).
    return false;
}



//this method is actually fetching the json string
private void getJSON(final String urlWebService) {
    /*
    * As fetching the json string is a network operation
    * And we cannot perform a network operation in main thread
    * so we need an AsyncTask
    * The constrains defined here are
    * Void -> We are not passing anything
    * Void -> Nothing at progress update as well
    * String -> After completion it should return a string and it will be the json string
    * */
    class GetJSON extends AsyncTask<Void, Void, String> {

        //this method will be called before execution
        //you can display a progress bar or something
        //so that user can understand that he should wait
        //as network operation may take some time
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        //this method will be called after execution
        //so here we are displaying a toast with the json string
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            try {
                getLatLng(s);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        //in this method we are fetching the json string
        @Override
        protected String doInBackground(Void... voids) {

            if(android.os.Debug.isDebuggerConnected())
                android.os.Debug.waitForDebugger();

            try {

                //creating a URL
                URL url = new URL(urlWebService);

                //Opening the URL using HttpURLConnection
                HttpURLConnection con = (HttpURLConnection) url.openConnection();

                //StringBuilder object to read the string from the service
                StringBuilder sb = new StringBuilder();

                //We will use a buffered reader to read the string from service
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(con.getInputStream()));

                //A simple string to read values from each line
                String json;

                //reading until we don't find null
                while ((json = bufferedReader.readLine()) != null) {

                    //appending it to string builder
                    sb.append(json + "\n");
                }

                //finally returning the read string
                return sb.toString().trim();
            } catch (Exception e) {
                return null;
            }

        }
    }

    //creating asynctask object and executing it
    GetJSON getJSON = new GetJSON();
    getJSON.execute();
}

private  void getLatLng(String json) throws JSONException {
    //creating a json array from the json string
    JSONArray jsonArray = new JSONArray(json);

    //creating a string array for listview

    list.clear();
    //looping through all the elements in json array
    for (int i = 0; i < jsonArray.length(); i++) {

        //getting json object from the json array
        JSONObject obj = jsonArray.getJSONObject(i);

        //getting the name from the json object and putting it inside string array
        lat = obj.getString("Latitude");
        lng=obj.getString("Longitude");
        name=obj.getString("company_name");
        Log.i("lat:", lat);
        Log.i("lng:", lng);
        Log.i("lng:", name);
        list.add(new returnLatLng(lat,lng,name));
        createMarker(Double.parseDouble(lat),Double.parseDouble(lng),name);

    }




}
protected Marker createMarker(double latitude, double longitude, String title) {

    return mGoogleMap.addMarker(new MarkerOptions()
            .position(new LatLng(latitude, longitude))
            .anchor(0.5f, 0.5f)
            .title(title)
    );
}
@Override
public void onDestroyView() {
    super.onDestroyView();
    MapFragment f = (MapFragment) getFragmentManager()
            .findFragmentById(R.id.mapFragment);
    if (f != null)
        getFragmentManager().beginTransaction().remove(f).commit();
}

}

Logcat错误

    04-07 15:57:43.504 22910-22910/com.example.cheng.freequeue E/AndroidRuntime: FATAL EXCEPTION: main
 android.view.InflateException: Binary XML file line #0: Error inflating class fragment
     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:713)
     at android.view.LayoutInflater.rInflate(LayoutInflater.java:755)
     at android.view.LayoutInflater.inflate(LayoutInflater.java:492)
     at android.view.LayoutInflater.inflate(LayoutInflater.java:397)
     at com.example.cheng.freequeue.MapPage.onCreateView(MapPage.java:44)
     at android.app.Fragment.performCreateView(Fragment.java:1699)
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885)
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057)
     at android.app.BackStackRecord.run(BackStackRecord.java:682)
     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435)
     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441)
     at android.os.Handler.handleCallback(Handler.java:730)
     at android.os.Handler.dispatchMessage(Handler.java:92)
     at android.os.Looper.loop(Looper.java:137)
     at android.app.ActivityThread.main(ActivityThread.java:5166)
     at java.lang.reflect.Method.invokeNative(Native Method)
     at java.lang.reflect.Method.invoke(Method.java:525)
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745)
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561)
     at dalvik.system.NativeStart.main(Native Method)
  Caused by: java.lang.IllegalArgumentException: Binary XML file line #0: Duplicate id 0x7f080070, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
     at android.app.Activity.onCreateView(Activity.java:4811)
     at android.support.v4.app.BaseFragmentActivityApi14.onCreateView(BaseFragmentActivityApi14.java:41)
     at android.support.v4.app.FragmentActivity.onCreateView(FragmentActivity.java:67)
     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:689)
     at android.view.LayoutInflater.rInflate(LayoutInflater.java:755) 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:492) 
     at android.view.LayoutInflater.inflate(LayoutInflater.java:397) 
     at com.example.cheng.freequeue.MapPage.onCreateView(MapPage.java:44) 
     at android.app.Fragment.performCreateView(Fragment.java:1699) 
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:885) 
     at android.app.FragmentManagerImpl.moveToState(FragmentManager.java:1057) 
     at android.app.BackStackRecord.run(BackStackRecord.java:682) 
     at android.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1435) 
     at android.app.FragmentManagerImpl$1.run(FragmentManager.java:441) 
     at android.os.Handler.handleCallback(Handler.java:730) 
     at android.os.Handler.dispatchMessage(Handler.java:92) 
     at android.os.Looper.loop(Looper.java:137) 
     at android.app.ActivityThread.main(ActivityThread.java:5166) 
     at java.lang.reflect.Method.invokeNative(Native Method) 
     at java.lang.reflect.Method.invoke(Method.java:525) 
     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:745) 
     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:561) 
     at dalvik.system.NativeStart.main(Native Method) 

activity_map_page.xml

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.example.cheng.freequeue.MapPage">

        <fragment
            android:id="@+id/mapFragment"
            class="com.google.android.gms.maps.MapFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="0dp"
            android:layout_marginTop="0dp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.0"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.294" />
    </android.support.constraint.ConstraintLayout>

任何人都可以帮助我吗?我已经尝试过onDestroyView();将android:name替换为class并尝试从stackoverflow解决方案中捕获所有方法,但仍然有同样的问题。我已经运行调试我注意到了这个

    myView = inflater.inflate(R.layout.activity_map_page, container, false);

第一次单击它运行没有问题,myView将从inflate获取值。当我第二次点击运行googleMap时,虽然inflate中包含相同的值,但myView将返回null并指向此错误:

   Binary XML file line #0: Error inflating class fragment

1 个答案:

答案 0 :(得分:1)

错误是因为,您正在对其他片段内的片段进行充气。这是Nested Fragment Documentation.

将布局更改为空容器。

@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
FragmentManager fm = getChildFragmentManager();
SupportMapFragment mapFragment = (SupportMapFragment) fm.findFragmentByTag("mapFragment");
if (mapFragment == null) {
    mapFragment = new SupportMapFragment();
    FragmentTransaction ft = fm.beginTransaction();
    ft.add(R.id.mapFragmentContainer, mapFragment, "mapFragment");
    ft.commit();
    fm.executePendingTransactions();
  }
   mapFragment.getMapAsync(callback);
}

然后在Fragment onViewCreated方法中:

SALES_STAFF_POSITION_en = {'Level 1 Sales Representative', 'Level 2 Sales Representative', 'Level 3 Sales Representative'}

如果有帮助,请告诉我。