学习笔记

87 阅读7分钟

待加入新内容

  1. 良好的编程习惯
  2. 独立思考的能力
  3. 主动并且善于沟通(跟各部门沟通)

反射、注入、注解

常用设计模式

  1. 简历面试
  2. 岗位面试
  3. 大牛面试

不能说不知道,可以提别的问题,要学会拆分

要读源码,读架构,读设计模式

1.选一个擅长的方向,例如 网络框架:Retrofit、Okhttp、Volly 读源码,深入深入再深入,将流程图画出来,能闭着眼睛读出来为止 2. 基础要背(灵活地背) 常用API背下 3. 试着了解这个领域市面上的技术 4. 如果有时间的话,研究其中一个众所周知的库的源码

基本知识点

Activity

它提供一个界面,让用户进行滑动点击

Activity生命周期

  1. activity4种状态
    • running处于活动状态,用户点击屏幕,屏幕会做出响应,处于activity栈顶
    • paused失去焦点、被非全屏activity占据、有透明的activity在栈顶位置:但这时候所有成员变量都存在,但当内存紧张时,将会被回收
    • stopped当一个activity被另一个activity完全覆盖时,但与paused相同,如果内存不紧张,那么所有的都还在
    • killed表明activity不存在
  2. activity生命周期

image.png

- Activity启动:onCreate、onStart(能看见不能交互)、onResume(可交互,也可以初始化一些资料)
- 点击Home键回到主界面(Activity不可见):onPause、onStop(表明Activity paused)
- 再次回到原Activity:onRestart(Activity从不可见状态到可见状态)、onStart、onResume
- 退出当前Activity:onPause、onStop、onDestroy

3. android进程优先级 - 前台进程:处于前台与用户交互 - 可见进程:用户可见但无法点击 - 服务进程:在后台开启一个Service服务 - 后台进程:pasued或stop进程,尚未因为内存不足而killed的进程 - 空进程:优先级最低 安卓系统可以随时杀掉它

Activity任务栈

我们需要启动模式,所以我们需要任务栈 当离开时 需要将任务栈所有内容销毁,安全保存任务栈

一个Activity可以启动任务栈

Activity启动模式

  1. standard模式:每次都是重新创建activity。每创建一个Activity,都会走生命周期方法,有很大消耗
  2. singletop模式:栈顶复用模式,如果已经在栈顶,直接复用栈顶Activity
  3. singletask模式:(单例模式)栈内复用模式,整个任务栈当中有时调用,以上的activity都销毁
  4. singleinstance模式:在整个系统当中有且仅有一个实例,Activity独享任务栈 (用时少)

scheme跳转协议

页面内跳转协议,非常好的实现机制。

客户端向H5页面注册一个URLscheme,有scheme去启动对应页面

  1. 服务端下发url路径,客户端根据服务端下发的url跳转到相应页面。

  2. 从H5页面跳转到相应的APPActivity

  3. App通过url跳转到另一个应用的的界面

Fragment

安卓3.0引入,大屏幕更灵活展现UI。

Fragment为什么成为第五大组件?

  1. 第五大组件? Fragment有自己的生命周期,它能灵活地加载到Activity中去,所以说Fragment是非独立的,需要依附Activity中去。

  2. 加载到Activity的两种方式

    • 静态加载
    • 动态加载
  3. FragmentPagerAdapter与FragmentStatePagerAdapter区别

Fragment的生命周期

Fragment之间的通信

Fragment管理器:FragmentManager

handler

只有主线程可以更新UI,如果子线程更新UI的情况下会报错,所以需要更新时由子线程发送通知给主线程。文件的读取、网络数据的获取也需要使用handler。安卓是线程不安全,所以子线程通过handler机制发送消息给主线程更新UI。

什么是handler

handler通过发送和处理Message和Runnable对象来关联相对应线程的MessageQueue。

  1. 可以让对应的Message和Runnable在未来的某个时间点进行相应处理
  2. 让自己想要处理的耗时操作放在子线程,让更新UI的操作放在主线程

handler的使用方法

  1. post(runnable) 执行完后自动绑定到主线程(最终也是调用2方法)
  2. sendMessage(messgae)
    • 创建handler
    • 复写handleMessage方法
    • 通过Message的值进行不同的处理操作
    • 创建msg对象 通过arg1,arg2进行赋值
    • 通过sendMessage() 将值传入

handler机制的原理

Looper从MessageQuene中获取消息,交由Handler(即发送该消息的Handler)的 dispatchMessage方法传递消息, 然后返回到Handler所在线程,目标Handler收到消息,调用 handleMessage方法,接收消息

在子线程执行完耗时操作,当Handler发送消息时,将会调用 MessageQueue.enqueueMessage,向消息队列中添加消息。 当通过 Looper.loop开启循环后,会不断地从消息池中读取消息,即调用 MessageQueue.next, 然后调用目标Handler(即发送该消息的Handler)的 dispatchMessage方法传递消息, 然后返回到Handler所在线程,目标Handler收到消息,调用 handleMessage方法,接收消息,处理消息。

handler内存泄露及解决方法

image.png

handler引起的内存泄露以及解决办法

深入知识点

基本知识点的细节

系统核心机制

OkHttp

Okhttp简单使用

  1. OkHttpClient创建对象client 代表客户端,作为全局实例进行保存,所有http请求可以共用response缓存和线程池,这和Volly一样
  2. 创建request对象,request包括一些请求的url地址,请求的方法,请求头,请求体,还有一些涉及的标记位等等。我们是使用内部类Builder去生成Request对象。
  3. 分异步和同步
    • okhttp的同步请求会去调用newCall的execute()方法,会去阻塞当前进程。
    • 或者异步调用newCall的enqueue方法,传回的参数是Callback方法,之后操作在子线程中进行
  4. 成功后client会回调onResponse方法获得response对象

源码分析

image.png

image.png

  1. OkHttpClient返回的是客户端。使用的内部类的Builder模式,是安卓开发中常用的模式,将复杂对象的构建与它的表示相分离,这样使得同样的构建过程创建不同的表示。在开源框架中对象的创建都是由Builder来创建的。
  2. execute()方法具体是realCall方法里面执行。
    1. 同步检查,先进行合法判断,因为每个Call只能被执行一次,想要一个完全的call,就调用capture方法进行克隆

    2. dispatcher() Okhttp拦截器的体现(在execute后进行dispatcher().finished()进行关闭)

    3. finished() 请求队列关闭

    4. 真正执行异步请求的是getResponseWithInterceptorChair()方法,该方法内部进行一堆interceptors(okhttp最核心的东西),它将网络请求等各功能合成在一起,再将它合成了一个interceptor.Chair的锁链形式,在此基础上我们可以完成一次完美的网络请求。

    5. interceptor里面还会加入的东西

      • retryAndFollowUpInterceptor失败重试重定向,在失败后重新设置一个url
      • BridgeInterceptor将用户构造的请求转换为发送给服务器的请求,然后将服务器返回的响应转化为对用户友好输出的响应
      • CacheIntercepted缓存的拦截器,更新缓存的一个拦截器
      • ConnectInterceptor负责和服务器端进行连接的拦截器
      • CallServerInterceptor网络的、服务端的连接
    6. enqueue异步方法区别

Retrofit

使用 运用接口的形式做好封装

  1. Builder模式创建Retrofit对象,同时加入注解GET下的url
  2. 创建retrofit.Call的call实例,调用call实例的enqueue方法进行异步操作

源码分析

  1. 创建一个retrofit对象
    • Builder创建者模式下构建的
  2. 通过Retrofit.create()方法将我们定义的接口转换为接口实例并使用接口中的方法
  3. 最终的网络请求调用okhttp

动态代理

  1. 首先,通过method把它转换成ServiceMethod
  2. 然后,通过serviceMethod,args获取到okHttpCall对象
  3. 最后,再把okHttpCall进一步封装并返回Call对象