–
最近没有写什么新博文,
一是太忙了,而且马上有新的挑战来到。
二是赶上过年期间。
三是没有什么太好的题材写。
四是自己在充电在半闭关学习。
计划下篇博文本月更新吧,题材从下列中出一个 Retrofit 、组件化、自定义View
最近重读《艺术探索》,将其中一些对我有用的、我仍然不知道的、或者觉得容易混淆的知识点整理出来。
部分也有可能是我自己总结整理出来的经验,一并放在里面。
第1章 Activity的生命周期和启动模式
1.1 生命周期,Activity从 不可见变成可见,onRestart()
会重新调用(按Home,从别的Activity返回)
1.2 但onPause()
方法回调后,才会执行新Activity的onCreate()
1.3 关于onSaveInstanceState()
。
back返回时不调用。
Home时会被调用。
启动一个新的Activity时 会被调用。
并不是和onRestoreInstanceState()
成对出现。
出现在 onStop()
前面.
(书上说和onPause()
没有关系,可能在前可能在后。)
该方法只有在Activity 即将可能被销毁,并且有机会重新的创建显示才会调用。
按Home、启动新Activity,这个Activity都是后台Activity了,可能被销毁,但是销毁后,还是有机会重新创建的,所以会回调。
而正常的back,不会会重新创建了,所以不回调。
1.4 关于onRestoreInstanceState()
。
出现在onStart()
后面。
1.5 关于上述两个方法
系统已经在这两个方法中,onRestoreInstanceState()
onSaveInstanceState()
.为我们做了一定的恢复工作,例如ListView的滚动位置,EditText的输入数据。
针对每一个View,系统能为我们自动恢复哪些数据,可以查看View的源码,也有onRestoreInstanceState()
onSaveInstanceState()
方法。
关于保存和恢复,是一个典型的委托思想,工作流程如下:
Activity被意外终止时:
-
Activity会调用
onSaveInstanceState()
保存数据 -
然后Activity会委托Window去保存数据
-
Window猥琐它的顶级容器去保存数据,顶层容器是一个ViewGroup,一般是DecorView.
-
顶层容器一一通知子View来保存数据。
onSaveInstanceState()
利用Bundle保存一些数据后,我们可以选择在onCreate()
或者onRestoreInstanceState()
中接收这些数据。二者的区别是:
-
onRestoreInstanceState()
一旦被调用,Bundle一定是有值的。 -
onCreate()
里要对Bundle判空。
官方建议是前者。
1.6 singleTop、singleTask、singleInstance
生命周期,onPause()
->onNewIntent()
->onResume()
1.7 singleTask 默认具有 cleaerTop的效果
1.8 singleInstance 只能单独的位于一个任务栈中。
1.9 TaskAffinity
这个参数标识了一个Activity所需要的任务栈的名字。
默认情况下,所有Activity所需的任务栈的名字是 应用的包名。
形式为aaa.bbb.ccc 。
TaskAffinity
主要和singleTask启动模式
或者allowTaskReparenting属性
配对使用。
1.10 IntentFilter的匹配规则(隐式调用)
IntentFilter
中有action
、category
、data
。
一个Activity
可以有多个IntentFilter
。
一个Intent
只要能匹配一组IntentFilter
即可。
但是一个Intent
必须同时匹配组内该IntentFilter
内的action
、category
、data
。
1.11 action的匹配规则
action
是一个字符串。
一个IntentFilter
内可以有多个actoin
,只要Intent
中的action
能够和IntentFilter
中的任何一个action
相同,即可匹配成功。
如果Intent
中没有action
,匹配失败。
总结:Intent
中action
存在,且和IntentFilter
中一个action
相同。
1.12 category的匹配规则
category
是一个字符串。
和action
不同。Intent
中如果含有category
,则所有category
必须和IntentFilter
中的一个category
匹配。
如果Intent
中没有category
,也能匹配成功。
原因是系统在调用startActivity
或者startActivityForResult
时,默认会为Intent
加上"android.intent.category.DEFAULT"
的category
。
所以我们的Activity
若想支持隐式调用,则必须要加上这个category
。
1.13 data 的匹配规则
和action
类似。如果IntentFilter
中定义了data
,那么Intent
中必须也要有匹配的data
。
data结构:
<data android:scheme=“string”
android:host=“string”
android:port=“string”
android:path=“string”
andorid:pathPattern=“string”
android:pathPrefix=“string”
android:mimeType=“string” />
data
由两部分组成:mimeType
和URI
。
如果IntentFilter
中没有指定URI
,URI
的默认值是content
和file
。
所以Intent
中的URI
部分的scheme
必须为content
或者file
才行。
比如 :
intent.setDataAndType(Uri.parse(“file://abc”),“image/png”);
同时设置mimeType
和URI
必须用setDataAndType
方法。
1.14 匹配时 建议先判断intent是否有Activity能匹配
可以通过PackageManger
的resolveActivity
方法 或者 Intent
的resolveActivity
方法判断,找不到会返回null。
这两个方法,第一个参数是int ent
,第二参数我们要使用int
的flag
值,为MATCH_DEFAULT_ONLY
.
PackageManger
还有一个queryIntentActivities
方法,它返回一个List<ResolveInfo>
.
第四章 View的工作原理
第一时间获取View的宽高:
-
Activity/View#onWindowFocusChanged();
-
view.post(Runnable)
-
ViewTreeObserver
-
手动view.measure().
自定义View注意事项:
-
让View支持wrap_content
-
View支持padding。ViewGroup支持padding和子View的margin.(View在onDraw中处理。ViewGroup需要在onMeasure()和onLayout()中处理)
-
View内部可以使用post…方法替代handler.
-
如果有线程、动画等,需要停止,防止内存泄漏。需要使用onDetachedFromWindow()
-
嵌套滑动
第9章 四大组件的工作过程
四大组件除了广播,其他三种都必须在AndroidManifest里注册。 对于BroadcastReceiver 可以在AndroidManifest里静态注册,也可以在代码中动态注册。
调用时,ContentProvier借助Uri,其他借助Intent。
IApplicationThread 这个Binder接口的实现类完成了和Activity、Service启动、停止相关的功能。
Activity
启动Activity: