activity详解一

首先从activity中在AndroidManifest.xml标签开始,先给出标签的相关内容,并从实际出发,列出我在开发过程中应用到的标签内容,因为有很多标签,在大多的程序中没有使用到,这里就不详细解释。

<activity android:alwaysRetainTaskState=["true" | "false"]
          android:configChanges=["mcc", "mnc", "locale",
                      "touchscreen", "keyboard", "keyboardHidden",
                      "navigation", "orientation", "screenLayout",
                                 "fontScale", "uiMode"]
          android:enabled=["true" | "false"]
          android:exported=["true" | "false"]
          android:icon="drawable resource"
          android:label="string resource"
          android:launchMode=["multiple" | "singleTop" |
                              "singleTask" | "singleInstance"]
          android:name="string"
          android:screenOrientation=["unspecified" | "user" | "behind" |
                                     "landscape" | "portrait" |
                                     "sensor" | "nosensor"]
          android:theme="resource or theme"
          android:windowSoftInputMode=["stateUnspecified",
                                       "stateUnchanged", "stateHidden",
                                       "stateAlwaysHidden", "stateVisible",
                                       "stateAlwaysVisible",               "adjustUnspecified",
                                       "adjustResize", "adjustPan"] >   
</activity>

1、android:alwaysRetainTaskState
是否保留状态不变, 比如切换回home, 再从新打开,activity处于最后的状态。比如一个浏
览器拥有很多状态(当打开了多个TAB的时候),用户并不希望丢失这些状态时,此时可将此属
性设置为true。

2.android:configChanges当窗口的状态发生改变了会怎么办呢?比如说,在一个Activity里有个Button,点击一下屏幕由竖屏变成了横屏。那么后台是怎么让它变的呢?比较残忍,调用Activity.onDestory()让它消失,再重新弄一个。当然这是默认状态。如果不想这样,我们就用上面这个属性来改变它。
mcc(IMSI移动国家代码MCC发生了变化。当SIM卡被检测到并更新MCC时配置变化);
mnc(IMSI移动国家代码MNC发生了变化。当SIM卡被检测到并更新MCC时配置变化);
locale(用户选择的新的文本显示语言时)
touchscreen(换触摸屏了,这个好多android手机不都支持多屏幕嘛)
keyboard(物理键盘类型改变了,比如你插入一个扩展键盘)
keyboardHidden(物理键盘被拔掉了)
navigation(导航硬件类型变了)
screenLayout(屏幕不见发生变化,可能屏幕上多了一个控件等之类的)
fontScale(字体缩放比例变了)
orientation(屏幕方向变了)
screenSize(屏幕尺寸变了)
smallestScreenSize(屏幕物理尺寸变了,比如又接个显示屏)

测试内容如下:
1、新建一个Activity,并把各个生命周期打印出来
  2、运行Activity,得到如下信息
  onCreate–>onStart–>onResume–>
  3、按crtl+f12切换成横屏时
  onSaveInstanceState–>onPause–>onStop–>onDestroy–>onCreate–>onStart–>onRestoreInstanceState–>onResume–>
  4、再按crtl+f12切换成竖屏时,发现打印了两次相同的log
  onSaveInstanceState–>onPause–>onStop–>onDestroy–>onCreate–>onStart–>onRestoreInstanceState–>onResume–>onSaveInstanceState–>onPause–>onStop–>onDestroy–>onCreate–>onStart–>onRestoreInstanceState–>onResume–>
  5、修改AndroidManifest.xml,把该Activity添加 android:configChanges=”orientation”,执行步骤3
  onSaveInstanceState–>onPause–>onStop–>onDestroy–>onCreate–>onStart–>onRestoreInstanceState–>onResume–>
  6、再执行步骤4,发现不会再打印相同信息,但多打印了一行onConfigChanged
  onSaveInstanceState–>onPause–>onStop–>onDestroy–>onCreate–>onStart–>onRestoreInstanceState–>onResume–>onConfigurationChanged–>
  7、把步骤5的android:configChanges=”orientation” 改成 android:configChanges=”orientation|screenSize”,(这个方式是开发版本大于13.)执行步骤3,就只打印onConfigChanged
  onConfigurationChanged–>
  8、执行步骤4
  onConfigurationChanged–>onConfigurationChanged–>
 
  

