待写

同一个ViewModel用于多个Activity之间通信

2022-03-04  本文已影响0人  ana生

上篇文章已经讲解了ViewModel的基本原理,了解了原理流程,接下来我们来实现同一个ViewModel如何用于多个Activity之间通信?

下面我先直接贴上代码:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface VMScope {
    String scopeName();
}
private static Map<String, VMStore> vMStores = new HashMap<>();
void injectViewModel() {
        for (Field field : this.getClass().getDeclaredFields()) {
            VMScope annotation = field.getAnnotation(VMScope.class);
            VMStore store = null;
            if (annotation != null) {
                String scopeName = annotation.scopeName();
                if (vMStores.containsKey(scopeName)) {
                    store = vMStores.get(scopeName);
                } else {
                    store = new VMStore();
                    vMStores.put(scopeName, store);
                }
            } else {
                store = new VMStore();
            }

            store.bindHost(this);
            Class<ViewModel> modelClass = (Class<ViewModel>) field.getType();
            ViewModel viewModel = new ViewModelProvider(store, new VMFactory()).get(modelClass);
            try {
                field.set(this, viewModel);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            }
        }
    }
class VMFactory implements ViewModelProvider.Factory {


        @NonNull
        @Override
        public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
            try {
                return modelClass.newInstance();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InstantiationException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    class VMStore implements ViewModelStoreOwner {
        private List<LifecycleOwner> bindTargets = new ArrayList<>();
        private ViewModelStore vmStore;

        void bindHost(LifecycleOwner host) {

            if (!bindTargets.contains(host)) {
                bindTargets.add(host);
                host.getLifecycle().addObserver(new LifecycleEventObserver() {
                    @Override
                    public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
                        if (event == Lifecycle.Event.ON_DESTROY) {
                            bindTargets.remove(host);
                            if (bindTargets.isEmpty()) {
                                vMStores.entrySet().iterator().forEachRemaining(stringVMStoreEntry -> {
                                    if (stringVMStoreEntry.getValue() == VMStore.this) {
                                        vmStore.clear();
                                        vMStores.remove(stringVMStoreEntry.getKey());
                                    }
                                });
                            }
                        }
                    }
                });
            }
        }

        @NonNull
        @Override
        public ViewModelStore getViewModelStore() {
            if (vmStore == null) {
                vmStore = new ViewModelStore();
            }
            return vmStore;
        }
    }
public class ViewModelTestAc extends BaseAc implements Observer<String> {
    @VMScope(scopeName = "test")
    TestVm testVm;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.ac_viewmodel_test);
        Log.d("vmTest", testVm.toString());
    }

    public void send(View view) {
        testVm.stringLiveData.postValue("ViewModelTestAc");
    }

    @Override
    public void onChanged(String s) {
        Log.d("ZLX", "ViewModelTestAc=" + s);
    }

}
上一篇 下一篇

猜你喜欢

热点阅读