众所周知,Fragment实例在添加到后台堆栈时不会被销毁(参见:Creating a Fragment)。
我的片段有一个复杂的视图。我的目的是防止在片段从后栈返回到布局时重新创建视图,以便更快地呈现。
我的Fragment扩展类中的代码类似如下:
View firstView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (firstView == null) {
firstView = inflater.inflate(R.layout.first_view, container, false);
Button btn_read = (Button)firstView.findViewById(R.id.btn_read);
btn_read.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// do something
}
});
}
return firstView;
}
我的片段被添加到后台。
然而,当我按“后退”弹出后台时,我得到以下异常。显然,先前在onCreateView中创建的视图仍然附加到某个地方,并且无法重新用于新的父视图。
我理解不遵循使用片段的“一般模式”是不明智的。我只是好奇如何防止重新创建BIG视图以提高Fragment中的性能。
-------------例外---------------
03-25 23:55:38.354: W/dalvikvm(314): threadid=3: thread exiting with uncaught exception (group=0x4001b188)
03-25 23:55:38.354: E/AndroidRuntime(314): Uncaught handler: thread main exiting due to uncaught exception
03-25 23:55:38.445: E/AndroidRuntime(314): java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewGroup.addViewInner(ViewGroup.java:1861)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewGroup.addView(ViewGroup.java:1756)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewGroup.addView(ViewGroup.java:1713)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewGroup.addView(ViewGroup.java:1693)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.NoSaveStateFrameLayout.wrap(NoSaveStateFrameLayout.java:40)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:874)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1080)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.BackStackRecord.popFromBackStack(BackStackRecord.java:697)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.FragmentManagerImpl.popBackStackState(FragmentManager.java:1465)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.FragmentManagerImpl.popBackStackImmediate(FragmentManager.java:447)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.support.v4.app.FragmentActivity.onBackPressed(FragmentActivity.java:164)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.app.Activity.onKeyUp(Activity.java:1863)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.KeyEvent.dispatch(KeyEvent.java:1061)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.app.Activity.dispatchKeyEvent(Activity.java:2043)
03-25 23:55:38.445: E/AndroidRuntime(314): at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1631)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2368)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2338)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.view.ViewRoot.handleMessage(ViewRoot.java:1641)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.os.Handler.dispatchMessage(Handler.java:99)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.os.Looper.loop(Looper.java:123)
03-25 23:55:38.445: E/AndroidRuntime(314): at android.app.ActivityThread.main(ActivityThread.java:4363)
03-25 23:55:38.445: E/AndroidRuntime(314): at java.lang.reflect.Method.invokeNative(Native Method)
03-25 23:55:38.445: E/AndroidRuntime(314): at java.lang.reflect.Method.invoke(Method.java:521)
03-25 23:55:38.445: E/AndroidRuntime(314): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
03-25 23:55:38.445: E/AndroidRuntime(314): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
03-25 23:55:38.445: E/AndroidRuntime(314): at dalvik.system.NativeStart.main(Native Method)
03-25 23:55:38.445: I/Process(52): Sending signal. PID: 314 SIG: 3
答案 0 :(得分:0)
你可以尝试
if (view != null) {
((ViewGroup) view.getParent()).removeView(view);
} else {
// Create your view
...
}
return view