Android 总结

Activity


Activity是Android 四大组合之一,在应用中表现为用户界面,显示各种UI元素。
Activity生命周期:onCreate, onStart, onResume, onPause, onStop, onDestroy, onRestart.

Activity视图层级图

image.png

从图中可以看出,Acitvity下有个PhoneWindow,这个PhoneWindow是Window实现类,下面包含了一个DecorView,实际上这个才是顶级视图。

Activity 启动模式 standard, singleTop, singleTask, singleInstance

//配置方式
<activity ndroid:launchMode="standard" > 

standard-默认模式

每次启动一个Activity都会重写创建一个新的实例,不管这个实例存不存在,这种模式下,谁启动了该模式的Activity,该Activity就属于启动它的Activity的任务栈中。

singleTop-栈顶复用模式
这个模式下,如果新的activity已经位于栈顶,那么这个Activity不会被重写创建,同时它的onNewIntent方法会被调用,需要注意的是这个Activity它的onCreate(),onStart()方法不会被调用,因为它并没有发生改变。

singleTop模式分3种情况
当前栈中已有该Activity的实例并且该实例位于栈顶时,不会新建实例,而是复用栈顶的实例,并且会将Intent对象传入,回调onNewIntent方法.当前栈中已有该Activity的实例但是该实例不在栈顶时,其行为和standard启动模式一样,依然会创建一个新的实例

singleTask-栈内复用模式
如果栈中存在这个Activity的实例就会复用这个Activity,不管它是否位于栈顶,复用时,会将它上面的Activity全部出栈,并且会回调该实例的onNewIntent方法。其实这个过程还存在一个任务栈的匹配,因为这个模式启动时,会在自己需要的任务栈中寻找实例,这个任务栈就是通过taskAffinity属性指定。如果这个任务栈不存在,则会创建这个任务栈。

Service总结


Service 基础使用

Service 的生命周期相对与Activity 比较简单,只有3个分别为:onCreate、onStartCommand各onDestory。

  1. 在项目的任何位置调用了Context的startService() 函数,相应的服务就会开启。
    首次创建时会调用onCreate方法,然后会回调onStartCommand()函数。
  2. 服务开启后一直保持运行,直到调用stopService()或stopSelf(),服务会停止。
  3. 每调用一次startService(),onStartCommand(),就会运行一次,但实际上服务只会创建一个实例。
  4. service 是运行在UI 线程中,不要直接做耗时操作,否则是新那些子线程。

IntentService 总结

IntentService 是 Android 提供直接运行在子线程的Service.这个只会只会执行一次,执行完后会自动高stopSelf自我销毁。它是Service 的子类。重写onHandleIntent()该方法是在子线程中运行

Android 中的消息机制 总结

先看一张图


image.png

先理解Handler, Looper, MessageQueue, Message 之间的关系,Handler都会关联一MessageQueue,而MessageQueue被封闭在Looper中,而Looper又会关联一个线程,最终就等于每个消息队列都会关联一个线程。
Handler 是一个消息处理器,把Message发送到MessageQueue中,然后在通过对应的线程Looper把消息取出进行处理.也就是说Handler在什么线程处理消息,取决于它对应的Looper所在的线程。

消息是怎样被处理的?答案是通过Looper.loop(),该方法就是一个死循环,然后通过消息队列逐步取出消息,然后调用dispatchMessage(msg);(target 是Handler类型)

image.png

在子线程中创建Handler为什么会异常?这是因为该线程中的Looper还没有创建,因为sThreadLocal.get()返回 为NUll,Handler就是与MessageQueue建立联系,如果没有MessageQueue Handler没有存在的意义。
解决方法如下:

               //1为当前线程创建Looper,关绑定在ThreadLocal中。
                Looper.prepare();
                Handler handler =new Handler();
                //2启动消息的循环
                Looper.loop();

RxJava


RxJava基础使用

1. 定义

RxJava 是一个 基于事件流、实现异步操作的库

2. 作用

实现异步操作
类似于 Android中的 AsyncTaskHandler作用

3. 特点

  • 逻辑简洁
  • 实现优雅
  • 使用简单
    更重要的是,随着程序逻辑的复杂性提高,它依然能够保持简洁 & 优雅
image

4. 实现步骤

  1. 创建事件 Observable.create
  2. 创建观察者 Observer
  3. 订阅observable.subsribe

Retrofit


retrofit基本使用

Retrofit, 其实是对okhttp一个封闭,它本身不做网络请求,只是生成请求的对象。

  • retrofit 扩展
    OkHttpClient:Retrofit使用OkHttpClient来实现网络请求,这个OkHttpClient虽然不能替换成其他网络执行框架,比如Volley,但是对他进行扩展,最简单的就是使用它的Interceptor拦截器。

  • addConverterFactory:对返回数据类型的自动转换。

  • addCallAdapterFactory:对网络工作对象callWorker的自动转换。把Retrofit中执行的网络请求的Call对象,转换为接口定义的Call对象。

