1. LeakCanary 工作原理详解
1.1 核心组件
- RefWatcher: 负责监控对象引用
- HeapDumper: 负责生成内存快照
- HeapAnalyzer: 负责分析内存快照
- AndroidHeapDumper: Android平台特定的dump实现
1.2 详细工作流程
graph TD
A[初始化] --> B[注册Activity生命周期]
B --> C[Activity.onDestroy]
C --> D[RefWatcher.watch]
D --> E[创建KeyedWeakReference]
E --> F[触发GC]
F --> G{检查引用是否存在}
G -->|存在| H[可能存在泄漏]
G -->|不存在| I[正常回收]
H --> J[生成heap dump]
J --> K[分析引用链]
K --> L[通知用户]
1.3 关键代码实现
class RefWatcher {
fun watch(watchedReference: Any) {
// 创建唯一标识
val key = UUID.randomUUID().toString()
// 创建弱引用
val reference = KeyedWeakReference(
watchedReference,
key,
referenceQueue
)
// 检查是否泄漏
checkRetainedExecutor.execute {
removeWeaklyReachableReferences()
if (gone(reference)) return@execute
// 可能存在泄漏,dump heap
dumpHeap()
}
}
}
2. EventBus 实现原理深度解析
2.1 核心概念
- 订阅者(Subscriber): 接收事件的对象
- 发布者(Publisher): 发送事件的对象
- 事件(Event): 传递的消息对象
- 订阅方法(SubscribeMethod): 处理事件的方法
2.2 详细工作流程
graph TD
A[注册订阅者] --> B[解析订阅方法]
B --> C[保存订阅信息]
D[发送事件] --> E[查找订阅者]
E --> F[事件分发]
F --> G[调用订阅方法]
H[粘性事件] --> I[保存到内存]
I --> J[新订阅者注册]
J --> K[立即接收事件]
2.3 核心实现代码
public class EventBus {
// 订阅者注册表
private final Map<Class<?>, CopyOnWriteArrayList<Subscription>> subscriptionsByEventType;
// 事件类型查找表
private final Map<Object, List<Class<?>>> typesBySubscriber;
// 注册订阅者
public void register(Object subscriber) {
Class<?> subscriberClass = subscriber.getClass();
// 查找订阅方法
List<SubscriberMethod> subscriberMethods =
subscriberMethodFinder.findSubscriberMethods(subscriberClass);
// 遍历订阅方法进行注册
for (SubscriberMethod method : subscriberMethods) {
subscribe(subscriber, method);
}
}
// 发送事件
public void post(Object event) {
// 获取当前线程的PostingThreadState
PostingThreadState postingState = currentPostingThreadState.get();
// 获取事件队列
List<Object> eventQueue = postingState.eventQueue;
eventQueue.add(event);
if (!postingState.isPosting) {
postingState.isPosting = true;
try {
while (!eventQueue.isEmpty()) {
postSingleEvent(eventQueue.remove(0), postingState);
}
} finally {
postingState.isPosting = false;
}
}
}
}
3. Interceptor 拦截器深入解析
3.1 拦截器类型
-
应用拦截器(Application Interceptor)
- 不需要担心中间响应比如重定向和重试
- 只调用一次,即使HTTP响应是从缓存中获取
- 可以访问应用程序设置的请求
-
网络拦截器(Network Interceptor)
- 可以操作中间响应比如重定向和重试
- 可以访问网络层的请求
- 可以访问Connection信息
3.2 责任链模式实现
graph LR
A[应用拦截器] --> B[网络拦截器]
B --> C[缓存拦截器]
C --> D[连接拦截器]
D --> E[请求服务器]
3.3 详细代码实现
// 拦截器接口
interface Interceptor {
fun intercept(chain: Chain): Response
interface Chain {
fun request(): Request
fun proceed(request: Request): Response
}
}
// 实际的拦截器链实现
class RealInterceptorChain(
private val interceptors: List<Interceptor>,
private val index: Int,
private val request: Request,
private val call: Call
) : Interceptor.Chain {
override fun proceed(request: Request): Response {
// 调用下一个拦截器
val next = RealInterceptorChain(
interceptors, index + 1, request, call)
val interceptor = interceptors[index]
return interceptor.intercept(next)
}
}
// 日志拦截器示例
class LoggingInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
println("发送请求: ${request.url}")
val response = chain.proceed(request)
println("收到响应: ${response.code}")
return response
}
}
3.4 具体方案
让我详细讲解 Android 中 Interceptor 拦截器的应用场景和实现。
1. Interceptor 常见应用场景
1.1 统一请求头管理
class HeaderInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val originalRequest = chain.request()
// 添加通用 Header
val newRequest = originalRequest.newBuilder()
.header("Content-Type", "application/json")
.header("Accept", "application/json")
.header("Authorization", "Bearer ${TokenManager.getToken()}")
.header("platform", "android")
.header("version", BuildConfig.VERSION_NAME)
.build()
return chain.proceed(newRequest)
}
}
1.2 网络日志记录
class LoggingInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
val startTime = System.nanoTime()
Log.d("HTTP", "发送请求: ${request.url}")
Log.d("HTTP", "请求头: ${request.headers}")
val response = chain.proceed(request)
val endTime = System.nanoTime()
Log.d("HTTP", "接收响应: ${response.code}")
Log.d("HTTP", "响应时间: ${(endTime - startTime) / 1e6}ms")
return response
}
}
1.3 缓存控制
class CacheInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
if (!NetworkUtils.isNetworkAvailable()) {
// 无网络时强制使用缓存
val newRequest = request.newBuilder()
.cacheControl(CacheControl.FORCE_CACHE)
.build()
return chain.proceed(newRequest)
}
// 有网络时的缓存策略
val newRequest = request.newBuilder()
.header("Cache-Control", "public, max-age=60") // 缓存60秒
.build()
return chain.proceed(newRequest)
}
}
1.4 请求重试
class RetryInterceptor(private val maxRetries: Int = 3) : Interceptor {
override fun intercept(chain: Chain): Response {
val request = chain.request()
var response: Response? = null
var retryCount = 0
while (retryCount < maxRetries) {
try {
response = chain.proceed(request)
if (response.isSuccessful) {
return response
}
} catch (e: IOException) {
if (retryCount == maxRetries - 1) throw e
}
retryCount++
Log.d("HTTP", "重试次数: $retryCount")
}
return response!!
}
}
1.5 参数加密
class EncryptInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
val originalRequest = chain.request()
// 获取原始参数
val originalBody = originalRequest.body
if (originalBody is FormBody) {
val builder = FormBody.Builder()
// 遍历并加密参数
for (i in 0 until originalBody.size) {
val name = originalBody.name(i)
val value = originalBody.value(i)
builder.add(name, EncryptUtils.encrypt(value))
}
// 添加时间戳和签名
val timestamp = System.currentTimeMillis()
builder.add("timestamp", timestamp.toString())
builder.add("sign", generateSign(timestamp))
// 构建新的请求
val newRequest = originalRequest.newBuilder()
.method(originalRequest.method, builder.build())
.build()
return chain.proceed(newRequest)
}
return chain.proceed(originalRequest)
}
}
2. 实际应用示例
2.1 网络请求配置
class NetworkConfig {
fun createOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.addInterceptor(HeaderInterceptor())
.addInterceptor(LoggingInterceptor())
.addInterceptor(CacheInterceptor())
.addInterceptor(RetryInterceptor())
.addInterceptor(EncryptInterceptor())
// 缓存配置
.cache(Cache(
directory = File(context.cacheDir, "http_cache"),
maxSize = 10L * 1024L * 1024L // 10 MB
))
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
}
}
2.2 错误处理拦截器
class ErrorHandlingInterceptor : Interceptor {
override fun intercept(chain: Chain): Response {
try {
val response = chain.proceed(chain.request())
// 处理业务错误码
val responseBody = response.body?.string()
val jsonObject = JSONObject(responseBody)
when (jsonObject.optInt("code")) {
401 -> { // 未授权
EventBus.getDefault().post(TokenExpiredEvent())
throw UnauthorizedException()
}
500 -> { // 服务器错误
throw ServerException(jsonObject.optString("message"))
}
200 -> { // 成功
return response.newBuilder()
.body(ResponseBody.create(
response.body?.contentType(),
responseBody
))
.build()
}
else -> {
throw ApiException(
jsonObject.optInt("code"),
jsonObject.optString("message")
)
}
}
} catch (e: Exception) {
throw when (e) {
is SocketTimeoutException -> TimeoutException()
is UnknownHostException -> NetworkException()
else -> e
}
}
}
}
2.3 进度监听拦截器
class ProgressInterceptor(
private val progressListener: ProgressListener
) : Interceptor {
override fun intercept(chain: Chain): Response {
val originalResponse = chain.proceed(chain.request())
return originalResponse.newBuilder()
.body(ProgressResponseBody(
originalResponse.body!!,
progressListener
))
.build()
}
}
class ProgressResponseBody(
private val responseBody: ResponseBody,
private val progressListener: ProgressListener
) : ResponseBody() {
private var bufferedSource: BufferedSource? = null
override fun contentType() = responseBody.contentType()
override fun contentLength() = responseBody.contentLength()
override fun source(): BufferedSource {
if (bufferedSource == null) {
bufferedSource = source(responseBody.source()).buffer()
}
return bufferedSource!!
}
private fun source(source: Source): Source {
return object : ForwardingSource(source) {
var totalBytesRead = 0L
override fun read(sink: Buffer, byteCount: Long): Long {
val bytesRead = super.read(sink, byteCount)
totalBytesRead += if (bytesRead != -1L) bytesRead else 0
progressListener.onProgress(
totalBytesRead,
responseBody.contentLength(),
bytesRead == -1L
)
return bytesRead
}
}
}
}
3. 最佳实践
3.1 拦截器顺序
graph LR
A[应用拦截器] --> B[Header拦截器]
B --> C[日志拦截器]
C --> D[缓存拦截器]
D --> E[重试拦截器]
E --> F[错误处理拦截器]
F --> G[网络拦截器]
3.2 完整网络配置示例
@Module
class NetworkModule {
@Provides
@Singleton
fun provideOkHttpClient(
context: Context,
tokenManager: TokenManager
): OkHttpClient {
return OkHttpClient.Builder()
// 应用拦截器
.addInterceptor(HeaderInterceptor(tokenManager))
.addInterceptor(LoggingInterceptor())
.addInterceptor(CacheInterceptor(context))
.addInterceptor(RetryInterceptor())
.addInterceptor(ErrorHandlingInterceptor())
.addInterceptor(EncryptInterceptor())
// 网络拦截器
.addNetworkInterceptor(StethoInterceptor()) // 调试工具
// 其他配置
.cache(Cache(
directory = context.cacheDir,
maxSize = 10 * 1024 * 1024L
))
.connectTimeout(15, TimeUnit.SECONDS)
.readTimeout(15, TimeUnit.SECONDS)
.writeTimeout(15, TimeUnit.SECONDS)
.build()
}
}
通过合理使用这些拦截器,我们可以实现:
- 统一的网络请求处理
- 灵活的缓存策略
- 全局的错误处理
- 网络请求的监控和调试
- 安全性保护
这些拦截器的使用大大提高了网络请求的可维护性和扩展性。
4. Glide 缓存机制详解
4.1 缓存层级
-
内存缓存
- Active Resources (活动资源)
- Memory Cache (内存缓存)
-
磁盘缓存
- Resource Cache (资源缓存)
- Data Cache (原始数据缓存)
4.2 缓存流程
graph TD
A[请求图片] --> B{检查Active Resources}
B -->|命中| C[返回图片]
B -->|未命中| D{检查Memory Cache}
D -->|命中| E[移动到Active]
D -->|未命中| F{检查Disk Cache}
F -->|命中| G[加载到内存]
F -->|未命中| H[网络请求]
H --> I[保存到磁盘]
I --> J[加载到内存]
4.3 核心实现代码
public class Engine {
private final ActiveResources activeResources;
private final MemoryCache memoryCache;
private final DiskCache diskCache;
public Resource<?> load(Key key) {
// 1. 检查活动资源
Resource<?> active = activeResources.get(key);
if (active != null) {
return active;
}
// 2. 检查内存缓存
Resource<?> cached = memoryCache.remove(key);
if (cached != null) {
activeResources.activate(key, cached);
return cached;
}
// 3. 检查磁盘缓存
File cached = diskCache.get(key);
if (cached != null) {
Resource<?> resource = decode(cached);
activeResources.activate(key, resource);
return resource;
}
// 4. 从网络加载
return null;
}
}
5. ViewModel 原理深入解析
5.1 核心功能
- 数据持久化
- 在配置更改时保持数据
- 避免重复加载数据
- 生命周期管理
- 自动清理资源
- 避免内存泄漏
- 数据共享
- Fragment 之间共享数据
- Activity 与 Fragment 之间共享数据
5.2 实现原理流程图
graph TD
A[Activity/Fragment创建] --> B[获取ViewModelStore]
B --> C[创建ViewModel]
C --> D[存储在ViewModelStore]
E[配置变更] --> F[重建Activity]
F --> G[恢复ViewModelStore]
G --> H[获取已存在ViewModel]
I[Activity真正销毁] --> J[清理ViewModelStore]
5.3 关键代码实现
class ViewModelStore {
private val map = HashMap<String, ViewModel>()
fun put(key: String, viewModel: ViewModel) {
map[key] = viewModel
}
fun get(key: String): ViewModel? {
return map[key]
}
fun clear() {
for (vm in map.values) {
vm.clear()
}
map.clear()
}
}
class ViewModelProvider(
private val store: ViewModelStore,
private val factory: Factory
) {
fun <T : ViewModel> get(modelClass: Class<T>): T {
val key = modelClass.canonicalName!!
val viewModel = store.get(key)
if (modelClass.isInstance(viewModel)) {
return viewModel as T
}
val newViewModel = factory.create(modelClass)
store.put(key, newViewModel)
return newViewModel
}
}
6. ButterKnife 实现原理详解
6.1 工作流程
- 注解处理器
- 编译时扫描注解
- 生成绑定代码
- 代码生成
- 生成 ViewBinding 类
- 实现 findViewById 逻辑
- 运行时绑定
- 反射创建 ViewBinding 实例
- 完成视图绑定
6.2 详细流程图
graph TD
A[编译时] --> B[扫描注解]
B --> C[生成绑定类]
D[运行时] --> E[创建绑定类实例]
E --> F[执行findViewById]
F --> G[完成视图绑定]
6.3 核心实现代码
public class Butterknife {
public static void bind(Activity target) {
View sourceView = target.getWindow().getDecorView();
bind(target, sourceView);
}
private static void bind(Object target, View source) {
Class<?> targetClass = target.getClass();
Constructor<?> constructor;
try {
// 查找生成的绑定类
Class<?> bindingClass = Class.forName(
targetClass.getName() + "_ViewBinding");
constructor = bindingClass.getConstructor(
targetClass, View.class);
// 创建绑定实例
constructor.newInstance(target, source);
} catch (Exception e) {
throw new RuntimeException("Unable to bind views for " +
targetClass.getName(), e);
}
}
}
// 生成的绑定类示例
public class MainActivity_ViewBinding {
private MainActivity target;
public MainActivity_ViewBinding(MainActivity target, View source) {
this.target = target;
// 绑定视图
target.textView = source.findViewById(R.id.text_view);
target.button = source.findViewById(R.id.button);
}
}
7. RxJava 背压原理详解
7.1 背压策略详解
-
ERROR
- 当队列满时抛出 MissingBackpressureException
- 适用于无法容忍数据丢失的场景
-
BUFFER
- 无限缓存所有数据
- 可能导致 OOM
- 适用于数据量可控的场景
-
DROP
- 丢弃无法处理的数据
- 适用于实时数据处理
-
LATEST
- 只保留最新数据
- 适用于只关心最新状态的场景
7.2 实现原理流程
graph TD
A[上游发送数据] --> B{检查策略}
B -->|ERROR| C[抛出异常]
B -->|BUFFER| D[加入缓存队列]
B -->|DROP| E[丢弃数据]
B -->|LATEST| F[更新最新数据]
G[下游处理] --> H[request请求数据]
H --> I[处理数据]
7.3 示例代码实现
public class RxJavaExample {
public void backpressureExample() {
// 创建被观察者
Flowable.create(emitter -> {
for (int i = 0; i < 1000000; i++) {
if (emitter.isCancelled()) {
return;
}
emitter.onNext(i);
}
emitter.onComplete();
}, BackpressureStrategy.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<Integer>() {
private Subscription subscription;
@Override
public void onSubscribe(Subscription s) {
this.subscription = s;
// 请求处理的数据量
s.request(Long.MAX_VALUE);
}
@Override
public void onNext(Integer value) {
// 处理数据
System.out.println("Received: " + value);
}
@Override
public void onError(Throwable t) {
t.printStackTrace();
}
@Override
public void onComplete() {
System.out.println("Completed");
}
});
}
}
7.4 背压实现机制
-
请求量控制
- 通过 request(n) 方法控制数据请求量
- 实现了 Publisher-Subscriber 模式
-
数据缓存
- 使用 Queue 实现数据缓存
- 根据不同策略处理溢出数据
-
线程调度
- subscribeOn() 控制发送线程
- observeOn() 控制接收线程
这些框架的深入理解对于Android开发至关重要,它们都采用了不同的设计模式和实现机制来解决特定的问题。理解这些原理不仅有助于更好地使用这些框架,也能帮助我们在实际开发中做出更好的技术选择。