0

我很長一段時間都在試圖解決這個問題。我已經閱讀了很多有關stackoverflow和其他來源的類似問題的問題,我無法列出所有這些問題。SupportMapFragment null on SECOND load

我的問題是,因爲第一次我嘗試用地圖所有工作正常加載片段我讀過別人不同......是的第二次我嘗試訪問片段與地圖上沒有重新啓動應用程序,它崩潰空指針:

googleMap = map.getMap(); 

,因爲地圖是空:

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

您必須刪除片段在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(); 
    } 
+0

你好,謝謝你,但它無法正常工作。 我在onDestroy視圖上看到這個異常 java.lang.IllegalStateException:在android.support.v4.app.FragmentManagerImpl.checkStateLoss(FragmentManager.java:1354) at ...處onSaveInstanceState 後無法執行此操作。enqueueAction(FragmentManager.java:1372) at ... .BackStackRecord.commitInternal(BackStackRecord.java:595) at ... .commit(BackStackRecord.java:574) at ... .fragments.MyFragment.onDestroyView( MyFragment.java:183)... 然後,與之前onActivityCreated上的pb相同 – MarionaDSR 2014-12-19 15:30:24

+0

您可以提供MainActivity的onCreate()方法的源代碼嗎? – ztan 2014-12-19 17:12:41

+0

通過編輯主帖添加MainActivity的onCreate()方法的源代碼 – MarionaDSR 2014-12-30 16:20:37