总结:

  1、不设置Activity的android:configChanges时,切屏会重新调用各个生命周期,切横屏时会执行一次,切竖屏时会执行两次
  2、设置Activity的android:configChanges=”orientation”时,切屏还是会重新调用各个生命周期,切横、竖屏时只会执行一次
  3、设置Activity的android:configChanges=”orientation|screenSize”时,切屏不会重新调用各个生命周期,只会执行onConfigurationChanged方法。
  补充一点,当前Activity产生事件弹出Toast和AlertDialog的时候Activity的生命周期不会有改变
  Activity运行时按下HOME键(跟被完全覆盖是一样的):onSaveInstanceState –> onPause –> onStop onRestart –>onStart—>onResume
  Activity未被完全覆盖只是失去焦点:onPause—>onResume
通过这个总结,我们可以得到如果需要切换屏幕,可以直接设置为android:configChanges=”orientation|screenSize”,这个是比较适中的方法。但是在大多数的情况下,我们开发的手机应用,是不能让屏幕能够随意的切换屏幕的,如果是游戏,就横屏(大的游戏,其他游戏可以横竖屏切换),如果是应用,那么是竖屏,有一种是需要切换屏幕的,视频播放,这个需要切换横竖。如何设置屏幕只有横屏和竖屏,看一下标签。

3.android:screenOrientation
activity显示的模式
默认为unspecified:由系统自动判断显示方向
landscape横屏模式,宽度比高度大
portrait竖屏模式, 高度比宽度大
user模式,用户当前首选的方向
behind模式:和该Activity下面的那个Activity的方向一致(在Activity堆栈中的)
sensor模式:有物理的感应器来决定。如果用户旋转设备这屏幕会横竖屏切换
nosensor模式:忽略物理感应器,这样就不会随着用户旋转设备而更改了

大多数情况下,我们单个设置为landscape和portrait。我在开发应用程序的时候,每个activity都设置为portrait,让其竖屏显示,不让它有切换屏幕的可能。有很多人都不关注这个问题,因为自己在测试的时候,自己没有打开屏幕旋转,以为自己开发的程序是没有问题的,但是当打开屏幕旋转,屏幕的布局发生了很大的变化。这个是开发人员需要考虑的,不能只是简单的理解用户不会去开切换屏幕的功能,但是如果用户开了,用户看到的杂乱的布局,给人的体验很不好,这就是一个很不合格的程序员。开发人员就是需要考虑到很多特殊的情况,我在说一个特殊情况,就是网络问题,大多数时候,我们只考虑有网的情况下,并且网络特别好的情况,但是当用户没有网络的情况,会出现什么样的情况呢。

android:name=”string”Activity包名
android:icon=”drawable resource”图标,这里没有任何效果
android:label=”string resource”标签,这里没有效果
android:theme=”resource or theme”主题,如果没有设置,则和Application一致,设置了,此activity覆盖Application的theme.
android:enabled 两个值:true或false。默认true.表示窗口是否能被实例化。一般就是true
android:exported两个值:true或false。默认true。决定其他的Activity是否可以隐式访问这个窗口。(很少用)

5 android:windowSoftInputMode
设置输入法显示模式。
stateUnspectified(默认)自动调整
stateUnchanged软键盘无论上次显示还是隐藏,都保持该状态
stateHidden跳转后隐藏键盘
stateAlwaysHidden窗口获得焦点后都会隐藏键盘
stateVisible获得焦点后显示键盘
stateAlwaysVisible获得焦点后都会显示
adjustUnspecified系统自动调整控件和键盘的位置
adjustResize窗口会根据软键盘窗口的大学调整自己位置
adjustPan自动调整控件位置,以便出现键盘后也能看到获得焦点的控件。

