LiveData使用解析并记录坑

注意:线程问题

This method must be called from the main thread. If you need set a value from a background thread, you can use {@link #postValue(Object)}

setValue必须发生在主线程,如果当前线程是子线程可以使用postValue。如果在子线程还是使用这个方法把,要不然不监听事件。

注解
在build文件下generated -> generated ->source -> apt -> release下生成下面代码生成MyLocationListener_LifecycleAdapter.java类

public class MyLocationListener implements LifecycleObserver {

    private static final String TAG = MyLocationListener.class.getSimpleName();

    @OnLifecycleEvent({Lifecycle.Event.ON_CREATE, Lifecycle.Event.ON_RESUME})
    public void start(LifecycleOwner lifecycleOwner, Lifecycle.Event event) {
        Log.d(TAG, "start: " + event.name() + " === " + lifecycleOwner.getLifecycle());
        Lifecycle.State currentState = lifecycleOwner.getLifecycle().getCurrentState();
        Log.d(TAG, "start: " + currentState);
    }

    @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
    public void stop(LifecycleOwner lifecycleOwner) {
        Log.d(TAG, "stop: " + lifecycleOwner.getLifecycle().getCurrentState());
    }
}

注解生成的 MyLocationListener_LifecycleAdapter.java

public class MyLocationListener_LifecycleAdapter implements GenericLifecycleObserver {
 final MyLocationListener mReceiver;

 MyLocationListener_LifecycleAdapter(MyLocationListener receiver) {
   this.mReceiver = receiver;
 }

 @Override
 public void onStateChanged(LifecycleOwner owner, Lifecycle.Event event) {
   if (event == Lifecycle.Event.ON_CREATE) {
     mReceiver.start(owner,event);
   }
   if (event == Lifecycle.Event.ON_RESUME) {
     mReceiver.start(owner,event);
   }
   if (event == Lifecycle.Event.ON_PAUSE) {
     mReceiver.stop(owner);
   }
 }

 public Object getReceiver() {
   return mReceiver;
 }
}

这个类的作用就是将生命周期事件分发到MyLocationListener对应的方法中。

在你的Activity或者fragment中,添加这样一行代码

getLifecycle().addObserver(new MyLocationListener());

就可以完成生命周期的监听,生命周期事件发生改变会通知到MyLocationListener类中对应的方法,

注意:如果你想实现自己Activity或者Fragment 实现LifecycleOwner。

public class MyFragment extends Fragment implements LifecycleRegistryOwner {
    LifecycleRegistry lifecycleRegistry = new LifecycleRegistry(this);

    @Override
    public LifecycleRegistry getLifecycle() {
        return lifecycleRegistry;
    }
}

注意:是 LifecycleRegistryOwner 不是LifecycleOwner,至于为什么后面会说到。

现在直接看看addObserver方法,从名字上也能看的出来,这是添加观察者的方法,

public void addObserver(LifecycleObserver observer) {
        ObserverWithState observerWithState = new ObserverWithState(observer);
        mObserverSet.putIfAbsent(observer, observerWithState);
        observerWithState.sync();
    }

mObserverSet就是一个保存观察者的自定义列表。
observerWithState.sync();这个方法很重要。看看代码

class ObserverWithState {
        private State mObserverCurrentState = INITIALIZED;
        private GenericLifecycleObserver mCallback;

        ObserverWithState(LifecycleObserver observer) {
            mCallback = Lifecycling.getCallback(observer);
        }

        void sync() {
            if (mState == DESTROYED && mObserverCurrentState == INITIALIZED) {
                mObserverCurrentState = DESTROYED;
            }
            while (mObserverCurrentState != mState) {
                Event event = mObserverCurrentState.isAtLeast(mState)
                        ? downEvent(mObserverCurrentState) : upEvent(mObserverCurrentState);
                mObserverCurrentState = getStateAfter(event);
                mCallback.onStateChanged(mLifecycleOwner, event);
            }
        }
    }

mObserverCurrentState观察者当前的状态,例如:如果我点击返回键,当前的事件onPause,那么观察者的当前状态就是onResume。
mState就是当前的状态。
简单的说就是比较两个状态,然后获取下一个生命周期事件。
只不过Google做的比较巧妙,仔细看代码会发现downEvent方法和upEvent方法返回的都是下一个事件,比如:算了 不举例了,至于为什么这么做,结合getStateAfter()方法,此方法是在handleLifecycleEvent方法中调用。看名字也知道啥意思了。

 public void handleLifecycleEvent(Lifecycle.Event event) {
        if (mLastEvent == event) {
            return;
        }
        mLastEvent = event;
        mState = getStateAfter(event);
        for (Map.Entry<LifecycleObserver, ObserverWithState> entry : mObserverSet) {
            entry.getValue().sync();
        }
    }

最后调用mCallback.onStateChanged(mLifecycleOwner, event);
把事件结果传递回来传递到我的MyLocationListener_LifecycleAdapter中。
如果你的代码中使用LiveData也是通过sync这个方法传递结果的。
不同的是mCallback这个返回值。
我们在看一下

 ObserverWithState(LifecycleObserver observer) {
            mCallback = Lifecycling.getCallback(observer);
        }

这个方法会根据传入的observer返回不同GenericLifecycleObserver的实现。

如果使用注解最终返回到MyLocationListener_LifecycleAdapter类onStateChanged方法,如果使用LiveData最终调用的是ReflectiveGenericLifecycleObserver类中的onStateChanged方法。

来看看使用LiveData怎么绑定生命周期的
发一下使用的代码 很简单

public class LocationLiveData extends LiveData<AMapLocation> {

    private static LocationLiveData sInstance;
    private LocationManager locationManager;

    public static final String TAG = LocationLiveData.class.getSimpleName();

    @MainThread
    private LocationLiveData(Context context) {
        locationManager = LocationManager.getInstance(context);
        locationManager.setOnLocationListener(locationResult);
    }

    private OnLocationResult locationResult = new OnLocationResult() {

        @Override
        public void locationSucceed(AMapLocation aMapLocation) {
            Log.d(TAG, "locationSucceed: 发送成功结果");
            postValue(aMapLocation);
        }

        @Override
        public void locationError(String error) {
            Log.w(TAG, "locationError: " + error);
            postValue(new AMapLocation("定位失败!"));
        }
    };

    @MainThread
    public static LocationLiveData get(Context context) {
        if (sInstance == null) {
            sInstance = new LocationLiveData(context);
        }
        return sInstance;
    }

    @Override
    protected void onActive() {
        super.onActive();
        Log.d(TAG, "onActive: 调用了");
        locationManager.startLocation();
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        Log.d(TAG, "onInactive: 调用了");
        locationManager.destroyLocation();
    }

在你自定义的LifecycleRegistryOwner中添加下面的代码。

 LifecycleOwner activity = (LifecycleOwner) getActivity();
        LocationLiveData.get(getActivity().getApplication()).observe(activity, new Observer<AMapLocation>() {
            @Override
            public void onChanged(@Nullable AMapLocation aMapLocation) {
                lastLocation = aMapLocation;
                if (aMapLocation != null) {
                    JSONObject message = JsonUtils.toJSONObject(LocationManager.getLocation(aMapLocation));
                    Log.d(TAG, "onChanged: " + message);
                    callbackContext.success(message);
                } else {
                    callbackContext.error("定位失败");
                }
            }
        });

同样来看看observe方法的实现。

public void observe(LifecycleOwner owner, Observer<T> observer) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && existing.owner != wrapper.owner) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
        wrapper.activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
    }

