活动生命周期 - onCreate呼吁每次重新定位

时间:2011-10-01 06:52:37

标签: android activity-lifecycle

我有一个简单的活动,可以在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一次。我错了吗?如何重新定位设备会导致重新创建活动?

13 个答案:

答案 0 :(得分:76)

android:configChanges="keyboardHidden|orientation|screenSize"
  

警告:从Android 3.2开始(API级别13),“屏幕尺寸”   当设备在纵向和横向之间切换时也会发生变化   取向。因此,如果您希望阻止运行时重新启动   开发API级别13或更高级别时的方向更改(如   由minSdkVersion和targetSdkVersion属性声明),你   除“方向”外,还必须包含“screenSize”值   值。也就是说,你必须decalare   android:configChanges="orientation|screenSize"。但是,如果你的   应用程序目标API级别12或更低,然后您的活动始终   处理此配置更改本身(此配置更改   即使在Android 3.2或Android上运行,也不会重新启动您的活动   更高的设备)。

http://developer.android.com/guide/topics/resources/runtime-changes.html

答案 1 :(得分:46)

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

答案 2 :(得分:44)

方向改变时会发生什么

定位的生命周期

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

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

---- app重新创建,现在正在运行---

如果您在onCreate()进行长时间操作,并希望阻止重新创建活动,请在主要节目中添加configChanges属性

<activity android:name=".MyActivity"
          android:configChanges="orientation|keyboardHidden|screenSize"
          android:label="@string/app_name">
如果您定位api&gt; = 13

,请

screenSize

答案 3 :(得分:12)

旋转屏幕时的Actvity生命周期

onPause
onSaveInstanceState
onStop
onDestroy

onCreate
onStart
onRestoreInstanceState
onResume

答案 4 :(得分:10)

如果您想阻止FC内存不足,则需要在onStop()onPause()中取消分配资源。这允许您在onCreate()中使用新鲜内存。

这是使用

防止重新开展活动的替代解决方案

android:configChanges="keyboardHidden|orientation"

有时您的活动布局在纵向和横向(布局,布局 - 土地)方面有所不同。 防止在方向更改时重新创建将阻止您的活动使用其他方向的布局。

答案 5 :(得分:9)

On Create方法会在您进行定向时每次调用,为避免这种情况,您必须使用

//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

              }
            }

它会像魅力一样!!

答案 6 :(得分:8)

是的,每次onCreate()更改时都会调用活动orientation,但您可以通过添加re-creation Activity来避免configChanges attribute Activity在活动代码中的AndroidManifest文件中。

android:configChanges="keyboardHidden|orientation"

答案 7 :(得分:4)

使用

android:configChanges="keyboardHidden|orientation" in Manifest XML activity Tag

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

使用上面的代码在Activity Java Code

中执行与方向相关的更改

干杯!!!

答案 8 :(得分:4)

处理方向变化的最常见和建议的“解决方案”之一是不处理它们。您可以通过在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/

虽然实现起来似乎有点乏味,但正确处理方向更改会为您提供以下好处:您将能够轻松地在纵向和横向方向上使用备用布局,并且您将能够处理许多异常状态,例如低内存情况和来电中断,无需任何额外代码。

答案 9 :(得分:2)

请看我的做法: -

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);

答案 10 :(得分:0)

尽管清单方式可能有效,但是对于这些类型的问题有更好更好的解决方案。 ViewModel类。您应该在这里看看:https://developer.android.com/topic/libraries/architecture/viewmodel

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

答案 11 :(得分:-2)

我遇到了同样的问题,当屏幕方向改变时,我的onCreate被多次调用。当我在android:configChanges="orientation|keyboardHidden|screenSize"

中的activity标记中添加manifest时,我的问题就解决了

答案 12 :(得分:-3)

我遇到了同样的问题,我做了一些解决方法

使用false值定义didLoad布尔变量

private boolean didLoad = false;

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

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