Android 应用程序正在崩溃选项卡和 Google 地图

Android App is crashing Tabs and Google Maps

我正在使用 ActionBar 选项卡,有三个选项卡,第三个选项卡有 Google 地图。 当我在第 1 和第 3 之间切换时,它崩溃,在第 1 和第 2 之间它也崩溃,但在第 2 和第 3 之间切换永远不会崩溃。我不知道为什么会这样。

代码MainActivity

package com.example.prototype;


import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.ActionBar.TabListener;
import android.app.Activity;
import android.support.v4.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.support.v4.widget.DrawerLayout;
import android.support.v4.widget.DrawerLayout.DrawerListener;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends FragmentActivity implements ActionBar.TabListener  {
    TabsPagerAdapter tabpager;
    ViewPager pager;
    DrawerLayout drawerLayout;      
    ActionBar action_bar;
    ListView navigation_list;
    @SuppressWarnings("deprecation")
    ActionBarDrawerToggle drawerToggle;
    String items[];
    String tabs_list[]={"Best Offers","Categories","Near By Places"};

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.drawer_layout);
        initComponents();
        action_bar=getActionBar();
        setNavigationList();
        setTabs();
    }

    @SuppressWarnings("deprecation")
    private void setTabs() {

        action_bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
        for (String tab_name : tabs_list) {
            action_bar.addTab(action_bar.newTab().setText(tab_name)
                    .setTabListener(this));
        }
        pager.setAdapter(tabpager);
        pager.setOnPageChangeListener(new OnPageChangeListener() {

            @Override
            public void onPageSelected(int arg0) {
                // TODO Auto-generated method stub
                action_bar.setSelectedNavigationItem(arg0);;
            }

            @Override
            public void onPageScrolled(int arg0, float arg1, int arg2) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onPageScrollStateChanged(int arg0) {
                // TODO Auto-generated method stub

            }
        });
    }

    @SuppressWarnings("deprecation")
    private void setNavigationList() {

        int open=R.string.navigation_open;
        int close=R.string.navigation_close;
        navigation_list.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items));

        drawerToggle=new ActionBarDrawerToggle(this,drawerLayout, R.drawable.ic_menu_white_18dp,open,close){


            public void onDrawerClosed(View view) {
                super.onDrawerClosed(view);
                action_bar.show();
            }

            public void onDrawerOpened(View drawerView) {
                super.onDrawerOpened(drawerView);
                action_bar.hide();

            }
        };

        drawerLayout.setDrawerListener(drawerToggle);

        action_bar.setDisplayHomeAsUpEnabled(true);
        action_bar.setHomeButtonEnabled(true);

    }

    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onPostCreate(savedInstanceState);
        drawerToggle.syncState();
    }


    private void initComponents() {
        // TODO Auto-generated method stub

        drawerLayout=(DrawerLayout) findViewById(R.id.drawer_layout);
        action_bar=getActionBar();
        navigation_list=(ListView) findViewById(R.id.left_drawer);
        items=getResources().getStringArray(R.array.navigation_drawer);
        pager=(ViewPager) findViewById(R.id.pager);    
        FragmentManager m=getSupportFragmentManager();
        tabpager=new TabsPagerAdapter(m);

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();
        if (id == R.id.action_settings) {
            return true;
        }

        if (id == R.id.search_menu) {
            Toast.makeText(getApplicationContext(), "Searched Clicked ", Toast.LENGTH_LONG).show();
            return true;
        }

        if (id == R.id.share_menu) {
            Toast.makeText(getApplicationContext(), "Share Clicked ", Toast.LENGTH_LONG).show();
            return true;
        }

        if (id == R.id.navigation_menu) {
            Toast.makeText(getApplicationContext(), "Navigation Clicked ", Toast.LENGTH_LONG).show();
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onTabSelected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub
        pager.setCurrentItem(tab.getPosition());
    }

    @Override
    public void onTabUnselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onTabReselected(Tab tab, FragmentTransaction ft) {
        // TODO Auto-generated method stub

    }

}

选项卡 1 java 代码:

public class BestOfferFragment extends Fragment{

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

        rootView = inflater.inflate(R.layout.bestoffer, container, false);

    }
}

选项卡 2 java 代码:

public class CategoriesrFragment extends Fragment{
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View rootView = inflater.inflate(R.layout.categories, container, false);

        return rootView;
    }
}

选项卡 3 java 代码:

package com.example.prototype.tabs;

import java.util.Timer;

import com.example.prototype.MainActivity;
import com.example.prototype.R;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMapOptions;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
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 android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

