Android activity 方向改变,每次新实例
Android activity orientation change , each time new instance
我创建了非常简单的 activity 没有内容视图的 TempActivity,仅用于测试目的。当这个 activity 加载到 android phone 时,我做了大约 40 次方向更改,我将堆文件作为 hprof 导出到 MAT 工具并进行检查。它显示了我的 TempActivity 的 40 个实例,并且在每个实例中都有许多 class 用于 actionbar 视图,如 linearlayout、imageview 等。
每当我旋转屏幕时,DDMS 都会显示越来越多的内存添加到此应用程序的堆中,理想情况下,一段时间后它不应该被垃圾回收吗?当我强制执行 GC 时,它仍然没有被清除,并且显示堆内存增加。
请告诉我这是 Android 的默认行为,我们可以做些什么来删除 activity 的所有先前实例吗?这是内存泄漏的情况吗?因为在我的实时应用程序(contentview 中有图像和其他东西)中,我在旋转屏幕时遇到同样的问题,每次创建新实例 activity 并且堆大小不断增加。
是不是因为默认的ActionBar imageview, linearlayout 或者其他控件自动内置了每个 android activity 对吧?
这是我的温度 activity class:
[Activity(Label = "TempAcivity", MainLauncher = true)]
public class TempAcivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Create your application here
}
}
编辑
这是我申请的清单文件和样式文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="HF.Mobility.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21" />
<application android:label="Health Hub" android:theme="@style/CustomHoloTheme" android:icon="@drawable/ApplicationIcon" android:allowBackup="false">
<application android:label="@string/ApplicationName"></application>
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
</manifest>
样式文件:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="CustomHoloTheme" parent="@android:style/Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:icon">@android:color/transparent</item>
<item name="android:actionBarStyle">@style/MyTheme.ActionBarStyle</item>
<item name="android:itemTextAppearance">@style/myCustomMenuTextApearance </item>
<item name="android:typeface">monospace</item>
</style>
<style name="MyTheme.ActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:titleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="android:background">@drawable/actionbar_background</item>
</style>
<style name="MyTheme.ActionBar.TitleTextStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="myCustomMenuTextApearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
<item name="android:textColor">@color/xam_green</item>
</style>
</resources>
这是 actionbar_background.xml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
编辑:按照@Matt R 在他的链接 post 中概述的方式做似乎是最好的方法,我下面的回答更像是 "last resort",这就是 [=31] =] 文档也对其进行了分类。
来自文档:
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
原文post:
听起来将此添加到您的 AndroidManifest.xml 中会有所帮助,因为这样一来 Activity 就不会在方向更改时重新创建:
<activity android:name=".TempAcivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:label="@string/app_name">
此配置的文档状态:
Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration. By reading fields in the Configuration, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Link: http://developer.android.com/guide/topics/resources/runtime-changes.html
也请参阅此 post:How to detect orientation change in layout in Android?
我创建了非常简单的 activity 没有内容视图的 TempActivity,仅用于测试目的。当这个 activity 加载到 android phone 时,我做了大约 40 次方向更改,我将堆文件作为 hprof 导出到 MAT 工具并进行检查。它显示了我的 TempActivity 的 40 个实例,并且在每个实例中都有许多 class 用于 actionbar 视图,如 linearlayout、imageview 等。
每当我旋转屏幕时,DDMS 都会显示越来越多的内存添加到此应用程序的堆中,理想情况下,一段时间后它不应该被垃圾回收吗?当我强制执行 GC 时,它仍然没有被清除,并且显示堆内存增加。
请告诉我这是 Android 的默认行为,我们可以做些什么来删除 activity 的所有先前实例吗?这是内存泄漏的情况吗?因为在我的实时应用程序(contentview 中有图像和其他东西)中,我在旋转屏幕时遇到同样的问题,每次创建新实例 activity 并且堆大小不断增加。
是不是因为默认的ActionBar imageview, linearlayout 或者其他控件自动内置了每个 android activity 对吧?
这是我的温度 activity class:
[Activity(Label = "TempAcivity", MainLauncher = true)]
public class TempAcivity : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Create your application here
}
}
编辑
这是我申请的清单文件和样式文件
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="HF.Mobility.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="10" android:targetSdkVersion="21" />
<application android:label="Health Hub" android:theme="@style/CustomHoloTheme" android:icon="@drawable/ApplicationIcon" android:allowBackup="false">
<application android:label="@string/ApplicationName"></application>
</application>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
</manifest>
样式文件:
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<style name="CustomHoloTheme" parent="@android:style/Theme.Holo.Light">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowActionBarOverlay">true</item>
<item name="android:icon">@android:color/transparent</item>
<item name="android:actionBarStyle">@style/MyTheme.ActionBarStyle</item>
<item name="android:itemTextAppearance">@style/myCustomMenuTextApearance </item>
<item name="android:typeface">monospace</item>
</style>
<style name="MyTheme.ActionBarStyle" parent="@android:style/Widget.Holo.Light.ActionBar">
<item name="android:titleTextStyle">@style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="android:background">@drawable/actionbar_background</item>
</style>
<style name="MyTheme.ActionBar.TitleTextStyle" parent="@android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">#FFFFFF</item>
</style>
<style name="myCustomMenuTextApearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item">
<item name="android:textColor">@color/xam_green</item>
</style>
</resources>
这是 actionbar_background.xml 文件:
<?xml version="1.0" encoding="utf-8" ?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<solid android:color="#00000000" />
</shape>
</item>
</layer-list>
编辑:按照@Matt R 在他的链接 post 中概述的方式做似乎是最好的方法,我下面的回答更像是 "last resort",这就是 [=31] =] 文档也对其进行了分类。
来自文档:
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
原文post:
听起来将此添加到您的 AndroidManifest.xml 中会有所帮助,因为这样一来 Activity 就不会在方向更改时重新创建:
<activity android:name=".TempAcivity"
android:configChanges="orientation|screenSize|keyboardHidden"
android:label="@string/app_name">
此配置的文档状态:
Now, when one of these configurations change, MyActivity does not restart. Instead, the MyActivity receives a call to onConfigurationChanged(). This method is passed a Configuration object that specifies the new device configuration. By reading fields in the Configuration, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Link: http://developer.android.com/guide/topics/resources/runtime-changes.html
也请参阅此 post:How to detect orientation change in layout in Android?