android开发艺术探索 笔记(一)

2017-05-03  本文已影响0人  M1chaelY0ung

第一章Activity的启动与生命周期

正常情况下的启动状态
onCreate加载布局,初始化数据
onStart界面可视化,但尚在后台,不可交互。
onRestart从不可见(onStop)到可见(onStart)需要经过onRestart
onResume从后台到前台,Activity变得可以交互。
onPause一般onPause后紧接着onStop,所以不推荐将耗时的操作放在这里。
×当新的Activity为透明时,原先Activity还是可视的,因而不会执行onStop
onStop从不可互动到不可视,如点击home键回到桌面,这是Activity一般还没有被销毁,等待着onRestart->onStart->onResume重新恢复状态
onDestroy销毁Activity,并进行一些回收工作,如关闭数据库等。
一张应该出现过很多遍的图

基于书上说的屏幕的点亮熄灭以及手指的触摸,我个人试了一下

界面一切·从简,就是默认emptyActivity的界面
每个方法写都写一个Log.d("ActivityLife","onXXXX");//XXXX视方法而定

Activity刚启动时: onCreate->onStart->onResume


启动时

点击返回键,关闭程序时:onPause->onStop->onDestroy


退出
点击home键:onPause->onStop
后台

从后台唤醒:onRestart->onStart->onResume


唤醒
一直到这里,都和我们在前面的理论是一样的。
锁屏时,其实和挂到后台是一样的
锁屏
当唤醒屏幕时,如果有密码的话,唤醒之后是要输入密码,这个时候Activity的界面依旧不可见,因此不会调用以上的任何方法,只有解锁后,Activity重新可见时,又会执行之前从后台唤醒相同的步骤
唤醒
从Activity1启动Activity2,会先执行Activity1的onPause,然后创建Activity2(onCreate->onStart->onResume)再执行Activity1的onStop.
一些小细节
关于生命周期的重点在于onStart、onStop控制的是Activity是否可见(在后台),onResume、onPause控制的是Activity是否在前台可供操作。
异常情况下的生命周期

而onSaveInstanceState是系统自行销毁Activity时对数据的保存。重新打开时调用onRestoreInstanceState恢复数据。即异常情况下销毁Activity时,会调用这两个方法恢复数据。而横竖屏就属于这种异常情况。


横竖屏
资源不足导致的Activity被销毁
Activity的优先级
configChanges

当系统配置发生改变时,Activity会重新创建,如果在Activity指定configChanges属性,Activity就会执行configChanges的属性,而不用重新创建了。
如横竖屏切换:

manifests中配置
android:configChanges = "orientation"
//多个属性用|
@Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        Log.d("ActivityLife","onConfigChanged:"+newConfig.orientation);
    }

Activity创建后,从竖屏到横屏再到竖屏的过程中


没用调用onSaveInstanceState和onRestoreInstanceState方法,也没有重新创建Activity configChanges的一些属性

常用的是locale、orientation和keyboardHidden
×android4.0以上orientation要注意配置screensize,不然还是会调用onCreate
使用configChanges:orientation时,就不会使用oSaveInstanceState和onRestoreInstanceState来恢复数据了,因为都没有销毁。。。

Activity的启动模式
Activity的LaunchMode

任务栈是一个“后进先出”的栈结构,每次finish()处于前台的Activity就会出栈,直到栈为空为止,当栈中无任何Activity的时候,系统就会回收这个任务栈。

关于四个启动模式的流程图->http://www.jianshu.com/p/7a11ff292423
LaunchMode的使用方法
在manifests中activity下
android:launchMode="singleInstance"
或者在intent中addFlag
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
这里第二种方法的优先级更高,而区别在于第一种方法不能使用FLAG_ACTIVITY_CLEAR_TOP,第二种不能设置singleInstance。

这里书中还提到了TaskAffinity和AllowTaskReparenting两个属性
TaskAffinity标识了Activity所需的任务栈的名字
AllowTaskReparenting="true"时,例子如下:
A启动B的ActivityC,ActivityC刚好是这个属性,此时C会在A的任务栈中。当按下home键再打开应用B时,会直接打开ActivityC,而不是默认的首页面。此时ActivityC会从A的任务栈转移到B的任务栈

