Activity android:configChanges属性

xiaoxiao2021-02-28  63

报错android.view.windowleaked——窗口泄漏。

Android的每个Activity都有个WindowManager窗口管理器,构建在某个Activity之上的对话框、PopupWindow也有对应的WindowManager窗口管理器。由于Dialog、PopupWindown不能脱离Activity而单独存在着,所以当承载某个Dialog或者某个PopupWindow正在显示的Activity被finish()后。而Dialog(或PopupWindow)没有正常退出的话,就会抛Window Leaked错误了,由于这个Dialog(或PopupWindow)的WindowManager已经没有谁能够附属了,所以它的窗口管理器就泄漏了。

依据此信息分析出,在进入新的Activity时突然转屏。由于在AndroidManifest.xml中没有配置android:configChanges属性,此时Activity会又一次调用onCreate方法,即会又一次调用整个生命周期。而此时的Dialog已经显示并没有dismiss。所以造成了窗口泄漏。解决办法就变得如此简单,在AndroidManifest.xml中配置android:configChanges属性,这样当我们横竖屏切换的时候会调用Activity的onConfigurationChanged方法,不会又一次调用整个生命周期了。

我们最后配置了android:configChanges="screenSize|orientation|keyboardHidden|navigation"。

1、不设置Activity的android:configChanges时。切屏会又一次调用整个生命周期,切横屏时会运行一次,切竖屏时会运行两次

2、设置Activity的android:configChanges="orientation"时,切屏还是会又一次调用整个生命周期,切横、竖屏时仅仅会运行一次

3、设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会又一次调用整个生命周期,仅仅会运行onConfigurationChanged方法

可是。自从Android 3.2(API 13),在设置Activity的android:configChanges="orientation|keyboardHidden"后。还是一样会又一次调用各个生命周期的。由于screensize也開始跟着设备的横竖切换而改变。所以在AndroidManifest.xml里设置的MiniSdkVersion和 TargetSdkVersion属性大于等于13的情况下,假设你想阻止程序在执行时又一次载入Activity,除了设置"orientation"。 你还必须设置" screenSize"。

附上android:configChanges属性解

VALUE                        DESCRIPTION                                                                                                                                                                                      "mcc"国际移动用户识别码所属国家代号是改变了-----  sim被侦測到了,去更新mcc    mcc是移动用户所属国家代号"mnc"国际移动用户识别码的移动网号码是改变了------ sim被侦測到了。去更新mnc    MNC是移动网号码,最多由两位数字组成。用于识别移动用户所归属的移动通信网"locale"地址改变了-----用户选择了一个新的语言会显示出来"touchscreen"触摸屏是改变了------一般是不会发生的"keyboard"键盘发生了改变----比如用户用了外部的键盘"keyboardHidden"键盘的可用性发生了改变"navigation"导航发生了变化-----通常也不会发生"screenLayout"屏幕的显示发生了变化------不同的显示被激活"fontScale"字体比例发生了变化----选择了不同的全局字体"uiMode"用户的模式发生了变化"orientation"屏幕方向改变了"screenSize"屏幕大小改变了"smallestScreenSize"屏幕的物理大小改变了,如:连接到一个外部的屏幕上

增加一个属性"layoutDirection" :当布局方向发生改变的时候,正常情况下无法修改布局的layoutDirection的属性-API17新添加

代码:

public class MainActivity extends AppCompatActivity { private static final String TAG = "owen"; //Activity创建时调用 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Log.i(TAG,"执行了onCreate方法"); } //Activity创建或者从后台重新回到前台时被调用 @Override protected void onStart() { super.onStart(); Log.i(TAG,"执行了onStart方法"); } //Activity从后台重新回到前台时被调用 @Override protected void onRestart() { super.onRestart(); Log.i(TAG,"执行了onRestart方法"); } //Activity创建或者从被覆盖、后台重新回到前台时被调用 @Override protected void onResume() { super.onResume(); Log.i(TAG,"执行了onResume方法"); } //Activity被覆盖到下面或者锁屏时被调用 @Override protected void onPause() { super.onPause(); Log.i(TAG,"执行了onPause方法"); } //退出当前Activity或者跳转到新Activity时被调用 @Override protected void onStop() { super.onStop(); Log.i(TAG,"执行了onStop方法"); } //退出当前Activity时被调用,调用之后Activity就结束了 @Override protected void onDestroy() { super.onDestroy(); Log.i(TAG,"执行了onDestroy方法"); } //当指定了android:configChanges="orientation"后,方向改变时onConfigurationChanged被调用,并且activity不再销毁重建 @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); switch (newConfig.orientation) { case Configuration.ORIENTATION_PORTRAIT://竖屏 Log.i(TAG,"竖屏"); break; case Configuration.ORIENTATION_LANDSCAPE://横屏 Log.i(TAG,"横屏"); default: break; } } }

在没有配置android:configChanges时,进行横屏和竖屏的切换时(在手机的设置中打开”自动旋转屏幕”选项)日志如:

从上面的日志中可以看出activity执行了销毁重建的过程,onConfigurationChanaged并没有被调用 如果加上android:configChanges=”keyboardHidden|orientation|screenSize”再进行旋转日志如下:

转载请注明原文地址: https://www.6miu.com/read-2600038.html

最新回复(0)