我很长时间都在努力解决这个问题。我已经阅读了很多关于stackoverflow和其他来源的类似问题的问题,我无法列出所有这些问题。
我的问题与我读过的其他人不同,因为第一次我尝试用地图加载片段所有工作正常 ...是在< strong>第二次我尝试使用地图访问片段而不重新启动应用程序崩溃并使用空指针:
googleMap = map.getMap();
因为map为null:
map = (SupportMapFragment) myContext.getSupportFragmentManager().
findFragmentById(R.id.map);
关键区别在于:
我无法调试它,因为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);
}
}
答案 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();
}