在活动的onDestroy()回调中专门将实例变量设置为null是一个好主意吗?像这样的东西:
@Override
protected void onDestroy() {
super.onDestroy();
mClassVariable1 = null;
mClassVariable2 = null;
mClassVariable3 = null;
}
Run Code Online (Sandbox Code Playgroud)
如果我从Java SE中正确记得,任何被隔离但未连接到正在运行的程序的引用都可以进行垃圾收集.那么这会使上述多余吗?
另一方面,移动设备的生命周期不同,以上是最佳实践吗?
我知道这样做不会有什么坏处,但有时会有一些类变量(对单个UI元素的引用等),所以我真的想知道我自己的理解,真正发生了什么.
提前致谢!
我正在创建一个与数据库进行大量交互的应用程序(读写操作).
为了避免在每个请求中打开/关闭操作,我创建了SQLiteOpenHelper一个使用Singleton设计模式扩展的类.这样,我确信SQLiteOpenHelper在整个应用程序生命周期(而不仅仅是活动生命周期)中,只有一个与数据库建立连接的实例.
我还阅读了一些关于ContentProvider的文章,但我不确定这是一个更好的方法.
所以,这是我的Singleton类的主要逻辑(onCreate并onUpgrade删除):
public final class BaseSQLite extends SQLiteOpenHelper {
private static BaseSQLite mInstance = null;
private SQLiteDatabase db = null;
public static BaseSQLite getInstance(Context context) {
if (mInstance == null) {
mInstance = new BaseSQLite(context.getApplicationContext(),
DBNAME, DBVERSION);
}
return mInstance;
}
private BaseSQLite(final Context context, final String name,
final int version) {
super(context, name, null, version);
db = getWritableDatabase();
}
@Override
public synchronized void close() { …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序,一个包含片段的活动应用程序.
这个应用程序的通常用例是,你启动它并把电话拿走,不时,你回到手机并插入一些数据......这是一个日志应用程序,你正在做一些事情并插入你的结果进入应用程序...
我有问题,不时,我的活动被摧毁,并用空包重新创建......(大多数时候情况并非如此,但不时发生这种情况......).我的应用程序有时会启动服务,即使这种服务在这种情况下被杀死...
这意味着系统已杀死我的应用程序,是吗?我怎么能避免这个?
我需要保留用户数据和当前的顶级片段...并且它们被保存到捆绑包中,只要状态和数据得到保存,一切都会正常工作......
顺便说一句,我的活动始终是TOP ACTIVITY,只是屏幕经常关闭......我只想让我的活动尽可能长时间活着,直到用户离开后面的按钮......或者保存状态可靠
重要的提示
onSaveInstance并不总是有效(它不是生命周期的一部分,因此不能保证被调用)...它只能在大多数情况下工作......我需要一种方法来始终工作...如果android杀了我的应用程序. ..
为了清楚起见,我已经阅读了关于"IllegalStateException:在onSaveInstanceState之后无法执行此操作"的十几个SO问题,我已经阅读了Alex Lockwood的博客文章http://www.androiddesignpatterns.com/2013/08/片段事务提交状态-loss.html
所以我不是盲目地问这个.
我有一个非常简单的用例案例,不涉及AsyncTask或任何后台处理.
我有一个包含按钮的片段.在按钮的onClickListener上,我创建了一个DialogFragment并显示它.
public final class OverviewFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.overview_fragment, container, false);
startNewGameButton = (Button) view.findViewById(R.id.buttonNewGame);
startNewGameButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final NewGameFragment dialogFrag = NewGameFragment.create(getApplication());
dialogFrag.show(getFragmentManager(), NewGameFragment.FRAGMENT_TAG);
}
});
}
Run Code Online (Sandbox Code Playgroud)
[NewGameFragment]
public final class NewGameFragment extends DialogFragment {
public static final String FRAGMENT_TAG = "NewGameFragment";
private static final String MESSAGE = "message";
public static NewGameFragment …Run Code Online (Sandbox Code Playgroud) android android-lifecycle android-fragments android-dialogfragment android-nested-fragment
我知道这个问题已被问了一百万次,我自己虽然我已经知道了答案,而且正确的一个是唯一有保证的电话是onPause(),所以你应该把数据保存在那里.
但是,在android文档的许多地方,他们总是建议不要在onPause()方法中做繁重的工作(比如在数据库中写数据),因为它会延迟活动之间的转换.
onPause():此方法通常用于向持久数据提交未保存的更改,停止动画以及可能消耗CPU的其他内容,等等.它应该尽快做任何事情,因为下一个活动在返回之前不会恢复.
Killable:是的
然后根据类似表中的Android Developer Reference Guide.
它说同样的事情但是:
Killable:Pre-HONEYCOMB
并且他们添加了一个说明:
请注意,这些语义在针对从HONEYCOMB开始的平台的应用程序与针对先前平台的平台之间会略有不同.从Honeycomb开始,应用程序在其onStop()返回之前不处于killable状态.这可能会在调用onSaveInstanceState(Bundle)时产生影响(可以在onPause()之后安全地调用它,并允许和应用程序安全地等到onStop()以保存持久状态.
Killable
请注意上表中的"Killable"列 - 对于那些被标记为可填充的方法,在该方法返回之后,托管该活动的进程可能在任何时候被系统杀死而不执行其代码的另一行.
对于POST-HONEYCOMB(我不关心早期版本): 那么,可以假设任何Android设备(包括不同的ROMS)将确保在活动上调用onStop吗?这是任何耗费存储写入应用程序的最佳位置?
注意:这是非常令人困惑的,因为这里的大多数答案,网站,书籍,甚至在线Android测试都是正确的答案,你应该将它保存在onPause而不是onStop.
在我的MainActivity中,如果设置了intent中的标志,我会打开一个对话框.如果对话框已创建,则会被取消onPause()
@Override
public void onPause() {
super.onPause();
if (_dialog!= null) {
_dialog.dismiss();
_dialog= null;
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intentContainsFlag) {
_dialog = ....;
_dialog.show();
}
}
Run Code Online (Sandbox Code Playgroud)
如果按下ListView持有者按钮并打造一个意图URI,则打开该对话框:
bttn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// The URL scheme is registered in the intent filter
String intentString = "http://open.example.com/myParameters";
v.getContext().startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(intentString)));
}
});
Run Code Online (Sandbox Code Playgroud)
AndroidManigfest包含:
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:launchMode="singleTask"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="http" android:host="open.example.com" …Run Code Online (Sandbox Code Playgroud) android android-intent android-lifecycle android-alertdialog android-7.1-nougat
编写时Views,ViewModels并且LiveData具有生命周期意识。在ViewModel想是目前的FragmentActivity,LiveData当前的LifecycleOwner。您事先不知道您的 View 是否会被包裹或有所包裹。所以它需要一个灵活的函数来找到想要的上下文。我最终采用了这两种方法:
private FragmentActivity getFragmentActivity() {
Context context = getContext();
while (!(context instanceof FragmentActivity)) {
context = ((ContextWrapper) context).getBaseContext();
}
return (FragmentActivity) context;
}
private LifecycleOwner getLifecycleOwner() {
Context context = getContext();
while (!(context instanceof LifecycleOwner)) {
context = ((ContextWrapper) context).getBaseContext();
}
return (LifecycleOwner) context;
}
Run Code Online (Sandbox Code Playgroud)
现在这是要放入每个视图的大量样板代码。有没有更简单的方法?
我不想为此使用自定义的 View 基类,因为大的层次结构很难看。另一方面,组合需要与此解决方案一样多的代码。
我们observe在片段中大量使用了 LiveData 的方法。最近发布的 androidx 片段 sdk 导致 Android Studio 将 的实例标记liveDataObject.observe(this)为不正确,而支持liveDataObject.observe(getViewLifecycleOwner()).
添加了新的 Lint 检查,以确保您在从 onCreateView()、onViewCreated() 或 onActivityCreated() 观察 LiveData 时使用 getViewLifecycleOwner()。(b/137122478) https://developer.android.com/jetpack/androidx/releases/fragment
我们很担心实现这个变化,因为我们不明白 的功能与getViewLifecycleOwner()using的功能相比如何this,以及它是否会导致使用this或this.getActivity()在 Fragment 中设置 ViewModel 时发生冲突。
此外,我们使用 Android Navigation 组件并注意到当用户导航到同一个 Activity 中的不同片段时,每个片段的onDestroyView()方法都会被调用,但不会onDestroy()
这是我们的代码示例 onViewCreated()
vm.getStemLengths().observe(this, stemLengths -> {
this.stemLengths = new ArrayList<>(Stream.of(stemLengths).map(stemLength ->
new SearchModel(Integer.toString(stemLength.getValue()))).toList());
});
Run Code Online (Sandbox Code Playgroud)
后来,在 onDestroyView()
vm.getStemLengths().removeObservers(this);
Run Code Online (Sandbox Code Playgroud)
同时,根据片段,包含 LiveData 的 ViewModel 设置为以下之一:
vm = new ViewModelProvider(this.getActivity()).get(PrepareVM.class);
Run Code Online (Sandbox Code Playgroud)
跨活动中的片段保留视图模型。
或者: …
我需要知道ImageView的宽度和高度.有没有办法在片段中测量它?在标准Activity中我使用:
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
image.getWidth();
image.getHeight();
}
Run Code Online (Sandbox Code Playgroud)
但是我可以在哪里使用image.getWidth();和image.getHeight();片段?
我正在构建一个实现该LifecycleObserver接口的Android Java类.
这是构造函数:
public MyObserver(AppCompatActivity activity) {
this.mActivity = new WeakReference<AppCompatActivity>(activity);
activity.getLifecycle().addObserver(this);
}
Run Code Online (Sandbox Code Playgroud)
是否有必要使用以下内容进行呼叫removeObserver:
@OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
public void destroyListener() {
if (this.mActivity.get() != null) {
this.mActivity.get().getLifecycle().removeObserver(this);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,我可以永远观察吗?