最主要的两句话

owner.getLifecycle().addObserver(wrapper);
wrapper.activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));

LiveData就是通过addObserver添加生命周期监听的。 添加到观察者自定义列表中,当事件发生改变时由handleLifecycleEvent方法通知观察者。
wrapper.activeStateChanged这个方法的调用事件是:当有观察者监听时,观察者移除时,和生命周期改变时,都会调用此方法。

但是调用这个方法是有前提条件的。

if (newActive == active) {
                return;
            }
            active = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += active ? 1 : -1;
            if (wasInactive && active) {
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !active) {
                onInactive();
            }
            if (active) {
                dispatchingValue(this);
            }
        }

new action只有当前生命周期状态是STARTED或者RESUME才是ture。action是上一次状态,mActiveCount代表着当前观察者的数量。 当LiveData被主动观察者时,将调用此方法(观察者的数量从0变成1时调用)调用onActive。当LiveData没有任何观察者时,将调用此方法(观察者的数量从1变成0)调用onInactive。

至于dispatchingValue方法。分发结果方法,两个地方调用:

  1. setValue
  2. 就是上面的observer

那postValue就不会派送结果么?咱就看看postValue

protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        AppToolkitTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

mPostValueRunnable又怎么实现的呢

private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };

原来postValue最后也是调用setValue

最后由

 private void considerNotify(LifecycleBoundObserver observer) {
        if (!observer.active) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!isActiveState(observer.owner.getLifecycle().getCurrentState())) {
            return;
        }
        if (observer.lastVersion >= mVersion) {
            return;
        }
        observer.lastVersion = mVersion;
        //noinspection unchecked
        observer.observer.onChanged((T) mData);
    }

方法传递结果。
在来看看GenericLifecycleObserver接口
GenericLifecycleObserver接口有两个实现方法

/**
     * Called when a state transition event happens.
     * 当状态的事件发生改变时调用
     * @param source The source of the event
     * @param event The event
     */
    void onStateChanged(LifecycleOwner source, Lifecycle.Event event);

    /**
     * Returns the actual receiver of the event
     * 返回事件被观察者的对象
     * @return The actual receiver
     */
    Object getReceiver();