public class NearByPlacesFragment extends Fragment  implements OnMapReadyCallback, LocationListener {
    static int i=0;
    GoogleMap gmap;
    Marker mp;
    LatLng ll;
    Location l;
    Context ctx;
    double lat,lon;
    boolean isGpsEnabled,isNetworkAvailable,isLocationSet;
    LocationManager lmgr;
    long minTime = 1000;
    long minDistance = 1;
    Location loc;
    SupportMapFragment mapFragment;

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        ctx=getActivity();
        super.onCreateView(inflater, container, savedInstanceState);
        if(mapFragment!=null){ Toast.makeText(getActivity(), "fragment exist`", 1000).show();}
        View rootView = inflater.inflate(R.layout.nearbyplaces, container, false);
        loc=getLocation();
        if(gmap==null)
            setMap();
        Toast.makeText(getActivity(), "created`", 1000).show();   
        return rootView;

    }


    private void setMap() {
        // TODO Auto-generated method stub
     mapFragment = (SupportMapFragment) getChildFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    }


    private void setMarker() {
        // TODO Auto-generated method stub
        if(gmap!=null){
        lat=loc.getLatitude();
        lon=loc.getLongitude();
        ll=new LatLng(lat, lon);
        Toast.makeText(getActivity(), "lat"+lat, Toast.LENGTH_LONG).show();
        mp=gmap.addMarker(new MarkerOptions().position(ll).title("Your Location"));
        CameraUpdate center=CameraUpdateFactory.newLatLng(new LatLng(lat,lon));
        CameraUpdate zoom=CameraUpdateFactory.zoomTo(15);
        gmap.moveCamera(center);
        gmap.animateCamera(zoom);
        }
    }




    @Override
    public void onMapReady(GoogleMap map) {
        // TODO Auto-generated method stub

            map.getUiSettings().setAllGesturesEnabled(true);
            map.setMapType(GoogleMap.MAP_TYPE_HYBRID);
            map.setMyLocationEnabled(true);
            gmap=map;
        setMarker();
    }



    public Location getLocation(){

        lmgr=(LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);

        isGpsEnabled=lmgr.isProviderEnabled(LocationManager.GPS_PROVIDER);
        isNetworkAvailable=lmgr.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if(isGpsEnabled==true){
            setLocationManager("gps");
        }
        else if(isNetworkAvailable==true){
            setLocationManager("network");
        }

        return loc;

    }


    private boolean setLocationManager(String s){

        if(s.equals("gps")){
            Toast.makeText(getActivity(), "gps", Toast.LENGTH_LONG).show();
            lmgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, this);
            loc=lmgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);        
        }

        else{
            lmgr.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, this);
            loc=lmgr.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        }

        return isLocationSet;
    }



    @Override
    public void onLocationChanged(Location location) {

    }



    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
        // TODO Auto-generated method stub

    }



    @Override
    public void onProviderEnabled(String provider) {
        // TODO Auto-generated method stub

    }



    @Override
    public void onProviderDisabled(String provider) {
        // TODO Auto-generated method stub

    }

}

选项卡 3 xml:

<?xml version="1.0" encoding="utf-8"?>

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

    <fragment android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/map"

    android:name="com.google.android.gms.maps.SupportMapFragment" />

</RelativeLayout>

标签适配器:

package com.example.prototype;


import com.example.prototype.tabs.BestOfferFragment;
import com.example.prototype.tabs.CategoriesrFragment;
import com.example.prototype.tabs.NearByPlacesFragment;

import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class TabsPagerAdapter extends FragmentPagerAdapter {
    BestOfferFragment frag1=new BestOfferFragment();
    CategoriesrFragment frag2=new CategoriesrFragment();
    NearByPlacesFragment frag3=new NearByPlacesFragment();

    public TabsPagerAdapter(FragmentManager fm) {
        super(fm);
        // TODO Auto-generated constructor stub
    }

    Fragment f = null;
    @Override
    public Fragment getItem(int index) {

        switch (index) {
        case 0:

            f= frag1; break;

        case 1:
            f=  frag2; break;
        case 2:
            // Movies fragment activity
            f= frag3; break;
        }

        return f;
    }


    @Override
    public int getCount() {
        // TODO Auto-generated method stub
        return 3;
    }

}

这是日志:

