花瓣 v4.6.12版本的 MD5 值为:6a3515d4d16d98931f1b3d25a91b257e

以下内容为反编译后的 HandlerController.java 源代码,内容仅作参考


package io.realm;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import io.realm.internal.IdentitySet;
import io.realm.internal.RealmObjectProxy;
import io.realm.internal.Row;
import io.realm.internal.async.BadVersionException;
import io.realm.internal.async.QueryUpdateTask;
import io.realm.internal.log.RealmLog;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.Future;
public final class HandlerController implements Handler.Callback {
    static final int COMPLETED_ASYNC_REALM_OBJECT = 63245986;
    static final int COMPLETED_ASYNC_REALM_RESULTS = 39088169;
    static final int COMPLETED_UPDATE_ASYNC_QUERIES = 24157817;
    static final int LOCAL_COMMIT = 165580141;
    private static final Boolean NO_REALM_QUERY = Boolean.TRUE;
    static final int REALM_ASYNC_BACKGROUND_EXCEPTION = 102334155;
    static final int REALM_CHANGED = 14930352;
    private boolean autoRefresh;
    final BaseRealm realm;
    private Future updateAsyncQueriesTask;
    final CopyOnWriteArrayList<RealmChangeListener<? extends BaseRealm>> changeListeners = new CopyOnWriteArrayList<>();
    final List<WeakReference<RealmChangeListener<? extends BaseRealm>>> weakChangeListeners = new CopyOnWriteArrayList();
    private final ReferenceQueue<RealmResults<? extends RealmModel>> referenceQueueAsyncRealmResults = new ReferenceQueue<>();
    private final ReferenceQueue<RealmResults<? extends RealmModel>> referenceQueueSyncRealmResults = new ReferenceQueue<>();
    final ReferenceQueue<RealmModel> referenceQueueRealmObject = new ReferenceQueue<>();
    final Map<WeakReference<RealmResults<? extends RealmModel>>, RealmQuery<? extends RealmModel>> asyncRealmResults = new IdentityHashMap();
    final Map<WeakReference<RealmObjectProxy>, RealmQuery<? extends RealmModel>> emptyAsyncRealmObject = new ConcurrentHashMap();
    final IdentitySet<WeakReference<RealmResults<? extends RealmModel>>> syncRealmResults = new IdentitySet<>();
    final ConcurrentHashMap<WeakReference<RealmObjectProxy>, Object> realmObjects = new ConcurrentHashMap<>();
    private final List<Runnable> pendingOnSuccessAsyncTransactionCallbacks = new ArrayList();

    public HandlerController(BaseRealm baseRealm) {
        this.realm = baseRealm;
    }

    private void collectAsyncRealmResultsCallbacks(List<RealmResults<? extends RealmModel>> list) {
        collectRealmResultsCallbacks(this.asyncRealmResults.keySet().iterator(), list);
    }

    private void collectRealmResultsCallbacks(Iterator<WeakReference<RealmResults<? extends RealmModel>>> it, List<RealmResults<? extends RealmModel>> list) {
        while (it.hasNext()) {
            RealmResults<? extends RealmModel> realmResults = it.next().get();
            if (realmResults == null) {
                it.remove();
            } else if (realmResults.isLoaded()) {
                realmResults.syncIfNeeded();
                list.add(realmResults);
            }
        }
    }

    private void collectSyncRealmResultsCallbacks(List<RealmResults<? extends RealmModel>> list) {
        collectRealmResultsCallbacks(this.syncRealmResults.keySet().iterator(), list);
    }

