我在android活动中有一个BottomNavigationView,它由4个menuItems组成。当我有时在这些片段之间导航时,应用程序崩溃并出现空指针异常。在我的AppCentes诊断部分中,它说崩溃是在FragmentManager内部发生的。唯一的例外是在空对象上有一个getClass()方法调用。谁能指出造成这种现象的原因吗?附加崩溃日志。
下面介绍了用于切换片段的代码。
private void BottomNavigationItemSelected(object obj, BottomNavigationView.NavigationItemSelectedEventArgs args)
{
string title = "";
if (args.Item.ItemId == Resource.Id.menu_explore)
{
title = Resources.GetString(Resource.String.shelf_title);
fragment = _exploreFragment;
_fragmentTag = "Home";
}
else
{
title = args.Item.TitleFormatted.ToString();
}
if (args.Item.ItemId == Resource.Id.menu_dashboard)
{
fragment = _redesignDashboard;
_fragmentTag = "Dashboard";
}
else if (args.Item.ItemId == Resource.Id.menu_more)
{
fragment = _moreFragment;
_fragmentTag = "More";
}
else if (args.Item.ItemId == Resource.Id.menu_report)
{
fragment = _reportFragment;
_fragmentTag = "Report";
}
else if (args.Item.ItemId == Resource.Id.menu_downloads)
{
fragment = _downloadGalleryFragment;
_fragmentTag = "Downloads";
}
if (fragment != null)
{
_toolbarTitle.Text = title;
ToggleTitle(true);
SupportFragmentManager.BeginTransaction().SetCustomAnimations(Resource.Animation.fab_slide_in_from_right, Resource.Animation.fab_slide_out_to_left).Replace(Resource.Id.content_frame, fragment, _fragmentTag).Commit();
}
}
StackTrace用于MS AppCenter中的相同操作
JniEnvironment+InstanceMethods.CallObjectMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args)
JNIEnv.CallObjectMethod (System.IntPtr jobject, System.IntPtr jmethod, Android.Runtime.JValue* parms)
FragmentTransactionInvoker.Replace (System.Int32 containerViewId, Android.Support.V4.App.Fragment fragment, System.String tag)
BookshelfActivity.BottomNavigationItemSelected (System.Object obj, Android.Support.Design.Widget.BottomNavigationView+NavigationItemSelectedEventArgs args)
BottomNavigationView+IOnNavigationItemSelectedListenerImplementor.OnNavigationItemSelected (Android.Views.IMenuItem item)
BottomNavigationView+IOnNavigationItemSelectedListenerInvoker.n_OnNavigationItemSelected_Landroid_view_MenuItem_ (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_item)
(wrapper dynamic-method) System.Object.26(intptr,intptr,intptr)
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference
android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:392)
android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:439)
mono.android.support.design.widget.BottomNavigationView_OnNavigationItemSelectedListenerImplementor.n_onNavigationItemSelected(Native Method)
mono.android.support.design.widget.BottomNavigationView_OnNavigationItemSelectedListenerImplementor.onNavigationItemSelected(BottomNavigationView_OnNavigationItemSelectedListenerImplementor.java:30)
android.support.design.widget.BottomNavigationView$1.onMenuItemSelected(BottomNavigationView.java:182)
android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
android.support.design.internal.BottomNavigationMenuView$1.onClick(BottomNavigationMenuView.java:95)
android.view.View.performClick(View.java:6935)
android.view.View$PerformClick.run(View.java:26211)
android.os.Handler.handleCallback(Handler.java:790)
android.os.Handler.dispatchMessage(Handler.java:99)
android.os.Looper.loop(Looper.java:164)
android.app.ActivityThread.main(ActivityThread.java:7000)
java.lang.reflect.Method.invoke(Native Method)
com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:441)
com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1408)
答案 0 :(得分:0)
我怀疑您的碎片正在被Android垃圾收集,这导致了此问题。
您不应持有对片段的引用以切换标签。 FragmentManager具有内置的缓存机制,您可以利用该机制。
您已经在标记片段。您可以使用它来在片段管理器中查找缓存的片段,如果它为null,则创建一个新的片段:
var cachedFragment = SupportFragmentManager.FindFragmentByTag(fragmentTag);
if (cachedFragment == null){
cachedFragment = new MyFragment(); //or whatever fragment you are trying to show
}
SupportFragmentManager
.BeginTransaction()
.SetCustomAnimations(Resource.Animation.fab_slide_in_from_right, Resource.Animation.fab_slide_out_to_left)
.Replace(Resource.Id.content_frame, cachedFragment, fragmentTag)
.AddToBackStack(null) //this caches the fragment
.Commit();