android:configChanges属性

原创 2014年03月14日 20:54:16
      Android程序在运行时,一些设备的配置可能会改变,如:横竖屏的切换、键盘的可用性等。这些事件一旦发生,当前活动的Activity会重新启动,其中的过程是:在销毁之前会先调用onSaveInstanceState()方法去保存你应用中的一些数据,然后调用onDestroy()方法,最后调用onCreate()、onStart()、onResume()等方法启动一个新的Activity,。 

      如果想让某些配置在发生改变的时候不重启Activity,需要为Activity添加android:configChanges属性,该属性可以设置多个值,用"|"隔开,例如:“locale|navigation|orientation。设置了android:configChanges属性后,当指定的属性发生变化时,不会去重新启动Activity,而是通知程序去调用Activity的onConfigurationChanged()方法。例如:在进行横竖屏的切换时,会重新启动Activity,而定义了android:configChanges="orientation|keyboardHidden",就不会重新启动Activity了,而是去调用 onConfigurationChanged()方法。

      简言之,在Activity中添加了android:configChanges属性,目的是当android:configChanges所设置的属性值对应的配置属性发生改变时,通知程序调用 onConfigurationChanged()函数,而不会重启Activity。

     下面是android:configChanges属性可以指定的值(不完整):

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


      关于这些属性,用的最多的情况可能就是横竖屏切换的情况了,下面实际做了例子测试一下横竖屏切换时这些属性对Activity生命周期的影响。首先建立一个项目,Activity的代码如下(代码摘自:http://blog.csdn.net/liuhe688/article/details/6733407):

import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Log;

public class OrientationActivity extends Activity {

	 private static final String TAG = "OrientationActivity";  
	    private int param = 1;  
	      
	    @Override  
	    protected void onCreate(Bundle savedInstanceState) {  
	        super.onCreate(savedInstanceState);  
	        setContentView(R.layout.orientation_portrait);  
	        Log.i(TAG, "onCreate called.");  
	    }  
	      
	    @Override  
	    protected void onStart() {  
	        super.onStart();  
	        Log.i(TAG, "onStart called.");  
	    }  
	      
	    @Override  
	    protected void onRestart() {  
	        super.onRestart();  
	        Log.i(TAG, "onRestart called.");  
	    }  
	      
	    @Override  
	    protected void onResume() {  
	        super.onResume();  
	        Log.i(TAG, "onResume called.");  
	    }  
	      
	    @Override  
	    protected void onPause() {  
	        super.onPause();  
	        Log.i(TAG, "onPause called.");  
	    }  
	      
	    @Override  
	    protected void onStop() {  
	        super.onStop();  
	        Log.i(TAG, "onStop called.");  
	    }  
	      
	    @Override  
	    protected void onDestroy() {  
	        super.onDestroy();  
	        Log.i(TAG, "onDestory called.");  
	    }  
	  
	    @Override  
	    protected void onSaveInstanceState(Bundle outState) {  
	        outState.putInt("param", param);  
	        Log.i(TAG, "onSaveInstanceState called. put param: " + param);  
	        super.onSaveInstanceState(outState);  
	    }  
	      
	    @Override  
	    protected void onRestoreInstanceState(Bundle savedInstanceState) {  
	        param = savedInstanceState.getInt("param");  
	        Log.i(TAG, "onRestoreInstanceState called. get param: " + param);  
	        super.onRestoreInstanceState(savedInstanceState);  
	    }  
	      
	    //当指定了android:configChanges="orientation"后,方向改变时onConfigurationChanged被调用  
	    @Override  
	    public void onConfigurationChanged(Configuration newConfig) {  
	        super.onConfigurationChanged(newConfig);  
	        Log.i(TAG, "onConfigurationChanged called.");  
	        switch (newConfig.orientation) {  
	        case Configuration.ORIENTATION_PORTRAIT: 
	        	Log.i(TAG, "竖屏");
	            break;  
	        case Configuration.ORIENTATION_LANDSCAPE:  
	        	Log.i(TAG, "横屏");
	            break;  
	        }  
	    } 

}


      AndroidManifest.xml文件中Activity配置代码:

 	<activity
            android:name="com.example.lifecycle.OrientationActivity"
            android:label="@string/title_activity_orientation">
              <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>


下面我们分情况测试一下横竖屏切换时android:configChanges属性值对Activity生命周期的影响,注意下面这些测试都是在真机情况下测试的,真机为华为P6(Android版本4.2.2),模拟器测试结果可能会不同,运行前要把横竖屏切换开关打开:

1、不配置android:configChanges属性,如上面的Activity配置代码,执行一下看看输出结果:

      (1)、从竖屏切换为横屏:

      
       可以看出:Activity首先销毁当前的生命周期,然后又重新启动了生命周期,重启了一遍。

       (2)、 再从横屏切换为竖屏:
         
   可以看出:结果同上面一样。


2、为Activity配置android:configChanges属性为“orientation”:

     (1)、从竖屏切换为横屏:

      

       可以看出:调用了Activity的onConfigurationChanged()方法,但是调用完onConfigurationChanged()方法后,仍然按没配置android:configChanges属性时的步骤重启了Activity。

(2)、 再从横屏切换为竖屏:

 可以看出:从横屏切换为竖屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。


3、为Activity配置android:configChanges属性为“orientation|keyboardHidden”:

(1)、从竖屏切换为横屏:

可以看出:从竖屏切换为横屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,仍然按没配置android:configChanges属性时的步骤重启了Activity。

(2)、 再从横屏切换为竖屏:

可以看出:从横屏切换为竖屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。


4、为Activity配置android:configChanges属性为“orientation|keyboardHidden|screenSize”:

(1)、从竖屏切换为横屏:

可以看出:从竖屏切换为横屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。

(2)、 再从横屏切换为竖屏:

可以看出:从横屏切换为竖屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。

5、为Activity配置android:configChanges属性为“orientation|screenSize”:

(1)、从竖屏切换为横屏:

可以看出:从竖屏切换为横屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。

(2)、 再从横屏切换为竖屏:

可以看出:从横屏切换为竖屏时,调用了ActivityonConfigurationChanged()方法,调用完onConfigurationChanged()方法后,没有重启了Activity。


6、为Activity配置android:configChanges属性为“screenSize”:

(1)、从竖屏切换为横屏:

可以看出:从竖屏切换为横屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,仍然重启了Activity。

(2)、 再从横屏切换为竖屏:

可以看出:从横屏切换为竖屏时,调用了Activity的onConfigurationChanged()方法,调用完onConfigurationChanged()方法后,仍然重启了Activity。


总结:

1、不设置android:configChanges属性时,横竖屏切换都会重启Activity,不会调用onConfigurationChanged()方法。

2、android:configChanges属性值为“orientation”时,会调用onConfigurationChanged()方法;从竖屏切换为横屏时,仍然会重启Activity;从横屏切换为竖屏时,不会重启Activity的生命周期。

3、android:configChanges属性为“screenSize”时,会调用onConfigurationChanged()方法;从竖屏切换为横屏时,从横屏切换为竖屏时,都会重启Activity的生命周期。

4、android:configChanges属性为“orientation|screenSize”时,会调用onConfigurationChanged()方法;从竖屏切换为横屏时,从横屏切换为竖屏时,都不会重启Activity的生命周期。

5、经测试"keyboardHidden"属性对横竖屏切换时没有影响,为什么要测试加"keyboardHidden"属性呢,因为网上很多文章在写到横竖屏切换时都会添加该属性,可能低版本时需要该属性。

可以参考http://blog.csdn.net/goyoung/article/details/8921139中的描述:

设置Activity的android:configChanges="orientation|keyboardHidden"时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。

但是,自从Android 3.2(API 13),在设置Activity的android:configChanges="orientation|keyboardHidden"后,还是一样会重新调用各个生命周期的。因为screen size也开始跟着设备的横竖切换而改变。所以,在AndroidManifest.xml里设置的MiniSdkVersion和 TargetSdkVersion属性大于等于13的情况下,如果你想阻止程序在运行时重新加载Activity,除了设置"orientation",你还必须设置"ScreenSize"。

解决方法:

AndroidManifest.xml中设置android:configChanges="orientation|screenSize“


注意:以上的测试结果都是在华为P6(Android 4.2.2版本)真机中做的,在其他版本(例如3.2以下)以及模拟器中,测试结果会有所不同。


参考:http://f120412352.iteye.com/blog/1464625

         http://www.kankanews.com/ICkengine/archives/114284.shtml

http://blog.csdn.net/goyoung/article/details/8921139

android国际化代码动态更改语言环境

1.场景我们都知道,在安卓做国际化的过程中,创建不同的value文件夹,引用不同value文件夹下的string就可以实现国际化,系统会根据手机的语言环境自动匹配语言环境,但有时候我们的应用动态设置语...
  • Andy_l1
  • Andy_l1
  • 2017年09月19日 14:12
  • 551

关于Activity设置configChanges属性

当设置configChanges属性的时候,会让Activity在什么时候不进行重新创建; 例如: 当不想让Activity在屏幕旋转的时候重新创建,就可以给configChanges属性添加or...
  • Angle0o
  • Angle0o
  • 2016年08月20日 23:02
  • 748

【Android进阶】android:configChanges属性总结

android中的组件Activity在manifest.xml文件中可以指定参数android:ConfigChanges,用于捕获手机状态的改变。 在Activity中添加了android:co...
  • bz419927089
  • bz419927089
  • 2014年02月25日 16:51
  • 37562

android:configChanges

VALUE                         DESCRIPTION
  • jkkjklmn
  • jkkjklmn
  • 2012年03月13日 16:32
  • 21724

android基础---AndroidManifest中android:configChanges的作用

当手机横放时, 程序的activity会重启, 以适应新的设备配置. 假如是一个编辑页面,  重启的结果会导致所写内容的丢失, 如果已经写了很多内容, 那将是一件极其蛋疼的事情. 如果不想横屏时ac...
  • BHduke
  • BHduke
  • 2013年11月21日 17:01
  • 2759

android:configChanges="orientation|keyboardHidden"的使用

1. 了解android:configChanges 的属性      通过设置这个属性可以使Activity捕捉设备状态变化,以下是可以被识别的内容:        CONFIG_FONT_SCA...
  • songshiMVP1
  • songshiMVP1
  • 2015年11月30日 11:27
  • 3994

(原创)获取系统语言方式及动态全局切换语言方式

获取系统语言及切换语言
  • lnn368
  • lnn368
  • 2016年04月19日 10:45
  • 1903

android:configChanges属性

对android:configChanges属性,一般认为有以下几点: 1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一...
  • linghu_java
  • linghu_java
  • 2014年04月01日 15:09
  • 962

android:configChanges属性

通过设置这个属性可以使Activity捕捉设备状态变化,以下是可以被识别的内容:   CONFIG_FONT_SCALE CONFIG_MCC CONFIG_MNC CONFIG_LOCALE...
  • leiming32
  • leiming32
  • 2012年04月05日 13:54
  • 4346

Android中ConfigChanges属性

在android开发中, 通过设置ConfigChanges属性可以使Activity捕捉设备状态变化
  • luzhenyuxfcy
  • luzhenyuxfcy
  • 2016年10月12日 17:30
  • 1712
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android:configChanges属性
举报原因:
原因补充:

(最多只允许输入30个字)