feat: 添加DI框架Hilt,重构基类部分,添加module_home模块示例用法

This commit is contained in:
Quyunshuo
2021-05-25 17:47:55 +08:00
parent eb8ec75f04
commit 3ca38ee5b2
40 changed files with 316 additions and 118 deletions

View File

@@ -102,6 +102,7 @@ android {
* [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel) * [ViewModel](https://developer.android.com/topic/libraries/architecture/viewmodel)
* [LiveData](https://developer.android.com/topic/libraries/architecture/livedata) * [LiveData](https://developer.android.com/topic/libraries/architecture/livedata)
* [ViewBinding](https://developer.android.com/topic/libraries/view-binding) * [ViewBinding](https://developer.android.com/topic/libraries/view-binding)
* [Hilt](https://developer.android.com/jetpack/androidx/releases/hilt)
* [Android KTX](https://developer.android.com/kotlin/ktx) * [Android KTX](https://developer.android.com/kotlin/ktx)
* [OkHttp](https://github.com/square/okhttp):网络请求 * [OkHttp](https://github.com/square/okhttp):网络请求
* [Retrofit](https://github.com/square/retrofit):网络请求 * [Retrofit](https://github.com/square/retrofit):网络请求
@@ -364,4 +365,16 @@ fun test() {
**资料:** **资料:**
官方文档: [https://developer.android.com/topic/libraries/architecture/lifecycle](https://developer.android.com/topic/libraries/architecture/lifecycle) 官方文档: [https://developer.android.com/topic/libraries/architecture/lifecycle](https://developer.android.com/topic/libraries/architecture/lifecycle)
### Hilt
**Hilt****Android** 的依赖项注入库,可减少在项目中执行手动依赖项注入的样板代码。执行手动依赖项注入要求您手动构造每个类及其依赖项,并借助容器重复使用和管理依赖项。
**Hilt** 通过为项目中的每个 **Android** 类提供容器并自动管理其生命周期,提供了一种在应用中使用 **DI依赖项注入**的标准方法。**Hilt** 在热门 **DI****Dagger** 的基础上构建而成,因而能够受益于 **Dagger** 的编译时正确性、运行时性能、可伸缩性和 **Android Studio** 支持。
**资料:**
目前官方文档还没有更新正式版的,还是 **alpha** 版本的文档:[使用 Hilt 实现依赖项注入](https://developer.android.com/training/dependency-injection/hilt-android)
**Dagger****Hilt** 文档目前是最新的:[Dagger-Hilt](https://dagger.dev/hilt/)

View File

@@ -12,6 +12,7 @@
tools:ignore="ProtectedPermissions" /> tools:ignore="ProtectedPermissions" />
<application <application
android:name=".app.AppApplication"
android:allowBackup="false" android:allowBackup="false"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
android:label="@string/app_name" android:label="@string/app_name"

View File

@@ -1,10 +1,7 @@
package com.quyunshuo.androidbaseframemvvm.app package com.quyunshuo.androidbaseframemvvm.app
import android.app.Application import com.quyunshuo.androidbaseframemvvm.base.app.BaseApplication
import android.content.Context import dagger.hilt.android.HiltAndroidApp
import com.google.auto.service.AutoService
import com.quyunshuo.androidbaseframemvvm.base.app.ApplicationLifecycle
import com.quyunshuo.androidbaseframemvvm.base.app.InitDepend
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
/** /**
@@ -13,42 +10,15 @@ import org.greenrobot.eventbus.EventBus
* @author Qu Yunshuo * @author Qu Yunshuo
* @since 4/23/21 6:08 PM * @since 4/23/21 6:08 PM
*/ */
@AutoService(ApplicationLifecycle::class) @HiltAndroidApp
class AppApplication : ApplicationLifecycle { class AppApplication : BaseApplication() {
/** override fun onCreate() {
* 同[Application.attachBaseContext]
* @param context Context
*/
override fun onAttachBaseContext(context: Context) {
// 开启EventBusAPT,优化反射效率 当组件作为App运行时需要将添加的Index注释掉 因为找不到对应的类了 // 开启EventBusAPT,优化反射效率 当组件作为App运行时需要将添加的Index注释掉 因为找不到对应的类了
EventBus EventBus
.builder() .builder()
// .addIndex(MainEventIndex()) // .addIndex(MainEventIndex())
.installDefaultEventBus() .installDefaultEventBus()
super.onCreate()
} }
/**
* 同[Application.onCreate]
* @param application Application
*/
override fun onCreate(application: Application) {}
/**
* 同[Application.onTerminate]
* @param application Application
*/
override fun onTerminate(application: Application) {}
/**
* 需要立即进行初始化的放在这里进行并行初始化
* 需要必须在主线程初始化的放在[InitDepend.mainThreadDepends],反之放在[InitDepend.workerThreadDepends]
* @return InitDepend 初始化方法集合
*/
override fun initByFrontDesk(): InitDepend = InitDepend(mutableListOf(), mutableListOf())
/**
* 不需要立即初始化的放在这里进行后台初始化
*/
override fun initByBackstage() {}
} }

View File

@@ -11,6 +11,7 @@ buildscript {
classpath ProjectPluginManager.AndroidToolsPlugin classpath ProjectPluginManager.AndroidToolsPlugin
classpath ProjectPluginManager.KotlinPlugin classpath ProjectPluginManager.KotlinPlugin
classpath ProjectPluginManager.ARouterRegister classpath ProjectPluginManager.ARouterRegister
classpath ProjectPluginManager.HiltPlugin
} }
} }
@@ -18,6 +19,7 @@ allprojects {
repositories { repositories {
google() google()
jcenter() jcenter()
mavenCentral()
} }
} }

View File

@@ -8,6 +8,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'com.alibaba.arouter' apply plugin: 'com.alibaba.arouter'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
android { android {
compileSdkVersion ProjectBuildConfig.compileSdkVersion compileSdkVersion ProjectBuildConfig.compileSdkVersion
@@ -87,9 +88,13 @@ dependencies {
if (!ProjectBuildConfig.isAppMode) { if (!ProjectBuildConfig.isAppMode) {
// 有业务组件时 把这个去掉 这里只是为了使用base里的依赖库 // 有业务组件时 把这个去掉 这里只是为了使用base里的依赖库
implementation project(path: ':lib_common') implementation project(path: ':module_home')
} else { } else {
implementation project(path: ':lib_common') implementation project(path: ':lib_common')
} }
implementation DependencyConfig.JetPack.HiltCore
kapt DependencyConfig.GitHub.AutoServiceAnnotations kapt DependencyConfig.GitHub.AutoServiceAnnotations
kapt DependencyConfig.JetPack.HiltApt
kapt DependencyConfig.JetPack.HiltAndroidx
} }

View File

@@ -7,6 +7,7 @@ import com.quyunshuo.androidbaseframemvvm.buildsrc.*
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
android { android {
compileSdkVersion ProjectBuildConfig.compileSdkVersion compileSdkVersion ProjectBuildConfig.compileSdkVersion

View File

@@ -4,14 +4,15 @@
import com.quyunshuo.androidbaseframemvvm.buildsrc.* import com.quyunshuo.androidbaseframemvvm.buildsrc.*
if (ProjectBuildConfig.isAppMode){ if (ProjectBuildConfig.isAppMode) {
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
}else { } else {
apply plugin: 'com.android.library' apply plugin: 'com.android.library'
} }
apply plugin: 'kotlin-android' apply plugin: 'kotlin-android'
apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-kapt'
apply plugin: 'dagger.hilt.android.plugin'
android { android {
compileSdkVersion ProjectBuildConfig.compileSdkVersion compileSdkVersion ProjectBuildConfig.compileSdkVersion
@@ -81,9 +82,13 @@ dependencies {
testImplementation DependencyConfig.Android.Junit testImplementation DependencyConfig.Android.Junit
androidTestImplementation DependencyConfig.AndroidX.TestExtJunit androidTestImplementation DependencyConfig.AndroidX.TestExtJunit
androidTestImplementation DependencyConfig.AndroidX.TestEspresso androidTestImplementation DependencyConfig.AndroidX.TestEspresso
implementation DependencyConfig.JetPack.HiltCore
kapt DependencyConfig.GitHub.GlideCompiler kapt DependencyConfig.GitHub.GlideCompiler
kapt DependencyConfig.GitHub.ARouteCompiler kapt DependencyConfig.GitHub.ARouteCompiler
kapt DependencyConfig.GitHub.EventBusAPT kapt DependencyConfig.GitHub.EventBusAPT
kapt DependencyConfig.GitHub.AutoServiceAnnotations kapt DependencyConfig.GitHub.AutoServiceAnnotations
kapt DependencyConfig.JetPack.HiltApt
kapt DependencyConfig.JetPack.HiltAndroidx
kapt DependencyConfig.JetPack.LifecycleCompilerAPT kapt DependencyConfig.JetPack.LifecycleCompilerAPT
} }

View File

@@ -3,6 +3,7 @@
//**************************************** //****************************************
apply from: '../buildGradleScript/base/base_lib.gradle' apply from: '../buildGradleScript/base/base_lib.gradle'
apply plugin: 'dagger.hilt.android.plugin'
import com.quyunshuo.androidbaseframemvvm.buildsrc.* import com.quyunshuo.androidbaseframemvvm.buildsrc.*
@@ -35,6 +36,7 @@ dependencies {
api DependencyConfig.JetPack.ViewModelSavedState api DependencyConfig.JetPack.ViewModelSavedState
api DependencyConfig.JetPack.LiveData api DependencyConfig.JetPack.LiveData
api DependencyConfig.JetPack.Lifecycle api DependencyConfig.JetPack.Lifecycle
api DependencyConfig.JetPack.HiltCore
api DependencyConfig.GitHub.Gson api DependencyConfig.GitHub.Gson
api DependencyConfig.GitHub.MMKV api DependencyConfig.GitHub.MMKV
@@ -55,6 +57,8 @@ dependencies {
kapt DependencyConfig.GitHub.ARouteCompiler kapt DependencyConfig.GitHub.ARouteCompiler
kapt DependencyConfig.GitHub.EventBusAPT kapt DependencyConfig.GitHub.EventBusAPT
kapt DependencyConfig.GitHub.AutoServiceAnnotations kapt DependencyConfig.GitHub.AutoServiceAnnotations
kapt DependencyConfig.JetPack.HiltApt
kapt DependencyConfig.JetPack.HiltAndroidx
kapt DependencyConfig.JetPack.LifecycleCompilerAPT kapt DependencyConfig.JetPack.LifecycleCompilerAPT
debugApi DependencyConfig.GitHub.LeakCanary debugApi DependencyConfig.GitHub.LeakCanary

View File

@@ -27,9 +27,13 @@ dependencies {
api project(path: ':lib_base') api project(path: ':lib_base')
api project(path: ':lib_net') api project(path: ':lib_net')
api DependencyConfig.JetPack.HiltCore
kapt DependencyConfig.GitHub.GlideCompiler kapt DependencyConfig.GitHub.GlideCompiler
kapt DependencyConfig.GitHub.ARouteCompiler kapt DependencyConfig.GitHub.ARouteCompiler
kapt DependencyConfig.GitHub.EventBusAPT kapt DependencyConfig.GitHub.EventBusAPT
kapt DependencyConfig.GitHub.AutoServiceAnnotations kapt DependencyConfig.GitHub.AutoServiceAnnotations
kapt DependencyConfig.JetPack.HiltApt
kapt DependencyConfig.JetPack.HiltAndroidx
kapt DependencyConfig.JetPack.LifecycleCompilerAPT kapt DependencyConfig.JetPack.LifecycleCompilerAPT
} }

View File

@@ -3,6 +3,7 @@
//**************************************** //****************************************
apply from: '../buildGradleScript/base/base_lib.gradle' apply from: '../buildGradleScript/base/base_lib.gradle'
apply plugin: 'dagger.hilt.android.plugin'
import com.quyunshuo.androidbaseframemvvm.buildsrc.* import com.quyunshuo.androidbaseframemvvm.buildsrc.*
@@ -19,6 +20,9 @@ dependencies {
api DependencyConfig.GitHub.OkHttpInterceptorLogging api DependencyConfig.GitHub.OkHttpInterceptorLogging
api DependencyConfig.GitHub.Retrofit api DependencyConfig.GitHub.Retrofit
api DependencyConfig.GitHub.RetrofitConverterGson api DependencyConfig.GitHub.RetrofitConverterGson
api DependencyConfig.JetPack.HiltCore
kapt DependencyConfig.GitHub.AutoServiceAnnotations kapt DependencyConfig.GitHub.AutoServiceAnnotations
kapt DependencyConfig.JetPack.HiltApt
kapt DependencyConfig.JetPack.HiltAndroidx
} }

View File

@@ -35,7 +35,9 @@ object DependencyConfig {
const val Coroutines = "1.4.3" // 协程 const val Coroutines = "1.4.3" // 协程
// JetPack--------------------------------------------------------------- // JetPack---------------------------------------------------------------
const val Lifecycle = "2.3.1" const val Lifecycle = "2.3.1" // Lifecycle相关ViewModel & LiveData & Lifecycle
const val Hilt = "2.35.1" // DI框架-Hilt
const val HiltAndroidx = "1.0.0"
// GitHub---------------------------------------------------------------- // GitHub----------------------------------------------------------------
const val OkHttp = "3.14.9" // OkHttp const val OkHttp = "3.14.9" // OkHttp
@@ -105,6 +107,9 @@ object DependencyConfig {
const val Lifecycle = "androidx.lifecycle:lifecycle-runtime-ktx:${Version.Lifecycle}" const val Lifecycle = "androidx.lifecycle:lifecycle-runtime-ktx:${Version.Lifecycle}"
const val LifecycleCompilerAPT = const val LifecycleCompilerAPT =
"androidx.lifecycle:lifecycle-compiler:${Version.Lifecycle}" "androidx.lifecycle:lifecycle-compiler:${Version.Lifecycle}"
const val HiltCore = "com.google.dagger:hilt-android:${Version.Hilt}"
const val HiltApt = "com.google.dagger:hilt-compiler:${Version.Hilt}"
const val HiltAndroidx = "androidx.hilt:hilt-compiler:${Version.HiltAndroidx}"
} }
/** /**

View File

@@ -7,7 +7,8 @@ package com.quyunshuo.androidbaseframemvvm.buildsrc
* @since 4/24/21 5:56 PM * @since 4/24/21 5:56 PM
*/ */
object ProjectPluginManager { object ProjectPluginManager {
const val AndroidToolsPlugin = "com.android.tools.build:gradle:4.1.2" const val AndroidToolsPlugin = "com.android.tools.build:gradle:4.1.3"
const val KotlinPlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32" const val KotlinPlugin = "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32"
const val ARouterRegister = "com.alibaba:arouter-register:1.0.2" const val ARouterRegister = "com.alibaba:arouter-register:1.0.2"
const val HiltPlugin = "com.google.dagger:hilt-android-gradle-plugin:2.35.1"
} }

View File

@@ -1,6 +1,6 @@
#Wed Aug 26 17:16:28 CST 2020 #Sat May 22 08:57:40 CST 2021
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

View File

@@ -13,7 +13,7 @@ import kotlin.system.measureTimeMillis
* @author Qu Yunshuo * @author Qu Yunshuo
* @since 4/24/21 5:30 PM * @since 4/24/21 5:30 PM
*/ */
class BaseApplication : MultiDexApplication() { open class BaseApplication : MultiDexApplication() {
private val mCoroutineScope by lazy(mode = LazyThreadSafetyMode.NONE) { MainScope() } private val mCoroutineScope by lazy(mode = LazyThreadSafetyMode.NONE) { MainScope() }

View File

@@ -6,10 +6,10 @@ import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.flowOn
/** /**
* @Author: QuYunShuo * 仓库层 Repository 基类
* @Time: 2020/8/27 *
* @Class: BaseRepository * @author Qu Yunshuo
* @Remark: 仓库层 Repository 基类 * @since 8/27/20
*/ */
open class BaseRepository { open class BaseRepository {

View File

@@ -2,7 +2,6 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import android.os.Bundle import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
@@ -10,22 +9,17 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/** /**
* @Author: QuYunShuo * Activity基类
* @Time: 2020/8/27 *
* @Class: BaseFrameActivity * @author Qu Yunshuo
* @Remark: Activity基类 与项目无关 * @since 8/27/20
*/ */
abstract class BaseFrameActivity<VB : ViewBinding, VM : ViewModel> : abstract class BaseFrameActivity<VB : ViewBinding> : AppCompatActivity(), FrameView<VB> {
AppCompatActivity(), FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater) BindingReflex.reflexViewBinding(javaClass, layoutInflater)
} }
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewModel(javaClass, this)
}
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContentView(mBinding.root) setContentView(mBinding.root)

View File

@@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
import androidx.fragment.app.Fragment import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter import com.alibaba.android.arouter.launcher.ARouter
import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex import com.quyunshuo.androidbaseframemvvm.base.utils.BindingReflex
@@ -13,21 +12,17 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/** /**
* @Author: QuYunShuo * Fragment基类
* @Time: 2020/8/27 *
* @Class: BaseFrameFragment * @author Qu Yunshuo
* @Remark: Fragment基类 与项目无关 * @since 8/27/20
*/ */
abstract class BaseFrameFragment<VB : ViewBinding, VM : ViewModel> : Fragment(), FrameView<VB> { abstract class BaseFrameFragment<VB : ViewBinding> : Fragment(), FrameView<VB> {
protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) { protected val mBinding: VB by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater) BindingReflex.reflexViewBinding(javaClass, layoutInflater)
} }
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewModel(javaClass, this)
}
override fun onCreateView( override fun onCreateView(
inflater: LayoutInflater, inflater: LayoutInflater,
container: ViewGroup?, container: ViewGroup?,

View File

@@ -9,10 +9,10 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/** /**
* @Author: QuYunShuo * 不使用 MVVM 的 Activity 基类
* @Time: 2020/9/10 *
* @Class: BaseFrameNotMVVMActivity * @author Qu Yunshuo
* @Remark: 不使用 MVVM 的 Activity 基类 * @since /9/10/20
*/ */
abstract class BaseFrameNotMVVMActivity<VB : ViewBinding> : AppCompatActivity(), abstract class BaseFrameNotMVVMActivity<VB : ViewBinding> : AppCompatActivity(),
FrameNotMVVMView<VB> { FrameNotMVVMView<VB> {

View File

@@ -12,10 +12,10 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/** /**
* @Author: QuYunShuo * 不使用 MVVM 的 Fragment 基类
* @Time: 2020/9/10 *
* @Class: BaseFrameNotMVVMFragment * @author Qu Yunshuo
* @Remark: 不使用 MVVM 的 Fragment 基类 * @since 9/10/20
*/ */
abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> { abstract class BaseFrameNotMVVMFragment<VB : ViewBinding> : Fragment(), FrameNotMVVMView<VB> {

View File

@@ -3,10 +3,10 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
/** /**
* @Author: QuYunShuo * View层基类抽象
* @Time: 2020/10/13 *
* @Class: FrameNotMVVMView * @author Qu Yunshuo
* @Remark: View层基类抽象 * @since 10/13/20
*/ */
interface FrameNotMVVMView<VB : ViewBinding> { interface FrameNotMVVMView<VB : ViewBinding> {
/** /**

View File

@@ -3,10 +3,10 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.v
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
/** /**
* @Author: QuYunShuo * View层基类抽象
* @Time: 2020/10/13 *
* @Class: FrameView * @author Qu Yunshuo
* @Remark: View层基类抽象 * @since 10/13/20
*/ */
interface FrameView<VB : ViewBinding> { interface FrameView<VB : ViewBinding> {
/** /**

View File

@@ -2,23 +2,18 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.vm
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import com.quyunshuo.androidbaseframemvvm.base.mvvm.m.BaseRepository
/** /**
* @Author: QuYunShuo * ViewModel 基类
* @Time: 2020/8/27 *
* @Class: BaseViewModel * @author Qu Yunshuo
* @Remark: ViewModel 基类 * @since 8/27/20
*/ */
abstract class BaseViewModel<R : BaseRepository> : ViewModel() { abstract class BaseViewModel : ViewModel() {
// Loading 状态 // Loading 状态
val isLoading = MutableLiveData(false) val isLoading = MutableLiveData(false)
// 请求异常 // 请求异常
val requestError = MutableLiveData<Throwable?>() val requestError = MutableLiveData<Throwable?>()
protected val mRepository: R by lazy { initRepository() }
protected abstract fun initRepository(): R
} }

View File

@@ -7,7 +7,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application android:name="com.quyunshuo.androidbaseframemvvm.base.app.BaseApplication"> <application>
<!-- 屏幕适配基准DP --> <!-- 屏幕适配基准DP -->
<meta-data <meta-data

View File

@@ -1,13 +1,12 @@
package com.quyunshuo.androidbaseframemvvm.common.ui package com.quyunshuo.androidbaseframemvvm.common.ui
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameActivity import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameActivity
/** /**
* @Author: QuYunShuo * Activity基类
* @Time: 2020/8/27 *
* @Class: BaseActivity * @author Qu Yunshuo
* @Remark: 项目相关的Activity基类 * @since 8/27/20
*/ */
abstract class BaseActivity<VB : ViewBinding, VM : ViewModel> : BaseFrameActivity<VB, VM>() abstract class BaseActivity<VB : ViewBinding> : BaseFrameActivity<VB>()

View File

@@ -1,13 +1,12 @@
package com.quyunshuo.androidbaseframemvvm.common.ui package com.quyunshuo.androidbaseframemvvm.common.ui
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameFragment import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameFragment
/** /**
* @Author: QuYunShuo * Fragment基类
* @Time: 2020/8/27 *
* @Class: BaseFragment * @author Qu Yunshuo
* @Remark: 项目相关的Fragment基类 * @since 8/27/20
*/ */
abstract class BaseFragment<VB : ViewBinding, VM : ViewModel> : BaseFrameFragment<VB, VM>() abstract class BaseFragment<VB : ViewBinding> : BaseFrameFragment<VB>()

View File

@@ -4,9 +4,9 @@ import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameNotMVVMActivity import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameNotMVVMActivity
/** /**
* @Author: QuYunShuo * 不是 MVVM 模式的基类
* @Time: 2020/9/10 *
* @Class: BaseNotMVVMActivity * @author Qu Yunshuo
* @Remark: 不是 MVVM 模式的基类 * @since 9/10/20
*/ */
abstract class BaseNotMVVMActivity<VB : ViewBinding> : BaseFrameNotMVVMActivity<VB>() abstract class BaseNotMVVMActivity<VB : ViewBinding> : BaseFrameNotMVVMActivity<VB>()

View File

@@ -4,9 +4,9 @@ import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameNotMVVMFragment import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameNotMVVMFragment
/** /**
* @Author: QuYunShuo * 不是 MVVM 模式的基类
* @Time: 2020/9/10 *
* @Class: BaseNotMVVMFragment * @author Qu Yunshuo
* @Remark: 不是 MVVM 模式的基类 * @since 9/10/20
*/ */
abstract class BaseNotMVVMFragment<VB : ViewBinding> : BaseFrameNotMVVMFragment<VB>() abstract class BaseNotMVVMFragment<VB : ViewBinding> : BaseFrameNotMVVMFragment<VB>()

1
module_home/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1 @@
apply("../buildGradleScript/module_home.gradle")

View File

21
module_home/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,24 @@
package com.quyunshuo.module.home
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("com.quyunshuo.module.home.test", appContext.packageName)
}
}

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.quyunshuo.module.home">
<application>
<!-- Main 首页 -->
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@@ -0,0 +1,22 @@
package com.quyunshuo.module.home
import com.quyunshuo.androidbaseframemvvm.base.mvvm.m.BaseRepository
import kotlinx.coroutines.delay
import javax.inject.Inject
/**
* 首页M层
*
* @author Qu Yunshuo
* @since 5/25/21 5:42 PM
*/
class HomeRepository @Inject constructor() : BaseRepository() {
/**
* 模拟获取数据
*/
suspend fun getData() = flowRequest<String> {
delay(1000L)
emit("Hello Hilt")
}
}

View File

@@ -0,0 +1,37 @@
package com.quyunshuo.module.home
import android.util.Log
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.viewModelScope
import com.quyunshuo.androidbaseframemvvm.base.mvvm.vm.BaseViewModel
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.launch
import javax.inject.Inject
/**
* 首页的VM层
*
* @property mRepository HomeRepository 仓库层 通过Hilt注入
*
* @author Qu Yunshuo
* @since 5/25/21 5:41 PM
*/
@HiltViewModel
class HomeViewModel @Inject constructor(private val mRepository: HomeRepository) : BaseViewModel() {
val data = MutableLiveData<String>()
/**
* 模拟获取数据
*/
fun getData() {
viewModelScope.launch(Dispatchers.IO) {
mRepository.getData()
.catch { Log.d("qqq", "getData: $it") }
.collect { data.postValue(it) }
}
}
}

View File

@@ -0,0 +1,37 @@
package com.quyunshuo.module.home
import android.graphics.Color
import androidx.activity.viewModels
import com.quyunshuo.androidbaseframemvvm.common.ui.BaseActivity
import com.quyunshuo.module.home.databinding.HomeActivityMainBinding
import dagger.hilt.android.AndroidEntryPoint
/**
* 首页
*
* @author Qu Yunshuo
* @since 5/22/21 2:26 PM
*/
@AndroidEntryPoint
class MainActivity : BaseActivity<HomeActivityMainBinding>() {
/**
* 通过 viewModels() + Hilt 获取 ViewModel 实例
*/
private val mViewModel by viewModels<HomeViewModel>()
override fun HomeActivityMainBinding.initView() {}
override fun initLiveDataObserve() {
// 订阅数据
mViewModel.data.observe(this, {
mBinding.vTvHello.text = it
mBinding.vTvHello.setTextColor(Color.BLUE)
})
}
override fun initRequestData() {
// 模拟获取数据
mViewModel.getData()
}
}

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:id="@+id/vTvHello"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World"
android:textColor="@android:color/black"
android:textSize="20sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="HardcodedText" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1 @@
<resources></resources>

View File

@@ -0,0 +1,17 @@
package com.quyunshuo.module.home
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@@ -2,5 +2,6 @@ include(
":app", ":app",
":lib_base", ":lib_base",
":lib_common", ":lib_common",
":lib_net" ":lib_net",
":module_home"
) )