android - 从 DialogFragment 访问宿主 Activity 的视图
问题描述
我遇到过这样的问题。在我的应用程序中,我有一个 Activity (MobileActivity),其中包含一些视图(Spinners、TextViews 和 Button)。当用户点击按钮时,我需要打开一个对话框(ConfirmDialog)。在这个对话框中,我需要从 MobileActivity 的视图中显示一些数据(参见下面的代码)。有时在 Play Console 中,我会看到带有 NullPointerException 的崩溃报告(我在代码中标记了该行)。问题出在哪里?
谢谢!
我想,问题可能出在 Activity 的生命周期方法中。我尝试了接下来的操作:
- 在模拟器上启动我的应用程序并打开 DialogFragment
- 按下主页按钮
- 在 adb 中,杀死了我的进程 (adb kill )
- 从后台应用重新打开我的应用
它没有崩溃。那么,问题不在于后台吗?
来自 MobileActivity 的代码,它将打开我的 DialogFragment
ConfirmDialog newFragment = new ConfirmDialog();
newFragment.show(getFragmentManager(), "Confirmation");
来自 ConfirmDialog 的代码
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
// Get the layout inflater
LayoutInflater inflater = getActivity().getLayoutInflater();
View v = null;
Spinner s;
v = inflater.inflate(R.layout.confirm_mobile_layout, null);
builder.setView(v);
//next row marked in stacktrace as problem row
//Spinner with Id=acn_debit_mobile is placed on MobileActivity
s = getActivity().findViewById(R.id.acn_debit_mobile);
Spinner b = getActivity().findViewById(R.id.biller_mobile);
//other code
return builder.create();
}
以及来自 Play 控制台的堆栈跟踪
java.lang.RuntimeException:
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2814)
at android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:2892)
at android.app.ActivityThread.handleRelaunchActivity (ActivityThread.java:4763)
at android.app.ActivityThread.-wrap18 (Unknown Source)
at android.app.ActivityThread$H.handleMessage (ActivityThread.java:1621)
at android.os.Handler.dispatchMessage (Handler.java:106)
at android.os.Looper.loop (Looper.java:171)
at android.app.ActivityThread.main (ActivityThread.java:6635)
at java.lang.reflect.Method.invoke (Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:547)
at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:823)
Caused by: java.lang.NullPointerException:
at ua.grant.smart.ConfirmDialog.onCreateDialog (ConfirmDialog.java:121)
at android.app.DialogFragment.onGetLayoutInflater (DialogFragment.java:406)
at android.app.Fragment.performGetLayoutInflater (Fragment.java:1325)
at android.app.FragmentManagerImpl.moveToState (FragmentManager.java:1279)
at android.app.FragmentManagerImpl.moveFragmentToExpectedState (FragmentManager.java:1562)
at android.app.FragmentManagerImpl.moveToState (FragmentManager.java:1623)
at android.app.FragmentManagerImpl.dispatchMoveToState (FragmentManager.java:3032)
at android.app.FragmentManagerImpl.dispatchActivityCreated (FragmentManager.java:2984)
at android.app.FragmentController.dispatchActivityCreated (FragmentController.java:178)
at android.app.Activity.performCreate (Activity.java:7090)
at android.app.Activity.performCreate (Activity.java:7075)
at android.app.Instrumentation.callActivityOnCreate (Instrumentation.java:1215)
at android.app.ActivityThread.performLaunchActivity (ActivityThread.java:2767)
我添加了 onAttach 和 onDetach 方法来存储对我的主机 Activity 的引用(下面的代码),并在 ConfirmDialog 类的所有位置将 getActivity() 替换为 mActivity。它会解决这个问题吗?
mActivity Activity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
@Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
解决方案
保留活动实例并在片段分离时销毁它是避免的好方法NullPointerException
mActivity Activity;
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
mActivity = activity;
}
@Override
public void onDetach() {
super.onDetach();
mActivity = null;
}
但是您可能需要检查两件事。
- 你为什么不对你的片段使用相同的方法,
mActivity
在你的onCreateDialog
. 顺便说一句,请mActivity
在进行任何交易之前检查 null 。
- 使用
yourDialogFragment.show()
显式运行此函数:
ft.commit()
安排此事务的提交。提交不会立即发生。它将被安排为主线程上的工作,以便在该线程下一次准备好时完成。因此,我们无法确保任何事情,IllegalStateException
例如它可能导致。
怎么样:commitAllowingStateLoss()
。但使用前请仔细阅读文档。看看这个。
- 你为什么不放大视图
onCreateView
?(你不必这样做onCreateDialog
)
推荐阅读
- css - 如何使 wordpress 宽敞主题全宽?
- c++ - 关闭简单的文本编写代码会减慢应用程序的速度
- javascript - React 编码需要解释
- javascript - 将 Cron 更改为可读的日期和时间
- database - 如何在 Laravel Socialite/Social Login 中保存额外的数据?
- python - Python:底图倒钩,地图上的风矢量绘图
- esb - 如何暂停消息处理一段时间?
- java - Hibernate Validator 的奇怪行为
- c# - 何时使用 Task.Run 而不是
- npm - 让 devextreme dataGrid 与 webpack 一起工作