前言

最近没有写什么新博文,
一是太忙了,而且马上有新的挑战来到。
二是赶上过年期间。
三是没有什么太好的题材写。
四是自己在充电在半闭关学习。
计划下篇博文本月更新吧,题材从下列中出一个 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被意外终止时:

  1. Activity会调用onSaveInstanceState()保存数据
  2. 然后Activity会委托Window去保存数据
  3. Window猥琐它的顶级容器去保存数据,顶层容器是一个ViewGroup,一般是DecorView.
  4. 顶层容器一一通知子View来保存数据。

onSaveInstanceState()利用Bundle保存一些数据后,我们可以选择在onCreate()或者onRestoreInstanceState() 中接收这些数据。二者的区别是:

  1. onRestoreInstanceState()一旦被调用,Bundle一定是有值的。
  2. 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中有actioncategorydata
一个Activity可以有多个IntentFilter
一个Intent只要能匹配一组IntentFilter即可。
但是一个Intent必须同时匹配组内IntentFilter内的actioncategorydata

1.11 action的匹配规则

action是一个字符串
一个IntentFilter可以有多个actoin只要Intent中的action能够和IntentFilter中的任何一个action相同,即可匹配成功
如果Intent没有action,匹配失败

总结:Intentaction存在,且和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两部分组成:mimeTypeURI

如果IntentFilter中没有指定URIURI默认值contentfile
所以Intent中的URI部分的scheme必须为content或者file才行。
比如 :

intent.setDataAndType(Uri.parse("file://abc"),"image/png");

同时设置mimeTypeURI必须用setDataAndType 方法。

1.14 匹配时 建议先判断intent是否有Activity能匹配

可以通过PackageMangerresolveActivity 方法 或者 IntentresolveActivity方法判断,找不到会返回null。
这两个方法,第一个参数是intent,第二参数我们要使用intflag值,为MATCH_DEFAULT_ONLY.

PackageManger还有一个queryIntentActivities方法,它返回一个List<ResolveInfo>.

第四章 View的工作原理

第一时间获取View的宽高:

  1. Activity/View#onWindowFocusChanged();
  2. view.post(Runnable)
  3. ViewTreeObserver
  4. 手动view.measure().

自定义View注意事项:

  1. 让View支持wrap_content
  2. View支持padding。ViewGroup支持padding和子View的margin.(View在onDraw中处理。ViewGroup需要在onMeasure()和onLayout()中处理)
  3. View内部可以使用post…方法替代handler.
  4. 如果有线程、动画等,需要停止,防止内存泄漏。需要使用onDetachedFromWindow()
  5. 嵌套滑动

第9章 四大组件的工作过程

四大组件除了广播,其他三种都必须在AndroidManifest里注册。 对于BroadcastReceiver 可以在AndroidManifest里静态注册,也可以在代码中动态注册。

调用时,ContentProvier借助Uri,其他借助Intent。

IApplicationThread 这个Binder接口的实现类完成了和Activity、Service启动、停止相关的功能。

Activity

启动Activity:
startActivity()->
ContextImpl.startActivity()->
Instrumentation->
ActivityManagerService(ActivityManagerNative.getDefault() )
…..
最终回调app.thread.scheduleLaunchActivity().
回到ActivityThread里的ApplicationThreadscheduleLaunchActivity()方法。