07-11 01:49:28.877: E/NativeCrypto(7463): ssl=0x616b4438 cert_verify_callback x509_store_ctx=0x6210aab0 arg=0x0
07-11 01:49:28.882: E/NativeCrypto(7463): ssl=0x616b4438 cert_verify_callback calling verifyCertificateChain authMethod=ECDHE_ECDSA
07-11 01:49:35.046: E/AndroidRuntime(7463): FATAL EXCEPTION: main
07-11 01:49:35.046: E/AndroidRuntime(7463): android.view.InflateException: Binary XML file line #8: Error inflating class fragment
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:704)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater.rInflate(LayoutInflater.java:746)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at com.example.prototype.tabs.NearByPlacesFragment.onCreateView(NearByPlacesFragment.java:58)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.Fragment.performCreateView(Fragment.java:1789)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:955)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentManagerImpl.attachFragment(FragmentManager.java:1314)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:730)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1501)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:490)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.view.ViewPager.populate(ViewPager.java:1105)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.view.ViewPager.populate(ViewPager.java:951)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.view.ViewPager.run(ViewPager.java:250)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.Choreographer$CallbackRecord.run(Choreographer.java:776)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.Choreographer.doCallbacks(Choreographer.java:579)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.Choreographer.doFrame(Choreographer.java:547)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:762)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.os.Handler.handleCallback(Handler.java:725)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.os.Handler.dispatchMessage(Handler.java:92)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.os.Looper.loop(Looper.java:153)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.app.ActivityThread.main(ActivityThread.java:5297)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at java.lang.reflect.Method.invokeNative(Native Method)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at java.lang.reflect.Method.invoke(Method.java:511)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at dalvik.system.NativeStart.main(Native Method)
07-11 01:49:35.046: E/AndroidRuntime(7463): Caused by: java.lang.IllegalArgumentException: Binary XML file line #8: Duplicate id 0x7f08006c, tag null, or parent id 0x7f08006b with another fragment for com.google.android.gms.maps.SupportMapFragment
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.app.FragmentManagerImpl.onCreateView(FragmentManager.java:2175)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.support.v4.view.LayoutInflaterCompatHC$FactoryWrapperHC.onCreateView(LayoutInflaterCompatHC.java:44)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater$FactoryMerger.onCreateView(LayoutInflater.java:168)
07-11 01:49:35.046: E/AndroidRuntime(7463):     at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:675)
07-11 01:49:35.046: E/AndroidRuntime(7463):     ... 27 more

运行 时间 exception:when 应用程序启动的原因是它初始化了所有选项卡并再次滑动到选项卡 3,即地图选项卡,代码正在尝试创建另一个尚未创建的地图片段yet destroyed 导致非法状态异常,有两种解决方案:

解决方案 1:

    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                Bundle savedInstanceState) {
              ctx=getActivity();

              if (view != null) {
                    ViewGroup parent = (ViewGroup) view.getParent();
                    if (parent != null)
                        parent.removeView(view);
                }
                try {
                    view = inflater.inflate(R.layout.nearbyplaces, container, false);
                } catch (InflateException e) {

                }

//rest of code is same      
}

在此我们首先替换现有片段,方法是将其从父片段中删除,然后再次添加..

解决方案 2:这是最佳解决方案:

public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
          ctx=getActivity();

          if (view == null) {
    view = inflater.inflate(R.layout.nearbyplaces, container, false);
            }
//rest of code is same
            return view;


    }

确保您不会 运行 出现此错误的最佳方法是使 Fragment 扩展 SupportMapFragment 而不是在 Fragment 中嵌套一个。

我刚刚使用 ViewPagerFragmentPagerAdapter 将地图作为选项卡之一来完成这项工作。

这里是大体结构,注意不需要重写onCreateView()方法,也不需要inflate任何布局xml:

public class MyMapFragment extends SupportMapFragment implements OnMapReadyCallback {

    private GoogleMap mMap;
    private Marker marker;


    public MyMapFragment() {
    }

    @Override
    public void onResume() {
        super.onResume();

        Log.d("MyMap", "onResume");
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {

        if (mMap == null) {

            Log.d("MyMap", "setUpMapIfNeeded");

            getMapAsync(this);
        }
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        Log.d("MyMap", "onMapReady");
        mMap = googleMap;
        setUpMap();
    }

    private void setUpMap() {

        mMap.setMyLocationEnabled(true);
        mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        mMap.getUiSettings().setMapToolbarEnabled(false);


        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {

            @Override
            public void onMapClick(LatLng point) {

                Log.d("MyMap", "MapClick");

                //remove previously placed Marker
                if (marker != null) {
                    marker.remove();
                }

                //place marker where user just clicked
                marker = mMap.addMarker(new MarkerOptions().position(point).title("Marker")
                        .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)));

                Log.d("MyMap", "MapClick After Add Marker");

            }
        });

    }


}

结果: