待加入新内容
- 良好的编程习惯
- 独立思考的能力
- 主动并且善于沟通(跟各部门沟通)
反射、注入、注解
常用设计模式
- 简历面试
- 岗位面试
- 大牛面试
不能说不知道,可以提别的问题,要学会拆分
要读源码,读架构,读设计模式
1.选一个擅长的方向,例如 网络框架:Retrofit、Okhttp、Volly 读源码,深入深入再深入,将流程图画出来,能闭着眼睛读出来为止 2. 基础要背(灵活地背) 常用API背下 3. 试着了解这个领域市面上的技术 4. 如果有时间的话,研究其中一个众所周知的库的源码
基本知识点
Activity
它提供一个界面,让用户进行滑动点击
Activity生命周期
- activity4种状态
- running处于活动状态,用户点击屏幕,屏幕会做出响应,处于activity栈顶
- paused失去焦点、被非全屏activity占据、有透明的activity在栈顶位置:但这时候所有成员变量都存在,但当内存紧张时,将会被回收
- stopped当一个activity被另一个activity完全覆盖时,但与paused相同,如果内存不紧张,那么所有的都还在
- killed表明activity不存在
- activity生命周期
- 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启动模式
- standard模式:每次都是重新创建activity。每创建一个Activity,都会走生命周期方法,有很大消耗
- singletop模式:栈顶复用模式,如果已经在栈顶,直接复用栈顶Activity
- singletask模式:(单例模式)栈内复用模式,整个任务栈当中有时调用,以上的activity都销毁
- singleinstance模式:在整个系统当中有且仅有一个实例,Activity独享任务栈 (用时少)
scheme跳转协议
页面内跳转协议,非常好的实现机制。
客户端向H5页面注册一个URLscheme,有scheme去启动对应页面
-
服务端下发url路径,客户端根据服务端下发的url跳转到相应页面。
-
从H5页面跳转到相应的APPActivity
-
App通过url跳转到另一个应用的的界面
Fragment
安卓3.0引入,大屏幕更灵活展现UI。
Fragment为什么成为第五大组件?
-
第五大组件? Fragment有自己的生命周期,它能灵活地加载到Activity中去,所以说Fragment是非独立的,需要依附Activity中去。
-
加载到Activity的两种方式
- 静态加载
- 动态加载
-
FragmentPagerAdapter与FragmentStatePagerAdapter区别
Fragment的生命周期
Fragment之间的通信
Fragment管理器:FragmentManager
handler
只有主线程可以更新UI,如果子线程更新UI的情况下会报错,所以需要更新时由子线程发送通知给主线程。文件的读取、网络数据的获取也需要使用handler。安卓是线程不安全,所以子线程通过handler机制发送消息给主线程更新UI。
什么是handler
handler通过发送和处理Message和Runnable对象来关联相对应线程的MessageQueue。
- 可以让对应的Message和Runnable在未来的某个时间点进行相应处理
- 让自己想要处理的耗时操作放在子线程,让更新UI的操作放在主线程
handler的使用方法
- post(runnable) 执行完后自动绑定到主线程(最终也是调用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内存泄露及解决方法
handler引起的内存泄露以及解决办法
深入知识点
基本知识点的细节
系统核心机制
OkHttp
Okhttp简单使用
- OkHttpClient创建对象client 代表客户端,作为全局实例进行保存,所有http请求可以共用response缓存和线程池,这和Volly一样
- 创建request对象,request包括一些请求的url地址,请求的方法,请求头,请求体,还有一些涉及的标记位等等。我们是使用内部类Builder去生成Request对象。
- 分异步和同步
- okhttp的
同步请求会去调用newCall的execute()方法,会去阻塞当前进程。 - 或者
异步调用newCall的enqueue方法,传回的参数是Callback方法,之后操作在子线程中进行
- okhttp的
- 成功后client会回调onResponse方法获得response对象
源码分析
- OkHttpClient返回的是客户端。使用的内部类的Builder模式,是安卓开发中常用的模式,将复杂对象的构建与它的表示相分离,这样使得同样的构建过程创建不同的表示。在开源框架中对象的创建都是由Builder来创建的。
- execute()方法具体是realCall方法里面执行。
-
同步检查,先进行合法判断,因为每个Call只能被执行一次,想要一个完全的call,就调用capture方法进行克隆
-
dispatcher() Okhttp拦截器的体现(在execute后进行dispatcher().finished()进行关闭)
-
finished() 请求队列关闭
-
真正执行异步请求的是getResponseWithInterceptorChair()方法,该方法内部进行一堆interceptors(okhttp最核心的东西),它将网络请求等各功能合成在一起,再将它合成了一个interceptor.Chair的锁链形式,在此基础上我们可以完成一次完美的网络请求。
-
interceptor里面还会加入的东西
- retryAndFollowUpInterceptor失败重试重定向,在失败后重新设置一个url
- BridgeInterceptor将用户构造的请求转换为发送给服务器的请求,然后将服务器返回的响应转化为对用户友好输出的响应
- CacheIntercepted缓存的拦截器,更新缓存的一个拦截器
- ConnectInterceptor负责和服务器端进行连接的拦截器
- CallServerInterceptor网络的、服务端的连接
-
enqueue异步方法区别
-
Retrofit
使用 运用接口的形式做好封装
- Builder模式创建Retrofit对象,同时加入注解GET下的url
- 创建retrofit.Call的call实例,调用call实例的enqueue方法进行异步操作
源码分析
- 创建一个retrofit对象
- Builder创建者模式下构建的
- 通过Retrofit.create()方法将我们定义的接口转换为接口实例并使用接口中的方法
- 最终的网络请求调用okhttp
动态代理
- 首先,通过method把它转换成ServiceMethod
- 然后,通过serviceMethod,args获取到okHttpCall对象
- 最后,再把okHttpCall进一步封装并返回Call对象