android:launchMode
standard、
singleTop、
singleTask、
singleInstance(其中前两个是一组、后两个是一组),默认为standard 。
下面是这四种模式的作用:
standard
默认模式,可以不用写配置。在这个模式下,都会默认创建一个新的实例。因此,在这种模式下,可以有多个相同的实例,也允许多个相同Activity叠加。

例如:
若我有一个Activity名为A1, 上面有一个按钮可跳转到A1。那么如果我点击按钮,便会新启一个Activity A1叠在刚才的A1之上,再点击,又会再新启一个在它之上……
点back键会依照栈顺序依次退出。

singleTop
可以有多个实例,但是不允许多个相同Activity叠加。即,如果Activity在栈顶的时候,启动相同的Activity,不会创建新的实例,而会调用其onNewIntent方法。

例如:
若我有两个Activity名为B1,B2,两个Activity内容功能完全相同,都有两个按钮可以跳到B1或者B2,唯一不同的是B1为standard,B2为singleTop。
若我意图打开的顺序为B1->B2->B2,则实际打开的顺序为B1->B2(后一次意图打开B2,实际只调用了前一个的onNewIntent方法)
若我意图打开的顺序为B1->B2->B1->B2,则实际打开的顺序与意图的一致,为B1->B2->B1->B2。

singleTask
只有一个实例。在同一个应用程序中启动他的时候,若Activity不存在,则会在当前task创建一个新的实例,若存在,则会把task中在其之上的其它Activity destory掉并调用它的onNewIntent方法。
如果是在别的应用程序中启动它,则会新建一个task,并在该task中启动这个Activity,singleTask允许别的Activity与其在一个task中共存,也就是说,如果我在这个singleTask的实例中再打开新的Activity,这个新的Activity还是会在singleTask的实例的task中。

例如:
若我的应用程序中有三个Activity,C1,C2,C3,三个Activity可互相启动,其中C2为singleTask模式,那么,无论我在这个程序中如何点击启动,如:C1->C2->C3->C2->C3->C1-C2,C1,C3可能存在多个实例,但是C2只会存在一个,并且这三个Activity都在同一个task里面。
但是C1->C2->C3->C2->C3->C1-C2,这样的操作过程实际应该是如下这样的,因为singleTask会把task中在其之上的其它Activity destory掉。

操作:C1->C2   C1->C2->C3    C1->C2->C3->C2    C1->C2->C3->C2->C3->C1      C1->C2->C3->C2->C3->C1-C2
实际:C1->C2   C1->C2->C3    C1->C2            C1->C2->C3->C1              C1->C2

若是别的应用程序打开C2,则会新启一个task。
如别的应用Other中有一个activity,taskId为200,从它打开C2,则C2的taskIdI不会为200,例如C2的taskId为201,那么再从C2打开C1、C3,则C2、C3的taskId仍为201。
注意:如果此时你点击home,然后再打开Other,发现这时显示的肯定会是Other应用中的内容,而不会是我们应用中的C1 C2 C3中的其中一个。

singleInstance
只有一个实例,并且这个实例独立运行在一个task中,这个task只有这个实例,不允许有别的Activity存在。

例如:
程序有三个ActivityD1,D2,D3,三个Activity可互相启动,其中D2为singleInstance模式。那么程序从D1开始运行,假设D1的taskId为200,那么从D1启动D2时,D2会新启动一个task,即D2与D1不在一个task中运行。假设D2的taskId为201,再从D2启动D3时,D3的taskId为200,也就是说它被压到了D1启动的任务栈中。

若是在别的应用程序打开D2,假设Other的taskId为200,打开D2,D2会新建一个task运行,假设它的taskId为201,那么如果这时再从D2启动D1或者D3,则又会再创建一个task,因此,若操作步骤为other->D2->D1,这过程就涉及到了3个task了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值