Android架构组件中的注解

LifeCycler源码解析

介绍 Architecture

Android官方架构组件是Google在I/O大会上推荐的一套的架构,提供一套强大的解耦架构

  • 巧妙的数据共享(可以做到简单的无视屏幕旋转(播放器))

问题:你在Activity中旋转是怎么做到将数据保存到内存的?

我们首先提供 ChronometerViewModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ChronometerViewModel extends ViewModel {

@Nullable
private Long mStartTime;

@Nullable
public Long getStartTime() {
return mStartTime;
}

public void setStartTime(final long startTime) {
this.mStartTime = startTime;
}
}

ViewModel只是一个接口

1
2
3
4
5
6
7
8
9
10
11
public abstract class ViewModel {
/**
* This method will be called when this ViewModel is no longer used and will be destroyed.
* <p>
* It is useful when ViewModel observes some data and you need to clear this subscription to
* prevent a leak of this ViewModel.
*/
@SuppressWarnings("WeakerAccess")
protected void onCleared() {
}
}

然后在onCreate中创建了ViewModel

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ChronometerViewModel chronometerViewModel= ViewModelProviders.of(this).get(ChronometerViewModel.class);
if (chronometerViewModel.getStartTime() == null) {
// If the start date is not defined, it's a new ViewModel so set it.
long startTime = SystemClock.elapsedRealtime();
chronometerViewModel.setStartTime(startTime);
chronometer.setBase(startTime);
} else {
// Otherwise the ViewModel has been retained, set the chronometer's base to the original
// starting time.
chronometer.setBase(chronometerViewModel.getStartTime());
}
}

那么一行代码是怎么通过非单例而做到在内存保存呢?

1
ChronometerViewModel chronometerViewModel=ViewModelProviders.of(this).get(ChronometerViewModel.class);

可以拆分为两段

  • ViewModelProviders.of(this)
  • ViewModelProvider.get(ChronometerViewModel.class)

获取ViewModelStore

ViewModelProviders

ViewModelProviders.of(this)

1
2
3
4
public static ViewModelProvider of(@NonNull FragmentActivity activity) {
initializeFactoryIfNeeded(checkApplication(activity));//application检查
return new ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory);
}

ViewModelProvider

ViewModelProvider(ViewModelStores.of(activity), sDefaultFactory);

1
2
3
4
public ViewModelProvider(@NonNull ViewModelStore store, @NonNull Factory factory) {
mFactory = factory;
this.mViewModelStore = store;
}

那么创建ViewModelProvider需要两个参数一个ViewModelStore另一个是Factory,Factory用的是ViewModelProviders中默认的一个Factory,那么ViewModelStore是什么又是怎么来的呢?

ViewModelStores.of(activity)

1
2
3
4
5
import static android.arch.lifecycle.HolderFragment.holderFragmentFor;

public static ViewModelStore of(@NonNull FragmentActivity activity) {
return holderFragmentFor(activity).getViewModelStore();
}

这里的静态方法holderFragmentFor()是HolderFragment中的一个静态方法

HolderFragment

1
2
3
4
5
6
7
/**
* @hide
*/
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public static HolderFragment holderFragmentFor(FragmentActivity activity) {
return sHolderFragmentManager.holderFragmentFor(activity);
}

sHolderFragmentManager是HolderFragment中的一个子类,其中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
HolderFragment holderFragmentFor(FragmentActivity activity) {
FragmentManager fm = activity.getSupportFragmentManager();
HolderFragment holder = findHolderFragment(fm);
if (holder != null) {
return holder;
}
holder = mNotCommittedActivityHolders.get(activity);
if (holder != null) {
return holder;
}

if (!mActivityCallbacksIsAdded) {
mActivityCallbacksIsAdded = true;
activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
}
holder = createHolderFragment(fm);
mNotCommittedActivityHolders.put(activity, holder);
return holder;
}

三种case

  • findHolderFragment
  • mNotCommittedActivityHolders.get(activity)
  • createHolderFragment(fm)
1
2
3
4
5
6
7
8
9
10
11
12
private static HolderFragment findHolderFragment(FragmentManager manager) {
if (manager.isDestroyed()) {
throw new IllegalStateException("Can't access ViewModels from onDestroy");
}

Fragment fragmentByTag = manager.findFragmentByTag(HOLDER_TAG);
if (fragmentByTag != null && !(fragmentByTag instanceof HolderFragment)) {
throw new IllegalStateException("Unexpected "
+ "fragment instance was returned by HOLDER_TAG");
}
return (HolderFragment) fragmentByTag;
}

