个人Android项目快速搭建框架基类
注: 1.x 和 2.x 版本的包结构不同
// build.gradle
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}// settings.gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
...
maven { url 'https://jitpack.io' }
}
}// 主项目的 build.gradle 中加入
android {
...
buildFeatures {
viewBinding true
}
}// 主项目的 build.gradle 中加入
android {
...
viewBinding {
enable = true
}
}直接下载源码引入 model
// gradle.properties
// 没有声明转移至 androidX,需要声明,否则报错
android.enableJetifier=true
dependencies {
implementation 'com.github.sHadowLess-LhQ:BaseView:Tag'
implementation 'com.github.getActivity:XXPermissions:26'
}-keepattributes Signature
-dontwarn sun.misc.**
-keepclassmembers class rx.internal.util.unsafe.*ArrayQueue*Field* {
long producerIndex;
long consumerIndex;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueProducerNodeRef {
rx.internal.util.atomic.LinkedQueueNode producerNode;
}
-keepclassmembers class rx.internal.util.unsafe.BaseLinkedQueueConsumerNodeRef {
rx.internal.util.atomic.LinkedQueueNode consumerNode;
}
-keepclassmembers class rx.android.**{*;}
// 基类已实现异步布局加载,如需异步加载,请重写isAsyncLoadView方法
// 并返回true
// 若异步加载需要加载弹窗,需要重写initSyncView,并返回实现AsyncLoadViewCallBack
// 默认没有异步加载弹窗
// 需要实现异步加载View动画,请实现AsyncLoadViewCallBack,并重写startAsyncAnimSetView
// 一定要回调animStart,否则基类不会把视图添加至根视图
// 接口的对象,供基类调用,显示和关闭
// 创建xml后,点击编译,填入需要绑定的视图和传递数据类型
// click监听已做快速点击处理,请重写antiShakingClick接口
// 设置Activity主题,请重写initTheme()方法
// 设置权限申请前置步骤,请重写initPermission(String[] permissions)方法
// 如果单个Activity需要动态使用不同的布局文件,请给BaseActivity的泛型类型
// 传递ViewBinding,并重写setBindViewClass模板方法,传递不同ViewBinding类的class
// 如果不想用默认的反射去动态使用不同的布局,请重写inflateView模板方法
// 手动传递和实现ViewBinding类的实例
// 如果有反射加载视图慢的情况,请重写inflateView方法,手动实现ViewBinding类创建
// 需要更改点击防抖时间阈值,请重写isFastClick,在超类调用传递时间
// 需要在获取权限,请重写permissions方法
// 新增initDataByPermission方法,用于需要获取权限后才可以获取数据的逻辑
public class MainActivity extends BaseVpActivity<ActivityMainBinding> {
@Nullable
@Override
public List<IPermission> permissions() {
// 设置需要动态获取的权限
return super.permissions();
}
@Override
public void dealPermission(FragmentActivity activity, List<IPermission> permissions, OnPermissionInterceptor interceptor, OnPermissionResult callBack) {
super.dealPermission(activity, permissions, interceptor, callBack);
// 若使用基类获取权限,可重写此方法
// 设置权限拦截器
// 权限获取结果回调
}
@Override
protected void initObject(Bundle savedInstanceState) {
// 初始化对象
}
@Override
protected void initView() {
// 初始化视图
}
@Override
protected void initViewListener() {
// 初始化监听
getBindView().test.setOnClickListener(this);
}
@Override
protected void initDataListener() {
// 初始化数据回调
}
@Override
protected void initData() {
// 初始化数据
}
@Override
public void initDataByPermission() {
//获取全部权限后,才会执行
super.initDataByPermission();
}
@Override
public void antiShakingClick(View v) {
super.antiShakingClick(v);
// 点击事件
}
@Override
public boolean isFastClick(int time) {
// 传递需要的防抖时间阈值
return super.isFastClick(time);
}
@Override
public Class<ViewBinding> setBindViewClass() {
// 反射动态布局
Class<?> cls;
if (i == 1) {
cls = ActivityMainBinding.class;
} else {
cls = XxxBinding.class;
}
return (Class<ViewBinding>) cls;
}
@Override
public ViewBinding inflateView(Object o, LayoutInflater layoutInflater) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// 手动动态布局或手动初始化布局
int i = 0;
if (i == 0){
return TestBinding.inflate(getLayoutInflater());
}
return Test1Binding.inflate(getLayoutInflater());
}
@Override
public boolean isAsyncLoad() {
// 是否异步加载视图
return false;
}
}// 基类已实现三种懒加载模式:
// DEFAULT:正常加载
// ONLY_LAZY_DATA:只懒加载数据
// LAZY_VIEW_AND_DATA:懒加载数据和页面
// 通过重写getLoadMode方法,返回不同的加载枚举
// 基类会执行不同的加载逻辑,不重写为DEFAULT
// 可通过isLazyInitSuccess方法,获取懒加载是否成功
// 基类已实现异步布局加载,如需异步加载,请重写isAsyncLoadView方法
// 并返回true
// 若异步加载需要加载弹窗,需要重写initSyncView,并返回实现AsyncLoadViewCallBack
// 默认没有异步加载弹窗
// 需要实现异步加载View动画,请实现AsyncLoadViewCallBack,并重写startAsyncAnimSetView
// 一定要回调animStart,否则基类不会把视图添加至根视图
// 接口的对象,供基类调用,显示和关闭
// 创建xml后,点击编译,填入需要绑定的视图和传递数据类型
// click监听已做快速点击处理,请重写antiShakingClick接口
// 设置Activity主题,请重写initTheme()方法
// 设置权限申请前置步骤,请重写initPermission(String[] permissions)方法
// 如果单个Fragment需要动态使用不同的布局文件,请给BaseFragment的泛型类型
// 传递ViewBinding,并重写setBindViewClass模板方法,传递不同ViewBinding类
// 如果不想用默认的反射去动态使用不同的布局,请重写inflateView模板方法
// 手动传递和实现ViewBinding类的实例
// 如果有反射加载视图慢的情况,请重写inflateView方法,手动实现ViewBinding类创建
// 需要更改点击防抖时间阈值,请重写isFastClick,在超类调用传递时间
// 需要获取权限,请重写permissions方法
// 新增initDataByPermission方法,用于需要获取权限后才可以获取数据的逻辑
public class MainFragment extends BaseVpFragment<FragmentMainBinding> {
@Nullable
@Override
public List<IPermission> permissions() {
// 设置需要动态获取的权限
return super.permissions();
}
@Override
public void dealPermission(Fragment fragment, List<IPermission> permissions, OnPermissionInterceptor interceptor, OnPermissionResult callBack) {
super.dealPermission(fragment, permissions, interceptor, callBack);
// 若使用基类获取权限,可重写此方法
// 设置权限拦截器
// 权限获取结果回调
}
@Override
protected LoadMode getLoadMode() {
// 设置加载模式
return LoadMode.LAZY_VIEW_AND_DATA;
}
@Override
protected void initFirst() {
// 碎片第一次创建
}
@Override
protected void initObject(Bundle savedInstanceState) {
// 初始化对象
}
@Override
protected void initView() {
// 初始化视图
}
@Override
protected void initViewListener() {
// 初始化监听
getBindView().test.setOnClickListener(this);
}
@Override
protected void initDataListener() {
// 初始化数据监听
}
@Override
protected void initData() {
// 初始化数据
}
@Override
public void initDataByPermission() {
//获取全部权限后,才会执行
super.initDataByPermission();
}
@Override
public void antiShakingClick(View v) {
super.antiShakingClick(v);
// 点击事件
}
@Override
public boolean isFastClick(int time) {
// 传递需要的防抖时间阈值
return super.isFastClick(time);
}
@Override
public ViewBinding inflateView(Object o, LayoutInflater layoutInflater) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// 手动动态布局或手动初始化布局
int i = 0;
if (i == 0){
return TestBinding.inflate(getLayoutInflater());
}
return Test1Binding.inflate(getLayoutInflater());
}
@Override
public Class<ViewBinding> setBindViewClass() {
// 动态布局
Class<?> cls;
if (i == 1) {
cls = ActivityMainBinding.class;
} else {
cls = XxxBinding.class;
}
return (Class<ViewBinding>) cls;
}
@Override
public boolean isAsyncLoad() {
// 是否异步加载视图
return false;
}
}// 基类已实现异步布局加载,如需异步加载,请重写isAsyncLoadView方法
// 并返回true
// 若异步加载需要加载弹窗,需要重写initSyncView,并返回实现AsyncLoadViewCallBack
// 默认没有异步加载弹窗
// 需要实现异步加载View动画,请实现AsyncLoadViewCallBack,并重写startAsyncAnimSetView
// 一定要回调animStart,否则基类不会把视图添加至根视图
// 接口的对象,供基类调用,显示和关闭
// 创建xml后,点击编译,填入需要绑定的视图和传递数据类型
// click监听已做快速点击处理,请重写antiShakingClick接口
// 设置Activity主题,请重写initTheme()方法
// 设置权限申请前置步骤,请重写initPermission(String[] permissions)方法
// 如果单个Activity需要动态使用不同的布局文件,请给BaseActivity的泛型类型
// 传递ViewBinding,并重写setBindViewClass模板方法,传递不同ViewBinding类的class
// 如果不想用默认的反射去动态使用不同的布局,请重写inflateView模板方法
// 手动传递和实现ViewBinding类的实例
// 如果有反射加载视图慢的情况,请重写inflateView方法,手动实现ViewBinding类创建
// 需要更改点击防抖时间阈值,请重写isFastClick,在超类调用传递时间
// 需要获取权限,请重写permissions方法
// 新增BaseViewModel#onModelInitDataByPermission方法,用于需要获取权限后才可以获取数据的逻辑
public class MainActivity extends BaseVmActivity<ActivityMainBinding> {
private TestViewModel viewModel;
@Nullable
@Override
public List<IPermission> permissions() {
// 设置需要动态获取的权限
return super.permissions();
}
@Override
public void dealPermission(FragmentActivity activity, List<IPermission> permissions, OnPermissionInterceptor interceptor, OnPermissionResult callBack) {
super.dealPermission(activity, permissions, interceptor, callBack);
// 若使用基类获取权限,可重写此方法
// 设置权限拦截器
// 权限获取结果回调
}
@Override
protected void initObject() {
// 初始化对象
// 如果使用的ViewModel必须继承自BaseViewModel
// 可按照常规方法初始化viewModel,kotlin使用by viewModels()也行
// 框架提供一个createActivityViewModel方法实例化
viewModel = createViewModel(this, TestViewModel.class);
}
@NonNull
@Override
public List<BaseViewModel<ActivityMainBinding, ?>> collectionViewModels() {
// 一定要传入,否则相关抽象方法不会调用
// 设置已经初始化的ViewModel
// 有多个需传递多个
return Collections.singletonList(viewModel);
}
@Override
protected void initView() {
// 初始化视图
}
@Override
protected void initViewListener() {
// 初始化监听
getBindView().test.setOnClickListener(this);
}
@Override
protected void initModelListener() {
// 初始化ViewModel通讯订阅
}
@Override
public void antiShakingClick(View v) {
super.antiShakingClick(v);
// 点击事件
}
@Override
public boolean isFastClick(int time) {
// 传递需要的防抖时间阈值
return super.isFastClick(time);
}
@Override
public Class<ViewBinding> setBindViewClass() {
// 反射动态布局
Class<?> cls;
if (i == 1) {
cls = ActivityMainBinding.class;
} else {
cls = XxxBinding.class;
}
return (Class<ViewBinding>) cls;
}
@Override
public ViewBinding inflateView(Object o, LayoutInflater layoutInflater) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// 手动动态布局或手动初始化布局
int i = 0;
if (i == 0){
return TestBinding.inflate(getLayoutInflater());
}
return Test1Binding.inflate(getLayoutInflater());
}
@Override
public boolean isAsyncLoad() {
// 是否异步加载视图
return false;
}
}// 基类已实现三种懒加载模式:
// DEFAULT:正常加载
// ONLY_LAZY_DATA:只懒加载数据
// LAZY_VIEW_AND_DATA:懒加载数据和页面
// 通过重写getLoadMode方法,返回不同的加载枚举
// 基类会执行不同的加载逻辑,不重写为DEFAULT
// 可通过isLazyInitSuccess方法,获取懒加载是否成功
// 基类已实现异步布局加载,如需异步加载,请重写isAsyncLoadView方法
// 并返回true
// 若异步加载需要加载弹窗,需要重写initSyncView,并返回实现AsyncLoadViewCallBack
// 默认没有异步加载弹窗
// 需要实现异步加载View动画,请实现AsyncLoadViewCallBack,并重写startAsyncAnimSetView
// 一定要回调animStart,否则基类不会把视图添加至根视图
// 接口的对象,供基类调用,显示和关闭
// 创建xml后,点击编译,填入需要绑定的视图和传递数据类型
// click监听已做快速点击处理,请重写antiShakingClick接口
// 设置Activity主题,请重写initTheme()方法
// 设置权限申请前置步骤,请重写initPermission(String[] permissions)方法
// 如果单个Fragment需要动态使用不同的布局文件,请给BaseFragment的泛型类型
// 传递ViewBinding,并重写setBindViewClass模板方法,传递不同ViewBinding类
// 如果不想用默认的反射去动态使用不同的布局,请重写inflateView模板方法
// 手动传递和实现ViewBinding类的实例
// 如果有反射加载视图慢的情况,请重写inflateView方法,手动实现ViewBinding类创建
// 需要更改点击防抖时间阈值,请重写isFastClick,在超类调用传递时间
// 需要获取权限,请重写permissions方法
// 新增BaseViewModel#onModelInitDataByPermission方法,用于需要获取权限后才可以获取数据的逻辑
public class MainFragment extends BaseVmFragment<FragmentMainBinding> {
private TestViewModel viewModel;
@Nullable
@Override
public List<IPermission> permissions() {
// 设置需要动态获取的权限
return super.permissions();
}
@Override
public void dealPermission(Fragment fragment, List<IPermission> permissions, OnPermissionInterceptor interceptor, OnPermissionResult callBack) {
super.dealPermission(fragment, permissions, interceptor, callBack);
// 若使用基类获取权限,可重写此方法
// 设置权限拦截器
// 权限获取结果回调
}
@Override
protected LoadMode getLoadMode() {
// 设置加载模式
return LoadMode.LAZY_VIEW_AND_DATA;
}
@Override
protected void initFirst() {
// 碎片第一次创建
}
@Override
protected void initObject() {
// 初始化对象
// 如果使用的ViewModel必须继承自BaseViewModel
// 可按照常规方法初始化viewModel,kotlin使用by viewModels()也行
// 框架提供一个createActivityViewModel方法实例化
viewModel = createViewModel(this, TestViewModel.class);
}
@NonNull
@Override
public List<BaseViewModel<ActivityMainBinding, ?>> collectionViewModels() {
// 一定要传入,否则相关抽象方法不会调用
// 设置已经初始化的ViewModel
// 有多个需传递多个
return Collections.singletonList(viewModel);
}
@Override
protected void initView() {
// 初始化视图
}
@Override
protected void initViewListener() {
// 初始化监听
getBindView().test.setOnClickListener(this);
}
@Override
protected void initModelListener() {
// 初始化ViewModel通讯订阅
}
@Override
public void antiShakingClick(View v) {
super.antiShakingClick(v);
// 点击事件
}
@Override
public boolean isFastClick(int time) {
// 传递需要的防抖时间阈值
return super.isFastClick(time);
}
@Override
public ViewBinding inflateView(Object o, LayoutInflater layoutInflater) throws InvocationTargetException, IllegalAccessException, NoSuchMethodException {
// 手动动态布局或手动初始化布局
int i = 0;
if (i == 0){
return TestBinding.inflate(getLayoutInflater());
}
return Test1Binding.inflate(getLayoutInflater());
}
@Override
public Class<ViewBinding> setBindViewClass() {
// 动态布局
Class<?> cls;
if (i == 1) {
cls = ActivityMainBinding.class;
} else {
cls = XxxBinding.class;
}
return (Class<ViewBinding>) cls;
}
@Override
public boolean isAsyncLoad() {
// 是否异步加载视图
return false;
}
}// 支持双向等待机制的基类
// 涵盖以上所有Activity和Fragment
// 机制只有在isAsyncLoad()为true的异步布局加载情况下生效
// 同步没必要双向等待
// 剩余功能完全一致
// 以MutualVpActivity为简单使用的例子
class TestActivity : BaseMutualVpActivity<ActivityMain3Binding>() {
private val userData: MutableLiveData<User> = MutableLiveData()
// 声明为true
// 否则使用getBindManager()方法会抛出异常
override fun isAsyncLoadView(): Boolean = true
override fun initObject(savedInstanceState: Bundle?) {
}
override fun initView() {
// 设置绑定器
bindManager.setBinder { data, _ ->
Log.e("TAG", "initDataListener: ${data.toString()}")
}
}
override fun initViewListener() {
}
override fun initDataListener() {
userData.observe(this) {
bindManager.setData(it)
}
}
override fun initData() {
// 模拟异步发送数据
lifecycleScope.launch(Dispatchers.IO) {
delay(5000)
withContext(Dispatchers.Main) {
userData.value = User("小王", 18)
}
}
}
}// 创建xml后,点击编译,填入需要绑定的视图
// 支持ViewBinding
// 自身支持Lifecycle
// 支持监听其他Lifcycle
// click监听已做快速点击处理,请重写antiShakingClick接口
// 如果单个Dialog需要动态使用不同的布局文件,请给BaseDialog的泛型类型
// 传递ViewBinding,并重写setBindViewClass模板方法,传递不同ViewBinding类
// 继承示例
public class TestDialog extends BaseDialog<PopTestBinding> {
public TestDialog(@NonNull Context context) {
super(context);
// 需要观察的Lifecycle
setNeedObserveLifecycle(Lifecycle lifecycle);
}
public TestDialog(@NonNull Context context, int themeResId) {
super(context, themeResId);
// 库里自带一个全屏Dialog主题BaseFullDialog
// 如不合要求,请自定义后传入
}
@Override
protected String setBindViewClass() {
// 动态布局
Class<?> cls;
if (i == 1) {
cls = ActivityMainBinding.class;
} else {
cls = XxxBinding.class;
}
return (Class<ViewBinding>) cls;
}
@Override
protected PopTestBinding inflateView() {
// 可重写后实现视图初始化或手动动态布局
return super.inflateView();
}
@Override
protected DialogSetting setDialogParam() {
DialogSetting setting = new DialogSetting();
// 按照顺序传入指定的X/Y/宽/高数值
setting.setDialogParams(int[] dialogParams);
// 传入Gravity的位置
setting.setDialogPosition(int dialogPosition)
// 是否清除边框
setting.setClearPadding(boolean clearPadding)
// 是否允许外部取消
setting.setCancelOutside(boolean cancelOutside)
// 是否允许拖动
setting.setDrag(boolean drag)
// 是否拥有阴影
setting.setHasShadow(boolean hasShadow)
// 设置Dialog的窗体标识
setting.setSetFlag(int setFlag)
return setting;
}
@Override
protected void initObject(Bundle savedInstanceState) {
// 初始化对象
}
@Override
protected void initView() {
// 初始化视图
}
@Override
protected void initViewListener() {
// 初始化视图监听
}
@Override
protected void initDataListener() {
// 初始化数据监听
}
@Override
protected void initData() {
// 初始化数据
}
@Override
public boolean isFastClick(int time) {
// 传递需要的防抖时间阈值
return PublicEvent.super.isFastClick(time);
}
@Override
public void antiShakingClick(View v) {
// 点击处理
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
// 监听其他Lifecycle组件的声明周期标识符
}
}// MutableLiveData聚合类
// 目的是解耦发散在Presenter或ViewModel中定义的MutableLiveData
// 已实现LifecycleEventObserver、LifecycleOwner接口
// 支持监听生命周期事件(被监听需自实现Lifecycle逻辑,并重写getLifecycle())
// 定义的全局MutableLiveData变量默认无需手动实例化
// BaseMutableLiveData自动反射实例化子类定义的所有全局MutableLiveData变量
// 若不想反射,则在构造超类中,第二参数传递false后,手动实例化即可
// 新增实现UpdateObjEvent接口,用于在ViewModel中,旋转屏幕后更新VmObjManager实例
// 默认自动反射更新类中实现接口的全局变量,若需手动,重写update方法,将isAutoUpdate传入false
// 若全局变量实际对象被隐藏,如懒加载、Kotlin委托,请在对象打上注解@UpdateReflect
// 注解默认提供处理Kotlin委托变量的更新的事件,如需其他处理,可实现UpdateReflectEvent接口
// 在需要处理且实现UpdateObjEvent接口的类中,重写update方法,将实现接口的类,添加到events集合
// 若有其他额外对象需要更新,请重写setReflectRules方法后填入逻辑
public class TestMutable extends BaseMutableLiveData {
private MutableLiveData<Integer> testInteger;
public TestMutable(LifecycleOwner lifecycleOwner) {
// 默认构造超类,自动反射实例化MutableLiveData
super(lifecycleOwner);
// 传递false,取消自动反射实例化
super(lifecycleOwner,false);
// 添加单个需要永久监听的MutableLiveData
setForeverObserve(LiveData<?> mutableLiveData);
// 添加多个需要永久监听的MutableLiveData
this.setForeverObserve(LiveData<?>... mutableLiveData);
// 解除永久监听的MutableLiveData订阅(默认无需手动调用,已在生命周期回调中使用)
this.clearAllForEverObserver(LifecycleOwner owner);
}
@Override
public void onTerminate() {
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
super.onStateChanged(source, event);
}
@Override
public List<UpdateReflectEvent> setReflectRules(List<UpdateReflectEvent> list) {
List<UpdateReflectEvent> temp = UpdateObjEvent.super.setReflectRules(list);
//在此添加额外的反射处理规则实例
return temp;
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager) {
UpdateObjEvent.super.update(manager);
//在此补充额外需要更新实例的逻辑
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate) {
//在此启用/停用自动更新
UpdateObjEvent.super.update(manager, isAutoUpdate);
}
@Override
public void update(Class<?> cls, Object obj, @NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate, List<UpdateReflectEvent> events) {
//在此启用/停用自动更新
//在此传入基于注解需要额外处理的反射的逻辑
UpdateObjEvent.super.update(cls, obj, manager, isAutoUpdate, events);
}
public MutableLiveData<Integer> getTestInteger() {
return testInteger;
}
}// Presenter基类
// 已实现LifecycleEventObserver、LifecycleOwner接口
// 支持监听和生命周期事件(被监听需自实现Lifecycle逻辑,并重写getLifecycle())
// 新增实现UpdateObjEvent接口,用于在ViewModel中,旋转屏幕后更新VmObjManager实例
// 默认自动反射更新类中实现接口的全局变量,若需手动,重写update方法,将isAutoUpdate传入false
// 若全局变量实际对象被隐藏,如懒加载、Kotlin委托,请在对象打上注解@UpdateReflect
// 注解默认提供处理Kotlin委托变量的更新的事件,如需其他处理,可实现UpdateReflectEvent接口
// 在需要处理且实现UpdateObjEvent接口的类中,重写update方法,将实现接口的类,添加到events集合
// 若有其他额外对象需要更新,请重写setReflectRules方法后填入逻辑
public class TestPresenter extends BasePresenter<TestMutable> {
private final TestMutable testMutable;
public TestPresenter(LifecycleOwner observeLifecycle) {
super(observeLifecycle);
this.testMutable = new TestMutable(observeLifecycle);
}
@Override
public TestMutable getMutable() {
return testMutable;
}
@Override
public void onTerminate() {
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
super.onStateChanged(source, event);
}
@Override
public List<UpdateReflectEvent> setReflectRules(List<UpdateReflectEvent> list) {
List<UpdateReflectEvent> temp = UpdateObjEvent.super.setReflectRules(list);
//在此添加额外的反射处理规则实例
return temp;
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager) {
super.update(manager);
//在此补充额外需要更新实例的逻辑
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate) {
//在此启用/停用自动更新
UpdateObjEvent.super.update(manager, isAutoUpdate);
}
@Override
public void update(Class<?> cls, Object obj, @NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate, List<UpdateReflectEvent> events) {
//在此启用/停用自动更新
//在此传入基于注解需要额外处理的反射的逻辑
UpdateObjEvent.super.update(cls, obj, manager, isAutoUpdate, events);
}
}// ViewModel基类
// 后者为使用双向等待基类所需使用的配套ViewModel,使用方式无异
// 已实现LifecycleEventObserver、LifecycleOwner接口
// 已支持监听和生命周期事件
// 可搭配presenter使用,进行数据获取解耦,model内只处理业务数据逻辑和页面数据绑定
// 新增实现UpdateObjEvent接口,用于在ViewModel中,旋转屏幕后更新VmObjManager实例
// 默认自动反射更新类中实现接口的全局变量,若需手动,重写update方法,将isAutoUpdate传入false
// 若全局变量实际对象被隐藏,如懒加载、Kotlin委托,请在对象打上注解@UpdateReflect
// 注解默认提供处理Kotlin委托变量的更新的事件,如需其他处理,可实现UpdateReflectEvent接口
// 在需要处理且实现UpdateObjEvent接口的类中,重写update方法,将实现接口的类,添加到events集合
// 若有其他额外对象需要更新,请重写setReflectRules方法后填入逻辑
public class TestViewModel extends BaseViewModel<ActivityMain2Binding, TestMutable> {
private TestMutable testMutable;
private TestPresenter presenter;
@Override
public TestMutable getMutable() {
return testMutable;
}
@Override
public void onModelCreated() {
//如果项目场景不存在旋转屏幕的情况
//在这里初始化或全局初始化都可以
//若存在旋转场景且不想activity重建后重新实例化
//BaseMutableLiveData和BasePresenter已实现UpdateObjEvent接口,调用update方法更新即可
//其他自定义类,实现UpdateObjEvent接口后自行展开逻辑
this.testMutable = new TestMutable(getObserveLifecycleOwner());
this.presenter = new TestPresenter(getObserveLifecycleOwner());
}
@Override
public void onModelInitView() {
// 视图准备完成
// 初始化视图
}
@Override
public void onModelInitListener() {
// 初始化数据监听
// 若是双向等待,这里可以设置双向监听
presenter.getMutable().getTestInteger().observe(observeLifecycle(), integer -> getBindView().test.setText(integer + ""));
}
@Override
public void onModelInitData() {
}
@Override
public void onModelInitDataByPermission() {
super.onModelInitDataByPermission()
}
@Override
public void onTerminate() {
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
super.onStateChanged(source, event);
}
@Override
public List<UpdateReflectEvent> setReflectRules(List<UpdateReflectEvent> list) {
List<UpdateReflectEvent> temp = UpdateObjEvent.super.setReflectRules(list);
//在此添加额外的反射处理规则实例
return temp;
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager) {
super.update(manager);
//在此补充额外需要更新实例的逻辑
}
@Override
public void update(@NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate) {
//在此启用/停用自动更新
UpdateObjEvent.super.update(manager, isAutoUpdate);
}
@Override
public void update(Class<?> cls, Object obj, @NonNull VmObjManager<? extends ViewBinding> manager, boolean isAutoUpdate, List<UpdateReflectEvent> events) {
//在此启用/停用自动更新
//在此传入基于注解需要额外处理的反射的逻辑
UpdateObjEvent.super.update(cls, obj, manager, isAutoUpdate, events);
}
public void test() {
presenter.testInteger();
}
}// 支持应用前后台判断
// 已接入MyActivityManager,可直接使用
// 已接入MyApplicationManager,可直接使用
// 已实现ViewModelStoreOwner,可通过getGlobalViewModel()获取全局ViewModel
public class MyApplication extends BaseApplication {
@Override
protected void init() {
// 初始化
}
}
// 判断应用在前/后台
// true为前台
// false为后台
MyApplication.isAppForeground()// 使用BaseApplication可直接使用
// 单独使用,需要在ActivityLifecycleCallbacks回调中的onActivityResumed设置
// 支持弱引用,获取到的Activity已做弱引用处理
// 设置当前正在显示的Activity
MyActivityManager.INSTANCE.setCurrentActivity(Activity activity);
// 获取当前正在显示的Activity
MyActivityManager.INSTANCE.getCurrentActivity();// 使用BaseApplication可直接使用
// 单独使用,需要在Application的onCreate设置
// 支持弱引用,获取到的Context已做弱引用处理
// 设置当前Context
MyApplicationManager.INSTANCE.setCurrentContext(Context context);
// 获取当前Context
MyApplicationManager.INSTANCE.getCurrentContext();CrashConfig.Builder
.create()
// 当应用程序处于后台时崩溃,也会启动错误页面
.backgroundMode(CrashConfig.BACKGROUND_MODE_SHOW_CUSTOM)
// 当应用程序处于后台崩溃时显示默认系统错误
.backgroundMode(CrashConfig.BACKGROUND_MODE_CRASH)
// 当应用程序处于后台时崩溃,默默地关闭程序
.backgroundMode(CrashConfig.BACKGROUND_MODE_SILENT)
// false表示对崩溃的拦截阻止。用它来禁用customactivityoncrash
.enabled(true)
// 这将隐藏错误活动中的"错误详细信息"按钮,从而隐藏堆栈跟踪,针对框架自带程序崩溃后显示的页面有用
.showErrorDetails(true)
// 是否可以重启页面,针对框架自带程序崩溃后显示的页面有用
.showRestartButton(true)
// 崩溃页面显示的图标
.errorDrawable(R.mipmap.ic_launcher)
.logErrorOnRestart(true)
// 错误页面中显示错误详细信息
.trackActivities(true)
// 定义应用程序崩溃之间的最短时间,以确定我们不在崩溃循环中
.minTimeBetweenCrashesMs(2000)
// 重新启动后的页面
.restartActivity(LoginActivity.class)
.apply();
// 需要在AM文件中声明Provider,以启用崩溃组件
<provider
android:name="cn.com.shadowless.baseview.crash.provider.CrashInitProvider"
android:authorities="${applicationId}.customActivityOnCrashInitProvider"
android:exported="false"
android:initOrder="101" />// 快速实现一个自身支持Lifecycle和支持监听其他Lifecycle的类
// 默认不重写getLifecycle时,lifecycle只跟监听的生命周期有关
// 重写并实现自身生命周期逻辑后,才区分自身与监听
public class Test implements BaseQuickLifecycle {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event){
}
@NonNull
@Override
public Lifecycle getLifecycle() {
// 实现自己的Lifecycle事件逻辑
return null;
}
@Nullable
@Override
public LifecycleOwner getObserveLifecycleOwner() {
// 监听的生命周期
return observeLifecycle;
}
}// 可动态变更是否粘性接收的LiveData
// 使用和正常的LiveData相同
// 新增方法:
// 设置是否粘性接收(发送前或接收后设置)
SingleMutableLiveData<?>.setSingleEvent(boolean singleEvent);