package com.google.android.agera;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import java.lang.ref.WeakReference;
/**
* Shared per-thread worker Handler behind internal logic of various Agera classes.
*
* Agera 内的工作 Handler
*/
final class WorkerHandler extends Handler {
/*
* BaseObservable.observableActivated()
*/
static final int MSG_FIRST_ADDED = 0;
/*
* BaseObservable.observableDeactivated()
*/
static final int MSG_LAST_REMOVED = 1;
/*
* BaseObservable.sendUpdate()
*/
static final int MSG_UPDATE = 2;
/*
* Updatable.update()
*/
static final int MSG_CALL_UPDATABLE = 3;
/*
* CompiledRepository.maybeStartFlow()
*/
static final int MSG_CALL_MAYBE_START_FLOW = 4;
/*
* CompiledRepository.acknowledgeCancel()
*/
static final int MSG_CALL_ACKNOWLEDGE_CANCEL = 5;
/*
* ThreadLocal 存放
* 当前线程 的一个 WorkerHandler 的弱引用
*/
private static final ThreadLocal<WeakReference<WorkerHandler>> handlers = new ThreadLocal<>();
/*
* 定义一个 IdentityMultiMap
* 用于存放 观察者,和该观察者 对应的 被观察者的 token
*/
@NonNull
private final IdentityMultimap<Updatable, Object> scheduledUpdatables;
/**
* 从 ThreadLocal 取出 当前线程的 一个 WorkerHandler 的弱引用
* 没有的话,进行实例化,添加到 ThreadLocal 中存储,并返回
*
* @return WorkerHandler
*/
@NonNull
static WorkerHandler workerHandler() {
final WeakReference<WorkerHandler> handlerReference = handlers.get();
WorkerHandler handler = handlerReference != null ? handlerReference.get() : null;
if (handler == null) {
handler = new WorkerHandler();
handlers.set(new WeakReference<>(handler));
}
return handler;
}
private WorkerHandler() {
this.scheduledUpdatables = new IdentityMultimap<>();
}
/**
* 删除 一个 观察者
*
* @param updatable 观察者
* @param token 观察者 对应的 被观察者 的 token
*/
synchronized void removeUpdatable(@NonNull final Updatable updatable,
@NonNull final Object token) {
scheduledUpdatables.removeKeyValuePair(updatable, token);
}
/**
* 只有 updatableObservable 内不存在 此次的 updatable 作为 key
* 就通知观察者 Updatable.update()
*
* @param updatable updatable
* @param token 观察者 对应的 被观察者 的 token
*/
synchronized void update(@NonNull final Updatable updatable, @NonNull final Object token) {
if (scheduledUpdatables.addKeyValuePair(updatable, token)) {
obtainMessage(WorkerHandler.MSG_CALL_UPDATABLE, updatable).sendToTarget();
}
}
/**
* 分发消息
*
* @param message message
*/
@Override
public void handleMessage(final Message message) {
switch (message.what) {
case MSG_UPDATE:
((BaseObservable) message.obj).sendUpdate();
break;
case MSG_FIRST_ADDED:
((BaseObservable) message.obj).observableActivated();
break;
case MSG_LAST_REMOVED:
((BaseObservable) message.obj).observableDeactivated();
break;
case MSG_CALL_UPDATABLE:
final Updatable updatable = (Updatable) message.obj;
scheduledUpdatables.removeKey(updatable);
updatable.update();
break;
case MSG_CALL_MAYBE_START_FLOW:
((CompiledRepository) message.obj).maybeStartFlow();
break;
case MSG_CALL_ACKNOWLEDGE_CANCEL:
((CompiledRepository) message.obj).acknowledgeCancel();
break;
default:
}
}
}