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)
* [LiveData](https://developer.android.com/topic/libraries/architecture/livedata)
* [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)
* [OkHttp](https://github.com/square/okhttp):网络请求
* [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" />
<application
android:name=".app.AppApplication"
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"

View File

@ -1,10 +1,7 @@
package com.quyunshuo.androidbaseframemvvm.app
import android.app.Application
import android.content.Context
import com.google.auto.service.AutoService
import com.quyunshuo.androidbaseframemvvm.base.app.ApplicationLifecycle
import com.quyunshuo.androidbaseframemvvm.base.app.InitDepend
import com.quyunshuo.androidbaseframemvvm.base.app.BaseApplication
import dagger.hilt.android.HiltAndroidApp
import org.greenrobot.eventbus.EventBus
/**
@ -13,42 +10,15 @@ import org.greenrobot.eventbus.EventBus
* @author Qu Yunshuo
* @since 4/23/21 6:08 PM
*/
@AutoService(ApplicationLifecycle::class)
class AppApplication : ApplicationLifecycle {
@HiltAndroidApp
class AppApplication : BaseApplication() {
/**
* 同[Application.attachBaseContext]
* @param context Context
*/
override fun onAttachBaseContext(context: Context) {
override fun onCreate() {
// 开启EventBusAPT,优化反射效率 当组件作为App运行时需要将添加的Index注释掉 因为找不到对应的类了
EventBus
.builder()
// .addIndex(MainEventIndex())
.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.KotlinPlugin
classpath ProjectPluginManager.ARouterRegister
classpath ProjectPluginManager.HiltPlugin
}
}
@ -18,6 +19,7 @@ allprojects {
repositories {
google()
jcenter()
mavenCentral()
}
}

View File

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

View File

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

View File

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

View File

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

View File

@ -3,6 +3,7 @@
//****************************************
apply from: '../buildGradleScript/base/base_lib.gradle'
apply plugin: 'dagger.hilt.android.plugin'
import com.quyunshuo.androidbaseframemvvm.buildsrc.*
@ -19,6 +20,9 @@ dependencies {
api DependencyConfig.GitHub.OkHttpInterceptorLogging
api DependencyConfig.GitHub.Retrofit
api DependencyConfig.GitHub.RetrofitConverterGson
api DependencyConfig.JetPack.HiltCore
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" // 协程
// 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----------------------------------------------------------------
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 LifecycleCompilerAPT =
"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
*/
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 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
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
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
* @since 4/24/21 5:30 PM
*/
class BaseApplication : MultiDexApplication() {
open class BaseApplication : MultiDexApplication() {
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
/**
* @Author: QuYunShuo
* @Time: 2020/8/27
* @Class: BaseRepository
* @Remark: 仓库层 Repository 基类
* 仓库层 Repository 基类
*
* @author Qu Yunshuo
* @since 8/27/20
*/
open class BaseRepository {

View File

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

View File

@ -5,7 +5,6 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.launcher.ARouter
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
/**
* @Author: QuYunShuo
* @Time: 2020/8/27
* @Class: BaseFrameFragment
* @Remark: Fragment基类 与项目无关
* Fragment基类
*
* @author Qu Yunshuo
* @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) {
BindingReflex.reflexViewBinding(javaClass, layoutInflater)
}
protected val mViewModel: VM by lazy(mode = LazyThreadSafetyMode.NONE) {
BindingReflex.reflexViewModel(javaClass, this)
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,

View File

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

View File

@ -12,10 +12,10 @@ import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusRegister
import com.quyunshuo.androidbaseframemvvm.base.utils.EventBusUtils
/**
* @Author: QuYunShuo
* @Time: 2020/9/10
* @Class: BaseFrameNotMVVMFragment
* @Remark: 不使用 MVVM 的 Fragment 基类
* 不使用 MVVM 的 Fragment 基类
*
* @author Qu Yunshuo
* @since 9/10/20
*/
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
/**
* @Author: QuYunShuo
* @Time: 2020/10/13
* @Class: FrameNotMVVMView
* @Remark: View层基类抽象
* View层基类抽象
*
* @author Qu Yunshuo
* @since 10/13/20
*/
interface FrameNotMVVMView<VB : ViewBinding> {
/**

View File

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

View File

@ -2,23 +2,18 @@ package com.quyunshuo.androidbaseframemvvm.base.mvvm.vm
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.quyunshuo.androidbaseframemvvm.base.mvvm.m.BaseRepository
/**
* @Author: QuYunShuo
* @Time: 2020/8/27
* @Class: BaseViewModel
* @Remark: ViewModel 基类
* ViewModel 基类
*
* @author Qu Yunshuo
* @since 8/27/20
*/
abstract class BaseViewModel<R : BaseRepository> : ViewModel() {
abstract class BaseViewModel : ViewModel() {
// Loading 状态
val isLoading = MutableLiveData(false)
// 请求异常
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.READ_PHONE_STATE" />
<application android:name="com.quyunshuo.androidbaseframemvvm.base.app.BaseApplication">
<application>
<!-- 屏幕适配基准DP -->
<meta-data

View File

@ -1,13 +1,12 @@
package com.quyunshuo.androidbaseframemvvm.common.ui
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameActivity
/**
* @Author: QuYunShuo
* @Time: 2020/8/27
* @Class: BaseActivity
* @Remark: 项目相关的Activity基类
* Activity基类
*
* @author Qu Yunshuo
* @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
import androidx.lifecycle.ViewModel
import androidx.viewbinding.ViewBinding
import com.quyunshuo.androidbaseframemvvm.base.mvvm.v.BaseFrameFragment
/**
* @Author: QuYunShuo
* @Time: 2020/8/27
* @Class: BaseFragment
* @Remark: 项目相关的Fragment基类
* Fragment基类
*
* @author Qu Yunshuo
* @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
/**
* @Author: QuYunShuo
* @Time: 2020/9/10
* @Class: BaseNotMVVMActivity
* @Remark: 不是 MVVM 模式的基类
* 不是 MVVM 模式的基类
*
* @author Qu Yunshuo
* @since 9/10/20
*/
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
/**
* @Author: QuYunShuo
* @Time: 2020/9/10
* @Class: BaseNotMVVMFragment
* @Remark: 不是 MVVM 模式的基类
* 不是 MVVM 模式的基类
*
* @author Qu Yunshuo
* @since 9/10/20
*/
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",
":lib_base",
":lib_common",
":lib_net"
":lib_net",
":module_home"
)