|
|
@@ -1,21 +1,12 @@
|
|
|
package com.miekir.mvp.view;
|
|
|
|
|
|
-import android.text.TextUtils;
|
|
|
+import androidx.lifecycle.ViewModelProvider;
|
|
|
+import androidx.lifecycle.ViewModelStoreOwner;
|
|
|
|
|
|
-import androidx.lifecycle.LifecycleOwner;
|
|
|
-import androidx.lifecycle.MutableLiveData;
|
|
|
-import androidx.lifecycle.Observer;
|
|
|
-
|
|
|
-import com.miekir.mvp.bean.DataResult;
|
|
|
-import com.miekir.mvp.constant.DialogAction;
|
|
|
-import com.miekir.mvp.constant.MvpResponse;
|
|
|
-import com.miekir.mvp.model.DataMethod;
|
|
|
-import com.miekir.mvp.model.DataSource;
|
|
|
import com.miekir.mvp.presenter.BasePresenter;
|
|
|
import com.miekir.mvp.presenter.InjectPresenter;
|
|
|
|
|
|
import java.lang.reflect.Field;
|
|
|
-import java.lang.reflect.Method;
|
|
|
import java.util.List;
|
|
|
|
|
|
/**
|
|
|
@@ -28,101 +19,18 @@ import java.util.List;
|
|
|
public class ViewHelper {
|
|
|
private ViewHelper() {}
|
|
|
|
|
|
- /**
|
|
|
- * 界面销毁时,清理Presenter
|
|
|
- * @param mInjectPresenters
|
|
|
- * @param owner
|
|
|
- */
|
|
|
- public static void clearPresenters(List<BasePresenter> mInjectPresenters, final LifecycleOwner owner) {
|
|
|
- if (mInjectPresenters.size() > 0) {
|
|
|
- for (BasePresenter presenter : mInjectPresenters) {
|
|
|
- if (presenter == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- MutableLiveData<DataResult<?>> liveData = presenter.getCommonLiveData();
|
|
|
- MutableLiveData<DataResult<?>> dialogData = presenter.getDialogLiveData();
|
|
|
- if (dialogData != null) {
|
|
|
- dialogData.removeObservers(owner);
|
|
|
- }
|
|
|
- if (liveData != null) {
|
|
|
- liveData.removeObservers(owner);
|
|
|
- }
|
|
|
- presenter.detachView();
|
|
|
- }
|
|
|
- mInjectPresenters.clear();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * 初始化获取需要回调的注解方法
|
|
|
- */
|
|
|
- public static void initCallbacks(List<Method> mDataMethodList, Class<?> getClass) {
|
|
|
- // 查找回调方法
|
|
|
- mDataMethodList.clear();
|
|
|
-
|
|
|
- Method[] methods = null;
|
|
|
- try {
|
|
|
- // This is faster than getMethods, especially when subscribers are fat classes like Activities
|
|
|
- methods = getClass.getDeclaredMethods();
|
|
|
- } catch (Throwable th) {
|
|
|
- // Workaround for java.lang.NoClassDefFoundError, see https://github.com/greenrobot/EventBus/issues/149
|
|
|
- try {
|
|
|
- methods = getClass.getMethods();
|
|
|
- } catch (LinkageError error) {
|
|
|
- error.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 参数校验
|
|
|
- if (methods == null || methods.length == 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- String methodAnnotationName = DataMethod.class.getName();
|
|
|
- for (Method method : methods) {
|
|
|
- DataMethod dataMethod = method.getAnnotation(DataMethod.class);
|
|
|
- if (dataMethod == null) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- int length = method.getParameterTypes().length;
|
|
|
- if (length != 3) {
|
|
|
- throw new AssertionError(methodAnnotationName + "修饰的方法参数数量必须为3个");
|
|
|
- }
|
|
|
-
|
|
|
- // 响应结果,必须为int或者boolean
|
|
|
- String firstType = method.getParameterTypes()[0].getSimpleName();
|
|
|
- String resultCodeType = int.class.getSimpleName();
|
|
|
- String resultStatusType = boolean.class.getSimpleName();
|
|
|
- if (!TextUtils.equals(resultCodeType, firstType) && !TextUtils.equals(resultStatusType, firstType)) {
|
|
|
- throw new AssertionError(methodAnnotationName + "修饰的方法第1个参数必须为" + resultCodeType + "或" + resultStatusType);
|
|
|
- }
|
|
|
-
|
|
|
- // 响应消息
|
|
|
- String secondType = method.getParameterTypes()[1].getSimpleName();
|
|
|
- String messageType = String.class.getSimpleName();
|
|
|
- if (!TextUtils.equals(messageType, secondType)) {
|
|
|
- throw new AssertionError(methodAnnotationName + "修饰的方法第2个参数必须为" + messageType);
|
|
|
- }
|
|
|
-
|
|
|
- method.setAccessible(true);
|
|
|
- mDataMethodList.add(method);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* 初始化添加注解的变量
|
|
|
* final Class<? extends IView> getClass,可以代表接口的实现类
|
|
|
*/
|
|
|
- public static void initVariables(List<BasePresenter> mInjectPresenters, final LifecycleOwner owner, final IView iView) {
|
|
|
- ViewHelper.clearPresenters(mInjectPresenters, owner);
|
|
|
+ public static <V extends IView> void initVariables(List<BasePresenter<V>> mInjectPresenters, final ViewModelStoreOwner owner, final IView iView) {
|
|
|
+ mInjectPresenters.clear();
|
|
|
// 这里可以获取到子类的成员变量
|
|
|
Field[] fields = iView.getClass().getDeclaredFields();
|
|
|
for (Field field : fields) {
|
|
|
// 获取变量上面的注解类型
|
|
|
- InjectPresenter injectViewModel = field.getAnnotation(InjectPresenter.class);
|
|
|
- if (injectViewModel == null) {
|
|
|
+ InjectPresenter presenterAnnotation = field.getAnnotation(InjectPresenter.class);
|
|
|
+ if (presenterAnnotation == null) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
@@ -130,43 +38,14 @@ public class ViewHelper {
|
|
|
field.setAccessible(true);
|
|
|
|
|
|
// 父类引用指向子类对象
|
|
|
- Class<? extends BasePresenter> type = (Class<? extends BasePresenter>) field.getType();
|
|
|
- BasePresenter presenter = type.newInstance();
|
|
|
- // 下面这种方法是单例形式,会造成重复回调的问题
|
|
|
- //BaseViewModel presenter = new ViewModelProvider(this).get(type);
|
|
|
-
|
|
|
- // 创建一个观察者去更新UI
|
|
|
- final Observer<DataResult> observer = new Observer<DataResult>() {
|
|
|
- @Override
|
|
|
- public void onChanged(final DataResult result) {
|
|
|
- // 回调是在主线程
|
|
|
- // Log.i("Thread", String.valueOf(Thread.currentThread() == Looper.getMainLooper().getThread()));
|
|
|
- iView.onDataResult(result);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- final Observer<DataResult> dialogObserver = new Observer<DataResult>() {
|
|
|
- @Override
|
|
|
- public void onChanged(final DataResult result) {
|
|
|
- if (result.getDataSource() == DialogAction.DIALOG_SHOW) {
|
|
|
- iView.onLoadTimeChange(true, result.getMessage());
|
|
|
- } else if (result.getDataSource() == DialogAction.DIALOG_DISMISS) {
|
|
|
- iView.onLoadTimeChange(false, result.getMessage());
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- if (injectViewModel.isPersist()) {
|
|
|
- presenter.getCommonLiveData().observeForever(observer);
|
|
|
- presenter.getDialogLiveData().observeForever(dialogObserver);
|
|
|
- } else {
|
|
|
- presenter.getCommonLiveData().observe(owner, observer);
|
|
|
- presenter.getDialogLiveData().observe(owner, dialogObserver);
|
|
|
- }
|
|
|
-
|
|
|
+ Class<? extends BasePresenter<V>> type = (Class<? extends BasePresenter<V>>) field.getType();
|
|
|
+ //BasePresenter<V> presenter = type.newInstance();
|
|
|
+ // todo 下面这种方法是单例形式,会造成重复回调的问题
|
|
|
+ BasePresenter<V> presenter = new ViewModelProvider(owner).get(type);
|
|
|
field.set(iView, presenter);
|
|
|
+ presenter.attachView((V) iView);
|
|
|
mInjectPresenters.add(presenter);
|
|
|
- } catch (IllegalAccessException | InstantiationException e) {
|
|
|
+ } catch (IllegalAccessException e) {
|
|
|
e.printStackTrace();
|
|
|
} catch (ClassCastException e) {
|
|
|
e.printStackTrace();
|
|
|
@@ -174,49 +53,4 @@ public class ViewHelper {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- /**
|
|
|
- * 分发回调的数据
|
|
|
- * @param object
|
|
|
- * @param mDataMethodList
|
|
|
- * @param result
|
|
|
- */
|
|
|
- public static void handleDataResult(Object object, List<Method> mDataMethodList, DataResult result) {
|
|
|
- Class<?> objParamClass = null;
|
|
|
- if (result != null && result.getBean() != null) {
|
|
|
- objParamClass = result.getBean().getClass();
|
|
|
- }
|
|
|
-
|
|
|
- for (Method method : mDataMethodList) {
|
|
|
- // 判断数据来源是否一致
|
|
|
- int dataSource = DataSource.DEFAULT;
|
|
|
- DataMethod dataMethod = method.getAnnotation(DataMethod.class);
|
|
|
- if (dataMethod != null) {
|
|
|
- dataSource = dataMethod.dataSource();
|
|
|
- }
|
|
|
-
|
|
|
- // 加载框的问题
|
|
|
- if (dataSource != result.getDataSource()) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- // 判断方法的第三个参数类型是否是回调对象的父类
|
|
|
- Class<?> methodParamClass = method.getParameterTypes()[2];
|
|
|
- if (objParamClass != null && !methodParamClass.isAssignableFrom(objParamClass)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- method.invoke(object, result.getResponseCode(), result.getMessage(), result.getBean());
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
-
|
|
|
- try {
|
|
|
- method.invoke(object, result.getResponseCode() == MvpResponse.SUCCESS, result.getMessage(), result.getBean());
|
|
|
- } catch (Exception e) {
|
|
|
- e.printStackTrace();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
}
|