从manager中拿固定的tag

1
2
3
4
5
private static HolderFragment createHolderFragment(FragmentManager fragmentManager) {
HolderFragment holder = new HolderFragment();
fragmentManager.beginTransaction().add(holder, HOLDER_TAG).commitAllowingStateLoss();
return holder;
}

直接添加Fragment

那么可以看到我们要获取ViewModelStore的流程图是

1
2
3
4
graph TD
ViewModelProviders[ViewModelProviders]-->ViewModelProvider[ViewModelProvider]
ViewModelProvider[ViewModelProvider]-->ViewModelStore[ViewModelStore]
HolderFragment[HolderFragment三种方式获取]-->ViewModelStore[ViewModelStore]

第二部分 get(ChronometerViewModel.class)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);

if (modelClass.isInstance(viewModel)) {
//noinspection unchecked
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}

viewModel = mFactory.create(modelClass);
mViewModelStore.put(key, viewModel);
//noinspection unchecked
return (T) viewModel;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@NonNull
@Override
public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
if (AndroidViewModel.class.isAssignableFrom(modelClass)) {
//noinspection TryWithIdenticalCatches
try {
return modelClass.getConstructor(Application.class).newInstance(mApplication);
} catch (NoSuchMethodException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (IllegalAccessException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InstantiationException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
} catch (InvocationTargetException e) {
throw new RuntimeException("Cannot create an instance of " + modelClass, e);
}
}
return super.create(modelClass);
}

通过反射拿到ViewModel

1
2
3
4
5
graph TD
ViewModelProviders[ViewModelProviders]-->ViewModelProvider[ViewModelProvider]
ViewModelProvider[ViewModelProvider]-->ViewModelStore[ViewModelStore]
HolderFragment[HolderFragment三种方式获取]-->ViewModelStore[ViewModelStore]
ViewModelStore[ViewModelStore]-->ViewModle[ViewModel]

问题: 那么为什么旋转的时候可以保存呢?

我们知道了在ViewModle是保存在HolderFragment中并且传递给了ViewModelProvider的,那么它为什么在activity重新创建的时候没有被销毁呢?

看Holder发现在创建的时候调用了setRetainInstance(true);方法

1
2
3
public HolderFragment() {
setRetainInstance(true);
}

经过层层调用,在Activity的fragmentManager中有一个moveToStatus

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
if (!f.mRetaining) {
f.performDestroy();
}

f.mCalled = false;
f.onDetach();
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f
+ " did not call through to super.onDetach()");
}
if (!keepActive) {
if (!f.mRetaining) {
makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
f.mChildFragmentManager = null;
}
}
1
if (f != null && f.mRetainInstance)

可以看到在fragmentManager中的remoteFragment中的moveToState方法中可以看到,fragment判断
mRetaining为true的时候并不会销毁fragment

1
2
3
4
5
6
7
switch (f.mState) {
case Fragment.INITIALIZING:
.........
if (!f.mRetaining) {
f.performCreate(f.mSavedFragmentState);
}
.....

并在初始化的过程中不会执行oncreawte,但是其他方法会执行比如detach attach方法

问题:find Fragment的第二个添加办法是做什么的?

首先在HolderFragment中,oncreate中执行了此方法

1
2
3
4
5
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sHolderFragmentManager.holderFragmentCreated(this);
}

这个方法会将其里面保存的fragment干掉

1
2
3
4
5
6
7
8
9
10
void holderFragmentCreated(Fragment holderFragment) {
Fragment parentFragment = holderFragment.getParentFragment();
if (parentFragment != null) {
mNotCommittedFragmentHolders.remove(parentFragment);
parentFragment.getFragmentManager().unregisterFragmentLifecycleCallbacks(
mParentDestroyedCallback);
} else {
mNotCommittedActivityHolders.remove(holderFragment.getActivity());
}
}

fragment的findfragmentbytag是从added中获取的

首先在系统的FragmentManagerImpl中的,有这么一个方法

1
ArrayList<Fragment> mAdded;

1
fragmentManager.beginTransaction().add(holder, HOLDER_TAG).commitAllowingStateLoss();