Retrofit实现原理-函数解析、网络请求、数据转换

image

根据接口定义解析函数,得到函数的具体定义,生成对应的ServiceMethod。然后根据这个ServiceMethod,实现一个OkHttpClient的Call对象,负责在Retrofit底层实现网络访问。其中在网络访问返回网络数据,根据ServiceMethod实现数据转换。最后利用适配器,把OkHttpCall对象转换为接口要求的Call网络请求对象

Retrofit 使用流程

  1. 通过接口来描述请求的行为与请求参数
  2. 创建Retrofit实例
  3. 创建一个代理对象
  4. 接口调用
  5. 执行与回调

java 动态代理


实现原理
设计动态代理类(DynamicProxy)时,不需要显式实现与目标对象类(RealSubject)相同的接口,而是将这种实现推迟到程序运行时由 JVM来实现

优点

  • 只需要1个动态代理类就可以解决创建多个静态代理的问题,避免重复、多余代码
  • 更强的灵活性

缺点

  • 效率低
    相比静态代理中 直接调用目标对象方法,动态代理则需要先通过Java反射机制 从而 间接调用目标对象方法
  • 应用场景局限

使用步骤

  1. 声明 调用处理器类 (实现InvocationHandler 接口)
  2. 声明目标对象类的抽象接口
  3. 声明目标对象类
  4. 通过动态代理对象,调用目标对象的方法
结论:动态代理增加运行前与运行后的两个切面,一种额外的能力,统一处理需求

Application启动流程


参考原文:

关键类说明

整个启动流程因为会涉及到多次Binder通信,这里先简要说明一下几个类的用途,方便大家理解整个交互流程:

  • ActivityManagerService :Android中最核心的服务之一,主要负责系统中四大组件的启动、切换、调度及应用进程的管理和调度等工作,它本身也是一个Binder的实现类。
  • Instrumentation :它用来监控应用程序和系统的交互。
  • ActivityThread :应用的入口类,系统通过调用main函数,开启消息循环队列。ActivityThread所在线程被称为应用的主线程(UI线程)。
  • ApplicationThread :ApplicationThread提供Binder通讯接口,AMS则通过代理调用此App进程的本地方法。
  • ActivityManagerProxy :AMS服务在当前进程的代理类,负责与AMS通信。
  • ApplicationThreadProxy :ApplicationThread在AMS服务中的代理类,负责与ApplicationThread通信。

启动App流程

用户点击Home上的一个App图标, 启动一个应用时:

image

Click事件会调用startActivity(Intent), 会通过Binder IPC机制, 最终调用到ActivityManagerService. 该Service会执行如下操作:

  • 第一步通过PackageManager的resolveIntent()收集这个intent对象的指向信息.
  • 指向信息被存储在一个intent对象中.
  • 下面重要的一步是通过grantUriPermissionLocked()方法来验证用户是否有足够的权限去调用该intent对象指向的Activity.
  • 如果有权限, ActivityManagerService会检查并在新的task中启动目标activity.
  • 现在, 是时候检查这个进程的ProcessRecord是否存在了.

如果ProcessRecord是null, ActivityManagerService会创建新的进程来实例化目标activity.

创建进程

ActivityManagerService调用startProcessLocked()方法来创建新的进程, 该方法会通过前面讲到的socket通道传递参数给Zygote进程. Zygote孵化自身, 并调用ZygoteInit.main()方法来实例化ActivityThread对象并最终返回新进程的pid.

ActivityThread随后依次调用Looper.prepareLoop()和Looper.loop()来开启消息循环.

流程图如下:

image.png

2.2 绑定Application

接下来要做的就是将进程和指定的Application绑定起来. 这个是通过上节的ActivityThread对象中调用bindApplication()方法完成的. 该方法发送一个BIND_APPLICATION的消息到消息队列中, 最终通过handleBindApplication()方法处理该消息. 然后调用makeApplication()方法来加载App的classes到内存中.

流程如下:

image.png

2.3 启动Activity

经过前两个步骤之后, 系统已经拥有了该application的进程. 后面的调用顺序就是普通的从一个已经存在的进程中启动一个新进程的activity了.

实际调用方法是realStartActivity(), 它会调用application线程对象中的sheduleLaunchActivity()发送一个LAUNCH_ACTIVITY消息到消息队列中, 通过 handleLaunchActivity()来处理该消息.

假设点击的是一个视频浏览的App, 其流程如下:


image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,427评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,551评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,747评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,939评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,955评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,737评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,448评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,352评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,834评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,992评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,133评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,815评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,477评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,022评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,147评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,398评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,077评论 2 355

推荐阅读更多精彩内容