值得一提的是,ApplicationThread extends ApplicationThreadNative.
public abstract class ApplicationThreadNative extends Binder implements IApplicationThread {
熟悉Aidl的,一眼可以看出,ApplicationThreadNative就是AIDL生成的Stub类。
在其内部还有一个ApplicationThreadProxy,和AIDL生成的Proxy类一样。内部存储Native,通过Binder机制,IPC调用Native的方法。
class ApplicationThreadProxy implements IApplicationThread {


(此时仍在Binder线程池中)scheduleLaunchActivity()发送消息
->ActivityThread.H.handleMessage()(切换到主线程)
->ActivityThread.handleLaunchActivity()
->ActivityThread.performLaunchActivity()(1 利用反射构造Activity 和 2 Application、3 回调Application的onCreate() 4 创建ContextImpl,5 调用Activity.attach()关联Activity和ContextImpl. 6 调用Activity的onCreate() )
->ActivityThread.handleResumeActivity()(显示界面 ,将View add 进Window中)

Service

运行在主线程。 有启动、和绑定两种状态(可以并存)。停止服务通过 stopService 和unBindService.

startService()过程:

Activity基本一致,
(此时仍在Binder线程池中)ActivityThread.ApplicationThread.scheduleCreateService)发送消息
->ActivityThread.H.handleMessage()(切换到主线程)
->ActivityThread.handleCreateService()
(1 反射构造Service 2 创建ContextImpl 3 得到Application(可能是构造) 4 调用service.attach()关联Service和ContextImpl和Application 5 回调Service的onCreate()方法 6,缓存Service至Map里,key是Binder对象(ServiceRecord))


Service的onStartCommand()是在随后由AMS回调scheduleServiceArgs()
->handleServiceArgs()
(1 从缓存里取出Service 2 回调onStartCommmand())

bindService()过程:

和前述过程基本一致


但是在bindService(Intent,ServiceConnection,int)中传入的ServiceConnection对象,
会在ContextImpl.bindServiceCommon()中被关联转化成一个Binder对象。(因为要跨进程和AMS通信)
->得到待启动Service的进程信息,传入ams,进入ams...
->也会执行onCreate()的流程
->ApplicationThread.scheduleBindService()(此时处于被启动、绑定服务的进程)
->handleBindService()
(1 从缓存里取出Service 2 回调onBind() 3 AMS.publishService(),传入onBind返回的Binder对象,回调告诉客户端ServiceConnection.onServiceConnected())
->回到AMS.publishService()
->在上文的和ServiceConnection关联的Binder中回调。利用请求绑定服务进程的activityThread.post一个消息将进程和线程切换。回调onBind()返回的Binder对象给onServiceConnected()

BroadcastReceiver

动态注册的Receiver需要注销。


动态注册过程和Service,bind 过程类似。
参数BroadcastReceiver要转换成一个Binder对象,传递给AMS。


发送的过程:
向AMS发送一个异步请求。
(3.1+,默认会对intent追加一个flag,忽略已经停止的引用。)

AMS找到匹配的Receiver(Binder对象),内部会利用注册Receiver的activityThread.post一个消息将进程和线程切换。

ContentProvider

内部的insert、delete、update、query 要处理好 线程同步。 因为这几个方法是在Binder线程池中被调用的。

当ContentProvider所在的进程启动时,ContentProvider会同时启动,并发布到AMS中。此时ContentProvider的onCreate()先于Application的onCreate执行。

访问ContentProvider需要通过ContentResolver,它是一个抽象类,实现是ApplicationContentResolver。

ApplicationContentResolver拿Provider时,
**如果是同进程的,那么App一启动就已经注册了。
如果是其他进程的,通过AMS去查。**

拿到的Provider**其实是一个Binder对象,而其中的方法 ,如query,是直接执行的,所以是直接在服务端的Binder线程池中执行。**

总结:

所有的异步回调接口类,最终都会被转换成一个Binder类用于AMS的IPC。
例如ServiceConnectionBroadcastReceiver``,ContentProvider

第11章 Android的线程和线程池

AsyncTask注意事项:

  1. AsyncTask的类必须在主线程中加载,意味着第一次使用到AsyncTask必须在主线程。(4.1以上版本已由系统自动完成。在ActivityThread中调用AsyncTask.init方法。查看23+的源码,内部Handler强制使用Looper.mainLooper();)
  2. Asynctask的创建必须在主线程。
  3. execute()方法必须在主线程中调用。
  4. 不要直接调用onPostExecute()….等回调。
  5. 一个AsyncTask只能执行一次,只能调用一次execute()方法,否则crash。
  6. 1.6之前,AsyncTask是串行执行任务的。从1.6开始,改为线程池并行处理任务。但从3.0开始,为避免并发错误,又改为了串行执行。但提供了executeOnExecutor()来并行执行任务。

《艺术探索》读书笔记(更新中)相关推荐

  1. Android开发艺术探索读书笔记(一)

    首先向各位严重推荐主席这本书<Android开发艺术探索>. 再感谢主席邀请写这篇读书笔记 + 书评.书已经完整的翻完一遍了,但是还没有细致的品读并run代码,最近有时间正好系统的把整本书 ...

  2. Android开发艺术探索 读书笔记

    啥也不说了,@主席的<Android开发艺术探索>真是业界良心之作,不得不看!感谢主席,膜拜主席!主席主席,我要跟你生猴子!(>^ω^<) 读书笔记中若有任何问题请留言告知,谢 ...

  3. Android 开发艺术探索 - 读书笔记目录

