在SECOND加载时SupportMapFragment为null

时间:2014-11-21 19:08:20

标签: android google-maps null navigation-drawer supportmapfragment

我很长时间都在努力解决这个问题。我已经阅读了很多关于stackoverflow和其他来源的类似问题的问题,我无法列出所有这些问题。

我的问题与我读过的其他人不同,因为第一次我尝试用地图加载片段所有工作正常 ...是在< strong>第二次我尝试使用地图访问片段而不重新启动应用程序崩溃并使用空指针:

googleMap = map.getMap();

因为map为null:

 map = (SupportMapFragment) myContext.getSupportFragmentManager().
           findFragmentById(R.id.map);

关键区别在于:

  • 第一次工作正常
  • 第二次findFragmentById返回null,但没有错误

我无法调试它,因为AVD模拟器没有安装Google Play服务。

MainActivity有一个NavigationDrawer,根据所选的选项,选择了一个片段或另一个片段。这里有一些与此问题相关的代码:

fragment_map.xml:

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

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

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

</RelativeLayout>

MyFragment.java:

...
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
...
public class MyFragment extends Fragment implements
        GooglePlayServicesClient.ConnectionCallbacks,
        GooglePlayServicesClient.OnConnectionFailedListener {

    private GoogleMap googleMap;
    private View fragmentView;
    private static WorldFragment fragment;
    private FragmentActivity myContext;
    ...

    public static MyFragment getInstance() {
        if (fragment == null) {
            fragment = new MyFragment();
        }
        return fragment;
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        myContext = (FragmentActivity) activity;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        try {
            GlobalState gs = (GlobalState) getActivity().getApplication(); 
            // recover View from previous use
            fragmentView = gs.getWorldFragmentView(); 
            if (fragmentView == null) {
                fragmentView = inflater.inflate(R.layout.fragment_map, 
                                    container, false);
                // save View for next use
                gs.setFragmentView(fragmentView); 
            } else {
                ViewGroup parent = (ViewGroup) fragmentView.getParent();
                parent.removeView(fragmentView);
            }
        } catch (InflateException e) {
            // map is already there, just return view as it is
        }
        return fragmentView;
    }

    ...

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

        // Set up the map fragment
        SupportMapFragment map = (SupportMapFragment) myContext.
             getSupportFragmentManager().findFragmentById(R.id.map);
        /*  // If I active this code, no crash, but fragment remains 
            // in gray background without map.
            // At least, if the app crashes, it restarts and the map 
            // gets loaded the first time
        if (map == null) {
            Toast.makeText(getActivity(), getString(R.string.maps_not_supported), 
                   Toast.LENGTH_LONG).show();
            return;
        } */
        googleMap = map.getMap();
        if (googleMap != null) {
            // Enable the current location "blue dot"
            googleMap.setMyLocationEnabled(true);
            ...
        } else {
            Toast.makeText(getActivity(), getString(R.string.maps_not_supported), 
                   Toast.LENGTH_LONG).show();
        }
    }

    ...
}

MainActivity.java:

public class MainActivity extends FragmentActivity implements
    NavigationDrawerFragment.NavigationDrawerCallbacks {

    @Override
    public void onNavigationDrawerItemSelected(int position) {
        Fragment contentFragment;
        switch (selectedOption) {
            case MAP:
                contentFragment = MyFragment.getInstance();
                break;
            case XXX:
                ...
                break;
            default:
                contentFragment = new OtherFragment(); 
        }
        // update the main content by replacing fragments
        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction()
                .replace(R.id.container, contentFragment)
                .commit();
    }
}

堆栈跟踪:

java.lang.NullPointerException
   at xxx.xxxxx.xxx.fragments.MyFragment.onActivityCreated(MyFragment.java:193)
   at android.support.v4.app.Fragment.performActivityCreated(Fragment.java:1508)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:958)
   at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1115)
   at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
   at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1478)
   at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:446)
   at android.os.Handler.handleCallback(Handler.java:725)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:153)
   at android.app.ActivityThread.main(ActivityThread.java:5297)
   at java.lang.reflect.Method.invokeNative(Method.java)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
   at dalvik.system.NativeStart.main(NativeStart.java)

如果您需要更多信息,请告诉我。

非常感谢你的时间和精力。

30/12/2014:MainActivity的onCreate()方法的源代码

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    GlobalState applicationContext = (GlobalState) getApplicationContext();
    applicationContext.updateLocale();

    NavigationDrawerFragment.setItems(applicationContext.getMenuItems());
    setContentView(R.layout.activity_main);

    mNavigationDrawerFragment = (NavigationDrawerFragment)
            getFragmentManager().findFragmentById(R.id.navigation_drawer);
    mTitle = getTitle();

    // Set up the drawer.
    mNavigationDrawerFragment.setUp(
            R.id.navigation_drawer,
            (DrawerLayout) findViewById(R.id.drawer_layout));

    // Treating incoming notifications
    Intent intent = getIntent();
    String action = intent.getAction();
    if (action != null && !action.isEmpty()) {
        ItemType itemType = ItemType.valueOf(action);
        String title = applicationContext.getMenuItemByType(itemType).getTitle();
        String itemId = null;
        try {
            JSONObject json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
            itemId = json.getString(EXTRA_ITEM_ID);
        } catch (JSONException e) {
            Crashlytics.logException(e);
        }
        launchFragment(itemType, null, title, itemId);
    }
}

1 个答案:

答案 0 :(得分:1)

您必须删除MyFragment类的onDestroyView()方法中的片段。

要删除的示例代码:

@Override
   public void onDestroyView() {
       SupportMapFragment f = (SupportMapFragment)myContext.getSupportFragmentManager().findFragmentById(R.id.map);

       if (f != null) {
           try {
               myContext.getSupportFragmentManager().beginTransaction().remove(f).commit();
           }
           catch (Exception e) {
               e.printStackTrace();
           }
       }
       super.onDestroyView();
   }