/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.android.agera;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import java.util.Arrays;
import static android.os.SystemClock.elapsedRealtime;
import static com.google.android.agera.Preconditions.checkNotNull;
import static com.google.android.agera.Preconditions.checkState;
import static com.google.android.agera.WorkerHandler.MSG_LAST_REMOVED;
import static com.google.android.agera.WorkerHandler.MSG_UPDATE;
import static com.google.android.agera.WorkerHandler.workerHandler;
/**
* A partial implementation of {@link Observable} that adheres to the threading contract between
* {@link Observable}s and {@link Updatable}s. Subclasses can use {@link #observableActivated()}
* and
* {@link #observableDeactivated()} to control the activation and deactivation of this observable,
* and to send out notifications to client updatables with {@link #dispatchUpdate()}.
*
* <p>For cases where subclassing {@link BaseObservable} is impossible, for example when the
* potential class already has a base class, consider using {@link Observables#updateDispatcher()}
* to help implement the {@link Observable} interface.
*/
public abstract class BaseObservable implements Observable {
/*
* 申请好一个 静态 长度为0 的对象数组
*/
@NonNull
private static final Object[] NO_UPDATABLES_OR_HANDLERS = new Object[0];
/*
* 保存一个 WorkerHandler
*/
@NonNull
private final WorkerHandler handler;
/*
* 创建一个 token 来标识 自身
*/
@NonNull
private final Object token = new Object();
/*
* 最小的更新时间间隔
*/
final int shortestUpdateWindowMillis;
/*
* 用于存放 观察者 和 观察者对应的 Handler
*/
@NonNull
private Object[] updatablesAndHandlers;
/*
* 用于记录 行为
* size++ 的话,是执行过了 add(...),并且 在 updatablesAndHandlers 中, 存放了 观察者 和 观察者对应的 Handler
* size-- 的话,是执行过了 remove(...),并且 在 updatablesAndHandlers 中, 删除了 观察者 和 观察者对应的 Handler
*/
private int size;
/*
* 记录 上次 更新的时候
*/
private long lastUpdateTimestamp;
/*
* 相当于一个 过程锁
* 在发送 通过 给 观察者时 会锁上( dispatchUpdate() )
* 处理后,会打开
*/
private boolean pendingUpdate = false;
/**
* 默认的
* 最少的更新时间间隔 = 0
*/
protected BaseObservable() {
this(0);
}
/**
* 构造方法
* 需要 最少的更新时间间隔
*
* @param shortestUpdateWindowMillis 最少的更新时间间隔
*/
BaseObservable(final int shortestUpdateWindowMillis) {
checkState(Looper.myLooper() != null, "Can only be created on a Looper thread");
this.shortestUpdateWindowMillis = shortestUpdateWindowMillis;
this.handler = workerHandler();
this.updatablesAndHandlers = NO_UPDATABLES_OR_HANDLERS;
this.size = 0;
}
/**
* 添加一个 观察者
*
* @param updatable 观察者
*/
@Override
public final void addUpdatable(@NonNull final Updatable updatable) {
checkState(Looper.myLooper() != null, "Can only be added on a Looper thread");
checkNotNull(updatable);
boolean activateNow = false;
synchronized (token) {
// 观察者 和 其对应的 WorkerHandler
add(updatable, workerHandler());
// 如果 执行 add(...) 成功了
if (size == 1) {
/*
* 1.如果 执行 BaseObservable.observableDeactivated() 的消息
* 还在队列中,则删除
*
* 2. 判断是否在 主线程
* 然后 activateNow = true
*
* 3. 如果 1. 2. 都不是
* 发送 执行 BaseObservable.observableActivated() 的消息
*/
if (handler.hasMessages(MSG_LAST_REMOVED, this)) {
handler.removeMessages(MSG_LAST_REMOVED, this);
} else if (Looper.myLooper() == handler.getLooper()) {
activateNow = true;
} else {
handler.obtainMessage(WorkerHandler.MSG_FIRST_ADDED, this).sendToTarget();
}
}
}
/*
* 如果在主线程
* 回调 observableActivated()
*/
if (activateNow) {
observableActivated();
}
}
/**
* 删除一个 观察者
*
* @param updatable 观察者
*/
@Override
public final void removeUpdatable(@NonNull final Updatable updatable) {
checkState(Looper.myLooper() != null, "Can only be removed on a Looper thread");
checkNotNull(updatable);
synchronized (token) {
// 删除 观察者 和 其对应的 Handler
remove(updatable);
// 如果 执行 remove(...) 成功了
if (size == 0) {
// 发送 执行 BaseObservable.observableDeactivated() 的 消息
handler.obtainMessage(MSG_LAST_REMOVED, this).sendToTarget();
// 删除 执行 BaseObservable.sendUpdate() 的 消息
handler.removeMessages(MSG_UPDATE, this);
// 解 dispatchUpdate() 上的 锁
pendingUpdate = false;
}
}
}
/**
* 通知所有观察者
* Notifies all registered {@link Updatable}s.
*/
protected final void dispatchUpdate() {
synchronized (token) {
// 检查 过程锁
if (!pendingUpdate) {
// 锁上
pendingUpdate = true;
// 发送 执行 BaseObservable.sendUpdate() 的消息
handler.obtainMessage(MSG_UPDATE, this).sendToTarget();
}
}
}
/**
* 添加 观察者 和 其对应的 WorkerHandler
*
* @param updatable 观察者
* @param handler 观察者 的 WorkerHandler
*/
private void add(@NonNull final Updatable updatable, @NonNull final Handler handler) {
int indexToAdd = -1;
for (int index = 0; index < updatablesAndHandlers.length; index += 2) {
// 判断是否 添加过 这个 观察者
if (updatablesAndHandlers[index] == updatable) {
throw new IllegalStateException("Updatable already added, cannot add.");
}
// 存在空位,记录下来,用于添加
if (updatablesAndHandlers[index] == null) {
indexToAdd = index;
}
}
// 如果数组满了,就扩容
if (indexToAdd == -1) {
indexToAdd = updatablesAndHandlers.length;
updatablesAndHandlers = Arrays.copyOf(updatablesAndHandlers,
indexToAdd < 2 ? 2 : indexToAdd * 2);
}
// 然后添加 观察者 和 其对应的 Handler
updatablesAndHandlers[indexToAdd] = updatable;
updatablesAndHandlers[indexToAdd + 1] = handler;
// 记录为 添加成功
size++;
}
/**
* 删除 观察者 和 其对应的 Handler
*
* @param updatable 观察者
*/
private void remove(@NonNull final Updatable updatable) {
for (int index = 0; index < updatablesAndHandlers.length; index += 2) {
// 找到 该 观察者
if (updatablesAndHandlers[index] == updatable) {
// 找到 该 观察者 对应的 Handler
WorkerHandler handler = (WorkerHandler) updatablesAndHandlers[index + 1];
// 在 该 Handler 情况 观察者的数据 和 token 信息
handler.removeUpdatable(updatable, token);
updatablesAndHandlers[index] = null;
updatablesAndHandlers[index + 1] = null;
// 记录为 删除成功
size--;
return;
}
}
throw new IllegalStateException("Updatable not added, cannot remove.");
}
/**
* 通知 该 被观察者上
* 所有的 观察者
*/
void sendUpdate() {
synchronized (token) {
// 只有 锁上( true )才能通知
if (!pendingUpdate) {
return;
}
/*
* 如果有 最小的更新时间间隔
*/
if (shortestUpdateWindowMillis > 0) {
// 记录 此时
final long elapsedRealtimeMillis = elapsedRealtime();
// 记录 此时-上次更新时间 之间的间隔
final long timeFromLastUpdate = elapsedRealtimeMillis - lastUpdateTimestamp;
// 如果 时间间隔 小于 最小的更新时间间隔
if (timeFromLastUpdate < shortestUpdateWindowMillis) {
/*
* 延迟发送,延迟时间 = 最小的更新时间间隔-时间间隔 的时间
* 重新 执行 BaseObservable.sendUpdate() 的消息
*/
handler.sendMessageDelayed(
handler.obtainMessage(WorkerHandler.MSG_UPDATE, this),
shortestUpdateWindowMillis - timeFromLastUpdate);
return;
}
lastUpdateTimestamp = elapsedRealtimeMillis;
}
// 打开 锁
pendingUpdate = false;
/*
* 逐个 找到 每个 观察者 后
* 再找到 对应的 Handler
* 用 Handler 去发送 执行 Updatable.update() 的消息
*/
for (int index = 0; index < updatablesAndHandlers.length; index = index + 2) {
final Updatable updatable = (Updatable) updatablesAndHandlers[index];
final WorkerHandler handler =
(WorkerHandler) updatablesAndHandlers[index + 1];
if (updatable != null) {
handler.update(updatable, token);
}
}
}
}
/**
* Called from the worker looper thread when this {@link Observable} is activated by
* transitioning
* from having no client {@link Updatable}s to having at least one client {@link Updatable}.
*
* 被观察者 被激活时( 成功添加一个观察者后 )
*/
protected void observableActivated() {}
/**
* Called from the worker looper thread when this {@link Observable} is deactivated by
* transitioning from having at least one client {@link Updatable} to having no client
* {@link Updatable}s.
*
* 被观察者 被失效时( 成功删除一个观察者后 )
*/
protected void observableDeactivated() {}
}