    private void completedAsyncQueriesUpdate(QueryUpdateTask.Result result) {
        int compareTo = this.realm.sharedGroupManager.getVersion().compareTo(result.versionID);
        if (compareTo > 0) {
            RealmLog.d("COMPLETED_UPDATE_ASYNC_QUERIES realm:" + this + " caller is more advanced, Looper will updates queries");
            return;
        }
        if (compareTo != 0) {
            RealmLog.d("COMPLETED_UPDATE_ASYNC_QUERIES realm:" + this + " caller is behind  advance_read");
            try {
                this.realm.sharedGroupManager.advanceRead(result.versionID);
            } catch (BadVersionException e2) {
                throw new IllegalStateException("Failed to advance Caller Realm to Worker Realm version", e2);
            }
        }
        ArrayList arrayList = new ArrayList(result.updatedTableViews.size());
        for (Map.Entry<WeakReference<RealmResults<? extends RealmModel>>, Long> entry : result.updatedTableViews.entrySet()) {
            WeakReference<RealmResults<? extends RealmModel>> key = entry.getKey();
            RealmResults<? extends RealmModel> realmResults = key.get();
            if (realmResults == null) {
                this.asyncRealmResults.remove(key);
            } else {
                realmResults.swapTableViewPointer(entry.getValue().longValue());
                realmResults.syncIfNeeded();
                arrayList.add(realmResults);
                RealmLog.d("COMPLETED_UPDATE_ASYNC_QUERIES realm:" + this + " updating RealmResults " + key);
            }
        }
        collectSyncRealmResultsCallbacks(arrayList);
        notifyAllListeners(arrayList);
        this.updateAsyncQueriesTask = null;
    }

    private void completedAsyncRealmObject(QueryUpdateTask.Result result) {
        WeakReference<RealmObjectProxy> next;
        RealmObjectProxy realmObjectProxy;
        RealmQuery<? extends RealmModel> realmQuery;
        Set<WeakReference<RealmObjectProxy>> keySet = result.updatedRow.keySet();
        if (keySet.size() <= 0 || (realmObjectProxy = (next = keySet.iterator().next()).get()) == null) {
            return;
        }
        int compareTo = this.realm.sharedGroupManager.getVersion().compareTo(result.versionID);
        if (compareTo == 0) {
            long longValue = result.updatedRow.get(next).longValue();
            if (longValue != 0 && this.emptyAsyncRealmObject.containsKey(next)) {
                this.emptyAsyncRealmObject.remove(next);
                this.realmObjects.put(next, NO_REALM_QUERY);
            }
            realmObjectProxy.realmGet$proxyState().onCompleted$realm(longValue);
            realmObjectProxy.realmGet$proxyState().notifyChangeListeners$realm();
        } else if (compareTo > 0) {
            if (RealmObject.isValid(realmObjectProxy)) {
                RealmLog.d("[COMPLETED_ASYNC_REALM_OBJECT " + realmObjectProxy + "] , realm:" + this + " RealmObject is already loaded, just notify it.");
                realmObjectProxy.realmGet$proxyState().notifyChangeListeners$realm();
                return;
            }
            RealmLog.d("[COMPLETED_ASYNC_REALM_OBJECT " + realmObjectProxy + "] , realm:" + this + " RealmObject is not loaded yet. Rerun the query.");
            Object obj = this.realmObjects.get(next);
            if (obj != null && obj != NO_REALM_QUERY) {
                realmQuery = (RealmQuery) obj;
            } else {
                realmQuery = this.emptyAsyncRealmObject.get(next);
            }
            BaseRealm.asyncTaskExecutor.submitQueryUpdate(QueryUpdateTask.newBuilder().realmConfiguration(this.realm.getConfiguration()).addObject(next, realmQuery.handoverQueryPointer(), realmQuery.getArgument()).sendToHandler(this.realm.handler, COMPLETED_ASYNC_REALM_OBJECT).build());
        } else {
            throw new IllegalStateException("Caller thread behind the Worker thread");
        }
    }