    仅作为读书笔记使用,建议阅读原书. 书中代码部分已和现版本不符,建议对比最新版本学习. 读了这本书,越发认识到和大佬们的差距.嗯,加油吧. 过去の自分が今仆の土台となる 第 1 章 - Activit ...

  4. Android开发艺术探索读书笔记

    前言 Android开发艺术(这本书真的是艺术,太崇拜刚哥了,值得每一个做Android开发刷十遍的书) 1,Activity生命周期和启动模式 典型情况下的生命周期分析 onCreate() onS ...

  5. Android开发艺术探索读书笔记(第5章 RemoteView)

    原理 RemoteView的作用是在其他进程中显示并更新view界面. 大量的IPC操作会影响效率,为了解决这个问题,系统并没有通过Binder去直接支持View的跨进程访问,而是提供了一个Actio ...

  6. Android开发艺术探索读书笔记(二)

    首先感谢大家支持,昨天第一篇写出来之后反响很好,主席本人也非常赞赏(捂脸-),再接再厉,推出第二篇.这篇的主要内容是对两章View的内容进行总结.不得不说,自定义View是很多开发者的痛点,一方面我们 ...

  7. 《硬核linux攻略》读书笔记更新中

    linux具有不同的三种接口:系统调用接口.库函数接口.应用程序接口. 用户启动shell窗口下进行工作. shell里先运行输入的命令行中的第一个字符串,搜索这个程序名,找到了就运行同时挂起shel ...

  8. 《爱的艺术》读书笔记作文3800字

    <爱的艺术>读书笔记作文3800字: 本书的封里是这么介绍作者的:"艾里希·弗洛姆(1900-1980),美国著名社会心理学家.精神分析学家和哲学家.弗洛姆的研究根植于弗洛伊德的 ...

  9. 《JavaScript DOM 编程艺术》读书笔记

    <JavaScript DOM 编程艺术>读书笔记--其一 第二章 1.Javascript代码编写方式: (1)将JavaScript代码放在文档<head>标签中的< ...

  10. 《android开发艺术探索》笔记之Bitmap的加载和Cache

    <Android开发艺术探索>笔记之Bitmap的加载和Cache<一> 我放暑假前,就在图书馆借了一本<Android开发艺术探索>,这也是我看到很多人推荐的.之 ...

最新文章

  1. SourceInsight 4.0 之三 常用宏使用、编辑、修改详解(附最新完善版本的宏)
  2. LinuxC-运算符
  3. WPF 基础控件之 DataGrid 样式
  4. oracle standby同步,PRIMARY Standby不能同步问题
  5. Java语言实现简单FTP软件------FTP软件远程窗口的实现(六)
  6. js上传本地文件到oss
  7. matlab 密文搜索 实验,基于B^+树的多关键字密文排序检索方法.pdf
  8. 论文阅读:SPR:Supervised Personalized Ranking Based on Prior Knowledge for Recommendation
  9. matlab 空间后方交会,摄影测量空间后方交会.docx
  10. (bat)检查今天星期几,并执行程序
  11. 搞笑新闻联播之老公岗位制度(上)铃声 搞笑新闻联播之老公岗...
  12. 微信公众号对接电影网站,回复名称推送电影
  13. 诺基亚C5智能手机的功能非常好,并具有一定程度的可取性
  14. 制作64M启动型+系统维护U盘,支持WINPE+CDLinux+DOS7
  15. elment ui 修改时间选择器的宽度及高度
  16. 百词斩2018年秋招面试题
  17. 网络规划设计师难考吗?
  18. word2013无法加载endnotex9解决方法
  19. 多乐影视电影网站开发——HTML+CSS+JavaScript+PHP
  20. 数据结构与算法(Python版) | (6) 线性结构---队列、双端队列和列表

热门文章

  1. CAD2010安装→注册
  2. 医学图像分类_深度学习与医学图像分析
  3. OpenCV4学习笔记(71)——散焦图像去模糊滤波
  4. stata计量之前数据清洗的必备步骤
  5. url的中文转码和解码
  6. HTML+CSS+JavaScript仿京东购物商城网站 web前端制作服装购物商城 html电商购物网站...
  7. php 爬虫图片,随机图片API-json格式基于python爬虫和PHP
  8. 发动机关键零部件3D视觉引导自动上料和装配系统
  9. unity学习之可编程渲染管线 SRP Batcher
  10. 《Python知识手册》V2.1版,高清PDF免费获取