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