美文网首页源码分析
LiveData使用解析并记录坑

LiveData使用解析并记录坑

作者: Android_冯星 | 来源:发表于2017-06-19 20:06 被阅读6720次

注意:线程问题

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

相关文章

网友评论

    本文标题:LiveData使用解析并记录坑

    本文链接:https://www.haomeiwen.com/subject/ucguqxtx.html