这个接口有两个实现类 一个是上面的生成的类,另一个就是 ReflectiveGenericLifecycleObserver,这个类是依靠反射。

ReflectiveGenericLifecycleObserver 类

通过反射调用onStateChange()方法在LiveData 中的LifecycleBoundObserver内部类。调用activeStateChanged方法,回调到自己定义继承LiveData类的onActive()或者onInactive()方法 。

生命周期事件的传递

首先说一下整个库的入口,通过反编译(不用反编译也行,在app/build/intermediates/manifests/full/release/AndroidManifest.xml),会发现AndroidManifest.xml文件多了几行代码,

<provider
        android:name="android.arch.lifecycle.LifecycleRuntimeTrojanProvider"
        android:authorities="${applicationId}.lifecycle-trojan"
        android:exported="false"
        android:multiprocess="true" />

整个库利用ContentProvider在应用程序初始化的时候,添加两行了代码

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class LifecycleRuntimeTrojanProvider extends ContentProvider {
    @Override
    public boolean onCreate() {
        LifecycleDispatcher.init(getContext());
        ProcessLifecycleOwner.init(getContext());
        return true;
    }

首先先看事件分发的init

static void init(Context context) {
        if (sInitialized.getAndSet(true)) {
            return;
        }
        ((Application) context.getApplicationContext())
                .registerActivityLifecycleCallbacks(new DispatcherActivityCallback());
    }

这是一个单例,获取全局的Application并注册Activity生命周期回调DispatcherActivityCallback(),在构造中 mFragmentCallback = new FragmentCallback();创建Fragment生命周期回调。
在onActivityCreated回调中,创建一个ReportFragment没有UI界面,并添加fragment的生命周期事件回调。

 @Override
        public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
            if (activity instanceof FragmentActivity) {
                ((FragmentActivity) activity).getSupportFragmentManager()
                        .registerFragmentLifecycleCallbacks(mFragmentCallback, true);
            }
            // ProcessLifecycleOwner should always correctly work and some activities may not extend
            // FragmentActivity from support lib, so we use framework fragments for activities
            android.app.FragmentManager manager = activity.getFragmentManager();
            if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
                manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
                // Hopefully, we are the first to make a transaction.
                manager.executePendingTransactions();
            }
        }

ProcessLifecycleOwner.init(getContext())监听进程的生命周期

同样的,是在contentProvider中调用的,也是单例。用于监听整个应用的前后台切换。也是利用 ActivityLifecycleCallback 监听每个 Activity 的生命周期,如果 onStop 事件后,没有监听到任意的 onStart 事件,那么 ProcessLifecycleOwner 就会认为整个应用切换到后台,同时留下一个标志。如果监听到 onStart 事件,同时检查有标志那么就会认为应用回到前台

static void init(Context context) {
        sInstance.attach(context);
    }
void attach(Context context) {
        mHandler = new Handler();
        mRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
        Application app = (Application) context.getApplicationContext();
        app.registerActivityLifecycleCallbacks(new EmptyActivityLifecycleCallbacks() {
            @Override
            public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
                LifecycleDispatcher.get(activity).setProcessListener(mInitializationListener);
            }

            @Override
            public void onActivityPaused(Activity activity) {
                activityPaused();
            }

            @Override
            public void onActivityStopped(Activity activity) {
                activityStopped();
            }
        });
    }

在应用程序启动时,直接发送处理生命周期OnCreate事件,对其进行生命周期事件的注册,并且把生命事件都交给ReportFragment类来处理;
最后由

private void dispatch(Lifecycle.Event event) {
       if (getActivity() instanceof LifecycleRegistryOwner) {
           ((LifecycleRegistryOwner) getActivity()).getLifecycle().handleLifecycleEvent(event);
       }
   }

来分发事件。
注意:if (getActivity() instanceof LifecycleRegistryOwner) {
如果你的自定义组件 继承的是 LifecycleOwner 事件当然分发不下去。

盗用一下组长的事件分发图TiouLims

64766-e57813cb987f6d6c.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容

  • 示例应用程序 使用LiveData的优点 使用LiveData对象创建LiveData对象观察LiveData对象...
    yyg阅读 5,805评论 5 7
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 170,569评论 25 707
  • 前言: 作为一名移动互联网App研发人员,在实际项目的研发过程中,保质保量高效率,方便快捷,同时方便开发者之间的互...
    Yagami3zZ阅读 4,585评论 1 9
  • 多久前静下来思考,多久前停下脚步细细品味生活的种种。 是的,时间一不小心又过去了一天了。这一天你做了什么,这一天你...
    若邻阅读 2,568评论 0 1
  • 01.按照计划做事,就会形成规律。 以前有一个同事,每个周末都是提前做好安排,比如周六理发,周日爬山;后来发现经理...
    心灵的花园阅读 153评论 0 2