Android横竖屏切换和灭屏亮屏时Activity的生命周期探究

来源:互联网 发布:python虚拟主机 编辑:程序博客网 时间:2024/05/20 20:48

研究这个问题的初衷在于项目中碰到了一个问题:横屏的时候灭屏再亮屏,亮屏的时候用户可以清晰的看到先启动竖屏(过程1)再切换到横屏的过程,由于灭屏的时候onSaveInstanceState()保存的时横屏时的状态信息,因此过程1竖屏会使用到横屏的状态参数而且这一过程用户是可见的,因此会导致一些意想不到的Bug的出现。

探究使用的实例中我用了屏幕的横竖屏和宽这两个配置信息来说明生命周期中此时系统所知道的屏幕的客观状态,注意这个客观状态与我们在onSaveInstanceState()中要保存的“状态信息”是不一样的,客观状态由硬件和系统决定,在那一时刻一定是这样的状态,“状态信息”是程序员想要保存的信息,这个由程序员自己控制。

横竖屏切换一般会由onConfigurationChanged()这个系统函数来响应,但响应这个函数需要在Manifest中为Activity配置如下信息(Android3.2及更高版本的配置方法)

<activity
            ...
            android:configChanges="orientation|screenSize"
            ... >

(设置该activity属性,实际上是让该activity去主动捕捉"orientation|screenSize"这些configsChanges事件

本篇先探究没有进行这种配置时Activity的生命状态,从结果中可以看到此时的横竖屏切换时一个完全杀死Activity再重启Activity的过程,同时横屏的灭屏亮屏都先做了一次切换到竖屏的过程。

源码如下:

[java] view plaincopy在CODE上查看代码片派生到我的代码片
  1. package com.vivo.configurationtest;  
  2.   
  3. import android.app.Activity;  
  4. import android.content.res.Configuration;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7.   
  8. public class MainActivity extends Activity {  
  9.   
  10.     @Override  
  11.     protected void onCreate(Bundle savedInstanceState) {  
  12.         Log.d("vi""---onCreate()--" + "orientation = " + orientation()  
  13.                 + "width = " + width());  
  14.         super.onCreate(savedInstanceState);  
  15.         setContentView(R.layout.activity_main);  
  16.     }  
  17.   
  18.     @Override  
  19.     protected void onSaveInstanceState(Bundle outState) {  
  20.         // TODO Auto-generated method stub  
  21.         Log.d("vi""---onSaveInstanceState()--" + "orientation = "  
  22.                 + orientation() + "width = " + width());  
  23.         super.onSaveInstanceState(outState);  
  24.     }  
  25.   
  26.     @Override  
  27.     protected void onStart() {  
  28.         // TODO Auto-generated method stub  
  29.         Log.d("vi""---onStart()--" + "orientation = " + orientation()  
  30.                 + "width = " + width());  
  31.         super.onStart();  
  32.     }  
  33.   
  34.     @Override  
  35.     protected void onResume() {  
  36.         // TODO Auto-generated method stub  
  37.         Log.d("vi""---onResume()--" + "orientation = " + orientation()  
  38.                 + "width = " + width());  
  39.         super.onResume();  
  40.     }  
  41.   
  42.     @Override  
  43.     protected void onPause() {  
  44.         // TODO Auto-generated method stub  
  45.         Log.d("vi""---onPause()--" + "orientation = " + orientation()  
  46.                 + "width = " + width());  
  47.         super.onPause();  
  48.     }  
  49.   
  50.     @Override  
  51.     public void onConfigurationChanged(Configuration newConfig) {  
  52.         // TODO Auto-generated method stub  
  53.         Log.d("vi""---onConfigurationChanged()--" + "width = " + width());  
  54.         super.onConfigurationChanged(newConfig);  
  55.     }  
  56.   
  57.     @Override  
  58.     protected void onStop() {  
  59.         // TODO Auto-generated method stub  
  60.         Log.d("vi""---onStop()--" + "orientation = " + orientation()  
  61.                 + "width = " + width());  
  62.         super.onStop();  
  63.     }  
  64.   
  65.     @Override  
  66.     protected void onRestart() {  
  67.         // TODO Auto-generated method stub  
  68.         Log.d("vi""---onRestart()--" + "orientation = " + orientation()  
  69.                 + "width = " + width());  
  70.         super.onRestart();  
  71.     }  
  72.   
  73.     @Override  
  74.     protected void onDestroy() {  
  75.         // TODO Auto-generated method stub  
  76.         Log.d("vi""---onDestroy()--" + "orientation = " + orientation()  
  77.                 + "width = " + width());  
  78.         super.onDestroy();  
  79.     }  
  80.   
  81.     private String orientation() {  
  82.   
  83.         int ori = this.getResources().getConfiguration().orientation;  
  84.         if (ori == Configuration.ORIENTATION_PORTRAIT) {  
  85.             return "ORIENTATION_PORTRAIT--";  
  86.         } else if (ori == Configuration.ORIENTATION_LANDSCAPE) {  
  87.             return "ORIENTATION_LANDSCAPE--";  
  88.         }  
  89.         return "-------";  
  90.     }  
  91.   
  92.     private int width() {  
  93.         int screenWidth = getWindowManager().getDefaultDisplay().getWidth();  
  94.         return screenWidth;  
  95.     }  
  96. }  


//以下为没有在manifest中配置configuration

//竖屏从创建到切换到横屏
C:\Users\Administrator>adb logcat -s vi
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
D/vi      (16610): ---onCreate()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStart()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onResume()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onPause()--orientation = ORIENTATION_LANDSCAPE--width = 854  //onPause()时已经获取到切换之后的屏幕的配置信息
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onStop()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onDestroy()--orientation = ORIENTATION_LANDSCAPE--width = 854 //屏幕切换是一个完全的杀死activity然后重启activity的过程
D/vi      (16610): ---onCreate()--orientation = ORIENTATION_LANDSCAPE--width =854
D/vi      (16610): ---onStart()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onResume()--orientation = ORIENTATION_LANDSCAPE--width =854




//从横屏切换到竖屏
C:\Users\Administrator>adb logcat -s vi
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
D/vi      (16610): ---onPause()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStop()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onDestroy()--orientation = ORIENTATION_PORTRAIT--width =480
D/vi      (16610): ---onCreate()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStart()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onResume()--orientation = ORIENTATION_PORTRAIT--width = 480


//竖屏从灭屏到亮屏
C:\Users\Administrator>adb logcat -s vi
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
D/vi      (16610): ---onPause()--orientation = ORIENTATION_PORTRAIT--width = 480 //灭屏从onPause()处开始
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_PORTRAIT--width = 480 //暂停并保存当前信息,要保存什么样的信息由用户选择
D/vi      (16610): ---onStop()--orientation = ORIENTATION_PORTRAIT--width = 480  
D/vi      (16610): ---onRestart()--orientation = ORIENTATION_PORTRAIT--width =480 //亮屏从onRestart()处开始
D/vi      (16610): ---onStart()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onResume()--orientation = ORIENTATION_PORTRAIT--width = 480


//横屏的灭屏
C:\Users\Administrator>adb logcat -s vi
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
D/vi      (16610): ---onPause()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStop()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onDestroy()--orientation = ORIENTATION_PORTRAIT--width =480
D/vi      (16610): ---onCreate()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStart()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onResume()--orientation = ORIENTATION_PORTRAIT--width = 480 //横屏的灭屏相当于先切换到竖屏,再灭屏,这个过程用户没看到


D/vi      (16610): ---onPause()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onStop()--orientation = ORIENTATION_PORTRAIT--width = 480


//横屏的亮屏
C:\Users\Administrator>adb logcat -s vi
--------- beginning of /dev/log/main
--------- beginning of /dev/log/system
D/vi      (16610): ---onRestart()--orientation = ORIENTATION_PORTRAIT--width =480
D/vi      (16610): ---onStart()--orientation = ORIENTATION_PORTRAIT--width = 480
D/vi      (16610): ---onResume()--orientation = ORIENTATION_PORTRAIT--width = 480 //横屏的亮屏相当于先亮到竖屏,再切换到横屏,这个过程用户是可以看到的,灭屏的时候系统也做了一次同样的切换到竖屏的动作,屏灭用户没看到而已


D/vi      (16610): ---onPause()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onSaveInstanceState()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onStop()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onDestroy()--orientation = ORIENTATION_LANDSCAPE--width = 854
D/vi      (16610): ---onCreate()--orientation = ORIENTATION_LANDSCAPE--width =854
D/vi      (16610): ---onStart()--orientation = ORIENTATION_LANDSCAPE--width = 854

D/vi      (16610): ---onResume()--orientation = ORIENTATION_LANDSCAPE--width =854


原文链接

0 0
原创粉丝点击