Fragment在执行commit方法的时候回执行将之前的add操作放入到Activity 中的一个handler里面去执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public void run() {
..........伪代码
while (op != null) {
switch (op.cmd) {
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = op.enterAnim;
mManager.addFragment(f, false);
}
break;
.............伪代码
}

op = op.next;
}

mManager.moveToState(mManager.mCurState, mTransition,
mTransitionStyle, true);

}

1
2
3
4
mManager.addFragment(f, false);


mAdded.add(fragment);

在addFragment中添加到added
然后执行moveToState方法中的

1
2
3
4
5
6
7
switch (f.mState) {
case Fragment.INITIALIZING:
.........
if (!f.mRetaining) {
f.performCreate(f.mSavedFragmentState);
}
.....

因此可以知道google在用这个东西做一个low底,在fragment创建到oncreate的过程中,如果操作过快oncreate没有执行完,可能还没有添加到fragment的集合中去,所以添加到一个列表里再在oncreate的时候释放掉。

屏幕旋转的时候

image

1
2
3
4
5
6
7
8
11-03 10:44:16.946 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e  FragmentManager{659732f in HostCallbacks{a888d3c}}
11-03 10:52:47.545 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{2b4062 in HostCallbacks{ca8ff5f}}
11-03 10:52:53.814 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{18d4eb1 in HostCallbacks{fe51627}}
11-03 10:52:57.027 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{316115 in HostCallbacks{bd8ec2a}}
11-03 10:52:58.384 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{bf53739 in HostCallbacks{d52117e}}
11-03 10:58:01.908 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{aef51d in HostCallbacks{a9b6392}}
11-03 10:58:08.305 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{1c7ec1 in HostCallbacks{506f666}}
11-03 10:58:09.966 onCreate: com.example.android.lifecycles.step2.ChronometerViewModel@9753d0e FragmentManager{fc77825 in HostCallbacks{279dfa}}

有关于hascode的错误在https://bugs.java.com/bugdatabase/view_bug.do?bug_id=6321873

那么在屏幕翻转的过程中Activity会重新创建,那么内存中的fragment是怎么保存下来的呢?

1
static final String FRAGMENTS_TAG = "android:fragments";

在Activit源码中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
protected void onSaveInstanceState(Bundle outState) {
outState.putBundle(WINDOW_HIERARCHY_TAG, mWindow.saveHierarchyState());

outState.putInt(LAST_AUTOFILL_ID, mLastAutofillId);
Parcelable p = mFragments.saveAllState();
if (p != null) {
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mAutoFillResetNeeded) {
outState.putBoolean(AUTOFILL_RESET_NEEDED, true);
getAutofillManager().onSaveInstanceState(outState);
}
getApplication().dispatchActivitySaveInstanceState(this, outState);
}
1
2
3
4
5
6
7
8
9
/* package */ void dispatchActivitySaveInstanceState(Activity activity, Bundle outState) {
Object[] callbacks = collectActivityLifecycleCallbacks();
if (callbacks != null) {
for (int i=0; i<callbacks.length; i++) {
((ActivityLifecycleCallbacks)callbacks[i]).onActivitySaveInstanceState(activity,
outState);
}
}
}
1
2
3
4
5
6
7
8
9
protected void onCreate(@Nullable Bundle savedInstanceState) {
···伪代码
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
···伪代码
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void restoreAllState(Parcelable state, List<Fragment> nonConfig) {
···伪代码

// If there is no saved state at all, then there can not be
// any nonConfig fragments either, so that is that.
if (state == null) return;
FragmentManagerState fms = (FragmentManagerState)state;
if (fms.mActive == null) return;


// Build the list of currently added fragments.
if (fms.mAdded != null) {
mAdded = new ArrayList<Fragment>(fms.mAdded.length);
for (int i=0; i<fms.mAdded.length; i++) {
Fragment f = mActive.get(fms.mAdded[i]);
if (f == null) {
throwException(new IllegalStateException(
"No instantiated fragment for index #" + fms.mAdded[i]));
}
f.mAdded = true;
if (DEBUG) Log.v(TAG, "restoreAllState: added #" + i + ": " + f);
if (mAdded.contains(f)) {
throw new IllegalStateException("Already added!");
}
mAdded.add(f);
}
} else {
mAdded = null;
}

···伪代码
}

那么这就解释了为什么added这个Fragment的list会在内存中一直保存了

谢谢您的鼓励~