adb shell dumpsys activity命令可以详细的了解当前任务栈情况
Activity的Flags
有该标识的Activity将不会出现在历史Activity列表中,xml中等同于:
android:exculdeFromRecents="true"```
#####IntentFliter的匹配规则
- 显式调用
明确表示启动对象的包名类名
- 隐式调用
需要Intent匹配IntentFliter所设置的过滤信息
- 一个Activity可以有多个IntentFliter,一个IntentFliter可以有多个action、category或是data。
- 其中Intent需要同时匹配一个IntentFliter中的三种(action、category和data)信息。
- 一个Activity中只要匹配一个IntentFliter就可以了。

- #####Action
action系统有预定义的,当然我们也能自己定义,其中intent中action必须与IntentFliter中一个action匹配。(没有就默认不匹配)还有一点就是action区分大小写
- #####Category
category系统有预定义的,当然我们也能自己定义。category与action不同的是:intent中没有category是默认匹配成功的。如果intent定义了category,则要求intent中所有的category都是intentFliter的category中的一个。
- #####data
data的匹配模式与action类似,都需要至少一个匹配。

data的语法
<data android:scheme="string"
android:host="string"
android:port="string"
android:path="string"
android:pathPattern="string"
android:pathPrefix="string"
android:mimeType="string"/>

data由两部分组成,URI和mimeType。URI指定类似于路径的状态,mimeType指定媒体数据
- URI的结构有mimeType前面的scheme、host、port、path、pathPattern、pathPrefix组成。

<scheme>://<host>:<port>/{<path>|<pathPrefix>|<pathPattern>}
对应:
content://com.example.project:200/folder/subfolder/etc
http://www.baidu.com:80/search/info

- scheme:URI的模式,如http、file、content等,若没有指定scheme,URI是无效的。
- Host:URIde主机名,URI中不能为空
- Port:URI的端口号,scheme和host都指定了才有意义。
- Path、pathPattern、pathPrefix:三个参数表述路径信息。

Path指定完整路径
pathPattern也指定完整路径,但是可以使用通配符"",""表示0或多个字符。由于正则表达式的规范,真实字符串中""要用"\"表示,""要用"\\"表示
pathPrefix表示路径的前缀信息

当没有指定URI时,URI默认为content和file。
Intent添加data信息:

如果要指定完整data信息,需要setDataAndType
intent.setDataAndType(Uri.parse("file://abc"),"image/png");
使用setData和setType会彼此擦除对方的值

这里data比action特殊的还有一点,就是:

<intent-filter...>
<data android:scheme="file" android:host="www.baidu.com"/>
...
</intent-filter>

<intent-filter...>
<data android:scheme="file"/>
<data android:host="www.baidu.com"/>
...
</intent-filter>

上面的两种方法是一样的。
当我们隐式启动一个Activity的时候,可以做一下判断,看是否能匹配到我们的隐式Intent,如果不做判断没找到对应的Activity系统就会抛出android.content.ActivityNotFoundException异常。
采用PackageManager的resolveActivity方法或者Intent的resolveActivity方法,如果找不到匹配的Activity就会返回null,我们通过判断返回值就可以规避上述错误了。
######接收隐式意图的Activity必须有<category android:name="android.intent.category.DEFAULT"/>,这个category的作用在于上述两个方法只要不返回null,就能启动Activity。
######有一类action和category的共同作用是标明这是一个入口Activity,并且会出现在系统的应用列表中,少一个都没有任何意义,也不会出现在系统的应用列表中。

<action android:name="android.intent.action.MAIN" />
//最先启动的activity
<category android:name="android.intent.category.LAUNCHER" />
//桌面的图标,显示在程序列表中


####知识点总结的比较全,难听点就是笔记太啰嗦了吧,感觉都有点重要,整章的内容都快要都写进来了。
####这一章的内容不是特别多,但我还是写的有些杂乱,或许写多了,就好了吧
上一篇 下一篇

猜你喜欢

热点阅读