活动生命周期-onCreate 调用每次重定向

我有一个简单的活动,加载一个位图在 onCreate。我发现如果旋转设备,我可以从 onCreate再次调用的日志中看到。事实上,因为所有的实例变量都被再次设置为默认值,所以我知道整个 Activity 已经被重新实例化了。

在旋转2次后,我得到一个 FC,因为没有足够的内存可以分配给位图。(活动的所有实例是否仍然存在于某个地方?还是 GC 清理得不够快?)

@Override
public void onCreate(Bundle savedInstanceState) {
File externalStorageDir = Environment.getExternalStorageDirectory();
File picturesDir = new File(externalStorageDir, "DCIM/Camera");
File[] files = picturesDir.listFiles(new FilenameFilter(){
public boolean accept(File dir, String name) {
return name.toLowerCase().endsWith(".jpg");
}});
if (files.length > 0) {
Bitmap bm = BitmapFactory.decodeStream(new FileInputStream(files[0]));
ImageView view = (ImageView) findViewById(R.id.photo);
view.setImageBitmap(bm);
}
}

从我读到的所有内容来看,onCreate 应该在应用程序的生存期内调用一次。我说错了吗?重新定向设备如何导致重新创建活动?

103290 次浏览

默认情况下,每次旋转后都会重新创建活动。可以使用 AndroidManifest 中 activity标记的 configChanges属性覆盖此行为。有关进一步的详细信息和不同的选项,请参见 http://developer.android.com/guide/topics/resources/runtime-changes.html

是的,每次当 orientation改变时,活动的 onCreate()都会被调用,但是您可以通过在活动标记的 AndroidManifest文件中添加 ActivityconfigChanges attribute来避免 Activityre-creation

android:configChanges="keyboardHidden|orientation"

清单 XML 活动标签:

android:configChanges="keyboardHidden|orientation"‍‍‍


@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
}

使用上面的代码执行与 ActivityJavaCode 中的方向相关的更改

干杯! ! !

如果希望防止 FC 内存不足,则需要在 onStop()onPause()中释放资源。这允许您在 onCreate()中使用新内存。

这是通过使用

android:configChanges="keyboardHidden|orientation"

因为有时你的活动布局在纵向和横向(布局,布局-土地)上是不同的。 防止在方向改变时重新创建将防止您的活动使用其他方向的布局。

android:configChanges="keyboardHidden|orientation|screenSize"

注意: 从 Android 3.2(API 级别13)开始,“屏幕大小” 当设备在纵向和横向之间切换时也会发生变化 因此,如果您希望防止由于以下原因而导致的运行时重新启动 在开发 API 级别13或更高的应用程序时,方向会发生变化(如 由 minSdkVersion 和 targetSdkVersion 属性声明) ,则 除了“方向”外,还必须包括“屏幕大小”值 价值。也就是说,你必须申报 但是,如果你的 应用程序的目标 API 级别为12或更低,那么您的活动总是 处理此配置更改本身(此配置更改 不会重新启动你的活动,即使是在安卓3.2或 更高的设备)。

来自文档: http://developer.android.com/guide/topics/resources/runtime-changes.html

在创建方法将调用每次当你做方向,以避免这一点,你必须使用

//Define Below in you Manifest file.
<activity
android:name="com.ecordia.activities.evidence.MediaAttachmentView"
android:configChanges="keyboardHidden|orientation|screenSize"
</activity>


//Define Below in your activity.


@Override
public void onConfigurationChanged(Configuration newConfig) {


super.onConfigurationChanged(newConfig);


if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
//your code
} else if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
//your code


}
}

它会像咒语一样起作用的! !

当方向改变时会发生什么

定向生命周期

onPause();
onSaveInstanceState();
onStop();
onDestroy();


onCreate();
onStart();
onResume();

——应用程序重建,现在正在运行——

如果你在 onCreate()中做了长时间的操作,并且想要阻止重新创建你的活动,那么在你的主目录中添加 configChanges属性

<activity android:name=".MyActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="@string/app_name">

如果你的目标是 api,屏幕大小 = 13

我也有同样的问题,所以我做了一些变通

用假值定义 diLoad 布尔变量

Private boolean diLoad = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity);


if (!this.didLoad){
// Your code...
this.didLoad = true;
}

我遇到了同样的问题,当屏幕方向改变时,我的 onCreate 被多次调用。当我在 manifest中的 activity标签中添加 android:configChanges="orientation|keyboardHidden|screenSize"时,我的问题得到了解决

处理方向变化最常见和建议的“解决方案”之一就是不去处理它们。可以通过在 AndroidManifest.xml 中的 Activity 上设置 android: configChanges 标志来实现这一点,如下所示:

<activity
android:name=".MyActivity"
android:label="@string/title_my_activity"
android:configChanges="orientation|screenSize|keyboardHidden" />

这不是处理方向变化的正确方法。

CORRECT 方法是实现 onSaveInstanceState 方法(这可以在 Activity、 Fragment 或两者中) ,并将需要保存的值放在传递给该方法的 Bundle 参数中。

这里很好地描述了它: http://code.hootsuite.com/orientation-changes-on-android/

虽然实现起来有点乏味,但是正确处理方向改变可以给你带来一些好处: 你可以很容易地在纵向和横向方向上使用替代布局,你也可以处理许多异常状态,比如低内存情况和来电中断,而不需要任何额外的代码。

旋转屏幕时的活动生命周期

onPause
onSaveInstanceState
onStop
onDestroy


onCreate
onStart
onRestoreInstanceState
onResume

请看看我的做法:-

Http://animeshrivastava.blogspot.in/2017/08/activity-lifecycle-oncreate-beating_3.html

片段是:-

@Override
protected void onSaveInstanceState(Bundle b) {
super.onSaveInstanceState(b);
String str="Screen Change="+String.valueOf(screenChange)+"....";
Toast.makeText(ctx,str+"You are changing orientation...",Toast.LENGTH_SHORT).show();
screenChange=true;
}


@Override
public void onCreate(Bundle b) {
super.onCreate(b);
ctx=getApplicationContext();
if(!screenChange) {
String str="Screen Change="+String.valueOf(screenChange);
// ...
}
}

虽然 Manifest 方法可以工作,但是对于这些类型的问题有一个更好和适当的解决方案。ViewModel 类。你应该看看这里: https://developer.android.com/topic/libraries/architecture/viewmodel

基本上,您可以扩展 ViewModel 类并定义其中的所有数据成员,在重新创建活动时,我们希望这些成员保持不变(在本例中是面向变化)。并提供相关的方法来访问 Activity 类中的方法。因此,当活动被重新创建时,ViewModel 对象仍然存在,我们的数据也是如此!