我正在重写一个包含3个活动的蓝牙应用程序,只使用1个活动和3个碎片:
所以我现在有4个文件:
它几乎可以工作,但作为一个Android编程新手我不明白 - 当我展示其他碎片时如何处理碎片?
我应该只删除片段(并从FragmentManager中删除吗?)进行垃圾回收?
或者我应该将这3个私有变量添加到 MainActivity.java 并重复使用它们(当用户向前和向后导航时)?
private MainFragment mMainFragment;
private SettingsFragment mSettingsFragment;
private ScanningFragment mScanningFragment;
或FragmentManager以某种方式为我管理所有3片段 - 无论它们是否可见?
这是我目前的代码(很简单,我只是一直致电replace()
) -
public class MainActivity extends Activity implements
MainListener,
SettingsListener,
ScanningListener,
BleWrapperUiCallbacks {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main); // empty FrameLayout
Fragment fragment = new MainFragment();
getFragmentManager().beginTransaction()
.replace(R.id.root, fragment, "main")
.commit();
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Fragment fragment = new SettingsFragment();
getFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(R.id.root, fragment, "settings")
.commit();
break;
}
return super.onOptionsItemSelected(item);
}
// implementing SettingsFragment.SettingsListener interface
public void scanClicked() {
// TODO how to stop indicator when returned?
setProgressBarIndeterminateVisibility(true);
String address = // get from shared preferences
Fragment fragment = ScanningFragment.newInstance(address);
getFragmentManager().beginTransaction()
.addToBackStack(null)
.replace(R.id.root, fragment, "scan")
.commit();
}
答案 0 :(得分:2)
我应该只删除片段(并从FragmentManager中删除?) 垃圾收集?
无需做任何其他事情。 FragmentManager是负责Fragments生命周期的人。一旦调用replace()
,FragmentManager就会负责其余的工作。如果需要,它会在内存中保留片段,或者释放它。
或者我应该将这3个私有变量添加到MainActivity.java和 重用它们(当用户向前和向后导航时)?
不,不要因为上述说法而这样做。
或者FragmentManager以某种方式为我管理所有3片段 - 无论它们是否可见?
是的,确实如此。例如,如果你有一个不可见的保留片段,它就足以创建一次,FragmentManager会处理它,即使在配置更改期间重新创建活动时也会保留它。
如果您动态创建片段(据我所知,这是您的情况),那么我建议动态添加第一个片段。你可以这样做。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.activity_main); // empty FrameLayout
if (savedInstanceState == null) { // <- important
Fragment fragment = new MainFragment();
getFragmentManager().beginTransaction()
.replace(R.id.root, fragment, "main")
.commit();
}
}
这将确保您不会在配置更改时复制MainFragment,因为当savedInstanceState
不为null时,FragmentManager会保留您的片段的实例。
答案 1 :(得分:1)
由于您在片段管理器上调用.replace(),它与调用.remove()基本相同。根据{{3}}:
This is essentially the same as calling remove(Fragment) for all currently
added fragments that were added with the same containerViewId and
then add(int, Fragment, String) with the same arguments given here.
因此,您不必担心任何进一步的管理,因为它会为您照顾(并被移除以释放资源)。这基本上意味着当显示一个时,另一个被移除。如果你打电话给.add()那么片段仍然会在后台使用资源,但你不必担心,因为使用.replace()只允许一次生活。 / p>
答案 2 :(得分:0)
如果我正确理解你的问题,你不需要在使用它们之后调用任何方法来销毁它们。 Android操作系统将采用它们。根据文档,当您将片段替换为另一个片段时,片段的 onStop()方法将被执行,并记录为,
片段不可见。主机活动已停止或片段已从活动中删除但已添加到后台堆栈。已停止的片段仍处于活动状态(系统会保留所有状态和成员信息)。但是,它不再对用户可见,并且如果活动被杀死将会被杀死。
因此,当活动被杀死时,片段将被操作系统杀死。直到活动生效,片段对象将驻留在内存中。
EDT:
因此,如果您希望将来再次使用该片段,正如文档所示,
也像活动一样,您可以使用Bundle保留片段的状态,以防活动的进程被终止,并且您需要在重新创建活动时恢复片段状态。您可以在片段的onSaveInstanceState()回调期间保存状态,并在onCreate(),onCreateView()或onActivityCreated()期间恢复它。有关保存状态的更多信息,请参阅“活动”文档。
答案 3 :(得分:0)
Fragment
在[{1}}中被硬编码,无法替换....
但是当你打电话给xml
时会发生什么?
好的,只要考虑你有3个片段 A,B,C 。在初级阶段 A 在MainActivity中初始化...现在,您将使用replace(..)
从 A 调用 B 。这意味着 A 将进入replace(....)
生命周期状态, B 将在MainActivity中初始化并加速...与 C 相同那么 B 是onPause(),onStop()
州。如果您想重复使用 A 或 B ,则需要再次从 C呼叫 A 或 B 使用onPause() ,onStop()
。然后 A 或 B 将重新初始化, C 将转到replace (..)
。但是还有另一种方法可以做到这一点
onPause(),onStop()
如果您使用上面的代码块,那么 A 仍然处于其生命周期的运行状态但不可见(仅与UI分离)..所以如果您需要再次使用这些片段会更好FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
hide(A);
show(B);
ft.commit();
方法因为便宜操作然后重新初始化片段。