    private void completedAsyncRealmResults(QueryUpdateTask.Result result) {
        Set<WeakReference<RealmResults<? extends RealmModel>>> keySet = result.updatedTableViews.keySet();
        if (keySet.size() > 0) {
            WeakReference<RealmResults<? extends RealmModel>> next = keySet.iterator().next();
            RealmResults<? extends RealmModel> realmResults = next.get();
            if (realmResults == null) {
                this.asyncRealmResults.remove(next);
                RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] realm:" + this + " RealmResults GC'd ignore results");
                return;
            }
            int compareTo = this.realm.sharedGroupManager.getVersion().compareTo(result.versionID);
            if (compareTo == 0) {
                if (!realmResults.isLoaded()) {
                    RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] , realm:" + this + " same versions, using results (RealmResults is not loaded)");
                    realmResults.swapTableViewPointer(result.updatedTableViews.get(next).longValue());
                    realmResults.syncIfNeeded();
                    realmResults.notifyChangeListeners(false);
                    return;
                }
                RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] , realm:" + this + " ignoring result the RealmResults (is already loaded)");
            } else if (compareTo > 0) {
                if (!realmResults.isLoaded()) {
                    RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] , realm:" + this + " caller is more advanced & RealmResults is not loaded, rerunning the query against the latest version");
                    RealmQuery<? extends RealmModel> realmQuery = this.asyncRealmResults.get(next);
                    BaseRealm.asyncTaskExecutor.submitQueryUpdate(QueryUpdateTask.newBuilder().realmConfiguration(this.realm.getConfiguration()).add(next, realmQuery.handoverQueryPointer(), realmQuery.getArgument()).sendToHandler(this.realm.handler, COMPLETED_ASYNC_REALM_RESULTS).build());
                    return;
                }
                RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] , realm:" + this + " caller is more advanced & RealmResults is loaded ignore the outdated result");
            } else {
                RealmLog.d("[COMPLETED_ASYNC_REALM_RESULTS " + next + "] , realm:" + this + " caller thread behind worker thread, ignore results (a batch update will update everything including this query)");
            }
        }
    }

    private void deleteWeakReferences() {
        while (true) {
            Reference<? extends RealmResults<? extends RealmModel>> poll = this.referenceQueueAsyncRealmResults.poll();
            if (poll == null) {
                break;
            }
            this.asyncRealmResults.remove(poll);
        }
        while (true) {
            Reference<? extends RealmResults<? extends RealmModel>> poll2 = this.referenceQueueSyncRealmResults.poll();
            if (poll2 == null) {
                break;
            }
            this.syncRealmResults.remove(poll2);
        }
        while (true) {
            Reference<? extends RealmModel> poll3 = this.referenceQueueRealmObject.poll();
            if (poll3 == null) {
                return;
            }
            this.realmObjects.remove(poll3);
        }
    }

    private void notifyAsyncTransactionCallbacks() {
        if (this.pendingOnSuccessAsyncTransactionCallbacks.isEmpty()) {
            return;
        }
        for (Runnable runnable : this.pendingOnSuccessAsyncTransactionCallbacks) {
            runnable.run();
        }
        this.pendingOnSuccessAsyncTransactionCallbacks.clear();
    }

    private void notifyGlobalListeners() {
        Iterator<RealmChangeListener<? extends BaseRealm>> it = this.changeListeners.iterator();
        while (!this.realm.isClosed() && it.hasNext()) {
            it.next().onChange(this.realm);
        }
        Iterator<WeakReference<RealmChangeListener<? extends BaseRealm>>> it2 = this.weakChangeListeners.iterator();
        ArrayList arrayList = null;
        while (!this.realm.isClosed() && it2.hasNext()) {
            WeakReference<RealmChangeListener<? extends BaseRealm>> next = it2.next();
            RealmChangeListener<? extends BaseRealm> realmChangeListener = next.get();
            if (realmChangeListener == null) {
                if (arrayList == null) {
                    arrayList = new ArrayList(this.weakChangeListeners.size());
                }
                arrayList.add(next);
            } else {
                realmChangeListener.onChange(this.realm);
            }
        }
        if (arrayList != null) {
            this.weakChangeListeners.removeAll(arrayList);
        }
    }

    private void notifyRealmObjectCallbacks() {
        ArrayList arrayList = new ArrayList();
        Iterator<WeakReference<RealmObjectProxy>> it = this.realmObjects.keySet().iterator();
        while (it.hasNext()) {
            RealmObjectProxy realmObjectProxy = it.next().get();
            if (realmObjectProxy == null) {
                it.remove();
            } else if (realmObjectProxy.realmGet$proxyState().getRow$realm().isAttached()) {
                arrayList.add(realmObjectProxy);
            } else if (realmObjectProxy.realmGet$proxyState().getRow$realm() != Row.EMPTY_ROW) {
                it.remove();
            }
        }
        Iterator it2 = arrayList.iterator();
        while (!this.realm.isClosed() && it2.hasNext()) {
            ((RealmObjectProxy) it2.next()).realmGet$proxyState().notifyChangeListeners$realm();
        }
    }

    private void realmChanged(boolean z) {
        StringBuilder sb = new StringBuilder();
        sb.append(z ? "LOCAL_COMMIT" : "REALM_CHANGED");
        sb.append(" : realm:");
        sb.append(this);
        RealmLog.d(sb.toString());
        deleteWeakReferences();
        boolean threadContainsAsyncQueries = threadContainsAsyncQueries();
        if (z && threadContainsAsyncQueries) {
            RealmLog.w("Mixing asynchronous queries with local writes should be avoided. Realm will convert any async queries to synchronous in order to remain consistent. Use asynchronous writes instead. You can read more here: https://realm.io/docs/java/latest/#asynchronous-transactions");
        }
        if (!z && threadContainsAsyncQueries) {
            updateAsyncQueries();
            return;
        }
        this.realm.sharedGroupManager.advanceRead();
        ArrayList arrayList = new ArrayList();
        collectAsyncRealmResultsCallbacks(arrayList);
        collectSyncRealmResultsCallbacks(arrayList);
        notifyAllListeners(arrayList);
    }

    private boolean threadContainsAsyncQueries() {
        Iterator<Map.Entry<WeakReference<RealmResults<? extends RealmModel>>, RealmQuery<? extends RealmModel>>> it = this.asyncRealmResults.entrySet().iterator();
        boolean z = true;
        while (it.hasNext()) {
            if (it.next().getKey().get() == null) {
                it.remove();
            } else {
                z = false;
            }
        }
        return !z;
    }

    private void updateAsyncEmptyRealmObject() {
        Iterator<Map.Entry<WeakReference<RealmObjectProxy>, RealmQuery<? extends RealmModel>>> it = this.emptyAsyncRealmObject.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<WeakReference<RealmObjectProxy>, RealmQuery<? extends RealmModel>> next = it.next();
            if (next.getKey().get() != null) {
                BaseRealm.asyncTaskExecutor.submitQueryUpdate(QueryUpdateTask.newBuilder().realmConfiguration(this.realm.getConfiguration()).addObject(next.getKey(), next.getValue().handoverQueryPointer(), next.getValue().getArgument()).sendToHandler(this.realm.handler, COMPLETED_ASYNC_REALM_OBJECT).build());
            } else {
                it.remove();
            }
        }
    }

    private void updateAsyncQueries() {
        Future future = this.updateAsyncQueriesTask;
        if (future != null && !future.isDone()) {
            this.updateAsyncQueriesTask.cancel(true);
            BaseRealm.asyncTaskExecutor.getQueue().remove(this.updateAsyncQueriesTask);
            RealmLog.d("REALM_CHANGED realm:" + this + " cancelling pending COMPLETED_UPDATE_ASYNC_QUERIES updates");
        }
        RealmLog.d("REALM_CHANGED realm:" + this + " updating async queries, total: " + this.asyncRealmResults.size());
        QueryUpdateTask.Builder.UpdateQueryStep realmConfiguration = QueryUpdateTask.newBuilder().realmConfiguration(this.realm.getConfiguration());
        QueryUpdateTask.Builder.RealmResultsQueryStep realmResultsQueryStep = null;
        Iterator<Map.Entry<WeakReference<RealmResults<? extends RealmModel>>, RealmQuery<? extends RealmModel>>> it = this.asyncRealmResults.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<WeakReference<RealmResults<? extends RealmModel>>, RealmQuery<? extends RealmModel>> next = it.next();
            WeakReference<RealmResults<? extends RealmModel>> key = next.getKey();
            if (key.get() == null) {
                it.remove();
            } else {
                realmResultsQueryStep = realmConfiguration.add(key, next.getValue().handoverQueryPointer(), next.getValue().getArgument());
            }
        }
        if (realmResultsQueryStep != null) {
            this.updateAsyncQueriesTask = BaseRealm.asyncTaskExecutor.submitQueryUpdate(realmResultsQueryStep.sendToHandler(this.realm.handler, COMPLETED_UPDATE_ASYNC_QUERIES).build());
        }
    }

    public void addChangeListener(RealmChangeListener<? extends BaseRealm> realmChangeListener) {
        this.changeListeners.addIfAbsent(realmChangeListener);
    }

    void addChangeListenerAsWeakReference(RealmChangeListener<? extends BaseRealm> realmChangeListener) {
        ArrayList arrayList = null;
        boolean z = true;
        for (WeakReference<RealmChangeListener<? extends BaseRealm>> weakReference : this.weakChangeListeners) {
            RealmChangeListener<? extends BaseRealm> realmChangeListener2 = weakReference.get();
            if (realmChangeListener2 == null) {
                if (arrayList == null) {
                    arrayList = new ArrayList(this.weakChangeListeners.size());
                }
                arrayList.add(weakReference);
            }
            if (realmChangeListener2 == realmChangeListener) {
                z = false;
            }
        }
        if (arrayList != null) {
            this.weakChangeListeners.removeAll(arrayList);
        }
        if (z) {
            this.weakChangeListeners.add(new WeakReference<>(realmChangeListener));
        }
    }

    public <E extends RealmObjectProxy> WeakReference<RealmObjectProxy> addToAsyncRealmObject(E e2, RealmQuery<? extends RealmModel> realmQuery) {
        WeakReference<RealmObjectProxy> weakReference = new WeakReference<>(e2, this.referenceQueueRealmObject);
        this.realmObjects.put(weakReference, realmQuery);
        return weakReference;
    }

    public WeakReference<RealmResults<? extends RealmModel>> addToAsyncRealmResults(RealmResults<? extends RealmModel> realmResults, RealmQuery<? extends RealmModel> realmQuery) {
        WeakReference<RealmResults<? extends RealmModel>> weakReference = new WeakReference<>(realmResults, this.referenceQueueAsyncRealmResults);
        this.asyncRealmResults.put(weakReference, realmQuery);
        return weakReference;
    }

    public void addToEmptyAsyncRealmObject(WeakReference<RealmObjectProxy> weakReference, RealmQuery<? extends RealmModel> realmQuery) {
        this.emptyAsyncRealmObject.put(weakReference, realmQuery);
    }

    public <E extends RealmObjectProxy> void addToRealmObjects(E e2) {
        for (WeakReference<RealmObjectProxy> weakReference : this.realmObjects.keySet()) {
            if (weakReference.get() == e2) {
                return;
            }
        }
        this.realmObjects.put(new WeakReference<>(e2, this.referenceQueueRealmObject), NO_REALM_QUERY);
    }

    public void addToRealmResults(RealmResults<? extends RealmModel> realmResults) {
        this.syncRealmResults.add(new WeakReference<>(realmResults, this.referenceQueueSyncRealmResults));
    }

    public void handleAsyncTransactionCompleted(Runnable runnable) {
        if (runnable != null) {
            this.pendingOnSuccessAsyncTransactionCallbacks.add(runnable);
        }
        realmChanged(false);
    }

    @Override
    public boolean handleMessage(Message message) {
        if (this.realm.sharedGroupManager != null) {
            int i2 = message.what;
            switch (i2) {
                case REALM_CHANGED:
                case LOCAL_COMMIT:
                    realmChanged(i2 == LOCAL_COMMIT);
                    break;
                case COMPLETED_UPDATE_ASYNC_QUERIES:
                    completedAsyncQueriesUpdate((QueryUpdateTask.Result) message.obj);
                    break;
                case COMPLETED_ASYNC_REALM_RESULTS:
                    completedAsyncRealmResults((QueryUpdateTask.Result) message.obj);
                    break;
                case COMPLETED_ASYNC_REALM_OBJECT:
                    completedAsyncRealmObject((QueryUpdateTask.Result) message.obj);
                    break;
                case REALM_ASYNC_BACKGROUND_EXCEPTION:
                    throw ((Error) message.obj);
                default:
                    throw new IllegalArgumentException("Unknown message: " + message.what);
            }
        }
        return true;
    }

    public boolean isAutoRefreshEnabled() {
        return this.autoRefresh;
    }

    void notifyAllListeners(List<RealmResults<? extends RealmModel>> list) {
        Iterator<RealmResults<? extends RealmModel>> it = list.iterator();
        while (!this.realm.isClosed() && it.hasNext()) {
            it.next().notifyChangeListeners(false);
        }
        notifyRealmObjectCallbacks();
        if (!this.realm.isClosed() && threadContainsAsyncEmptyRealmObject()) {
            updateAsyncEmptyRealmObject();
        }
        notifyAsyncTransactionCallbacks();
        notifyGlobalListeners();
    }

    public void refreshSynchronousTableViews() {
        Iterator<WeakReference<RealmResults<? extends RealmModel>>> it = this.syncRealmResults.keySet().iterator();
        while (it.hasNext()) {
            RealmResults<? extends RealmModel> realmResults = it.next().get();
            if (realmResults == null) {
                it.remove();
            } else {
                realmResults.syncIfNeeded();
            }
        }
    }

    public void removeAllChangeListeners() {
        this.changeListeners.clear();
    }

    public void removeChangeListener(RealmChangeListener<? extends BaseRealm> realmChangeListener) {
        this.changeListeners.remove(realmChangeListener);
    }

    public void removeFromAsyncRealmObject(WeakReference<RealmObjectProxy> weakReference) {
        this.realmObjects.remove(weakReference);
    }

    void removeWeakChangeListener(RealmChangeListener<? extends BaseRealm> realmChangeListener) {
        ArrayList arrayList = null;
        for (int i2 = 0; i2 < this.weakChangeListeners.size(); i2++) {
            WeakReference<RealmChangeListener<? extends BaseRealm>> weakReference = this.weakChangeListeners.get(i2);
            RealmChangeListener<? extends BaseRealm> realmChangeListener2 = weakReference.get();
            if (realmChangeListener2 == null || realmChangeListener2 == realmChangeListener) {
                if (arrayList == null) {
                    arrayList = new ArrayList(this.weakChangeListeners.size());
                }
                arrayList.add(weakReference);
            }
        }
        this.weakChangeListeners.removeAll(arrayList);
    }

    public void setAutoRefresh(boolean z) {
        if (z && Looper.myLooper() == null) {
            throw new IllegalStateException("Cannot enabled autorefresh on a non-looper thread.");
        }
        this.autoRefresh = z;
    }

    boolean threadContainsAsyncEmptyRealmObject() {
        Iterator<Map.Entry<WeakReference<RealmObjectProxy>, RealmQuery<? extends RealmModel>>> it = this.emptyAsyncRealmObject.entrySet().iterator();
        boolean z = true;
        while (it.hasNext()) {
            if (it.next().getKey().get() == null) {
                it.remove();
            } else {
                z = false;
            }
        }
        return !z;
    }
}