当前位置: 首页 > news >正文

Android开发常用外部组件及使用指南(下)

在这里插入图片描述

文章目录

    • 八、响应式编程组件
      • 1. RxJava
        • 1.1 引入依赖
        • 1.2 基本使用
      • 2. Kotlin协程与Flow
        • 2.1 基本使用
    • 九、测试组件
      • 1. JUnit
        • 1.1 基本使用
      • 2. Mockito
        • 2.1 引入依赖
        • 2.2 基本使用
      • 3. Espresso
        • 3.1 引入依赖
        • 3.2 基本使用
    • 十、性能优化组件
      • 1. LeakCanary
        • 1.1 引入依赖
        • 1.2 基本使用
      • 2. Chucker
        • 2.1 引入依赖
        • 2.2 基本使用
    • 十一、安全组件
      • 1. EncryptedSharedPreferences
        • 1.1 引入依赖
        • 1.2 基本使用
      • 2. SQLCipher
        • 2.1 引入依赖
        • 2.2 基本使用
    • 十二、其他实用组件
      • 1. Timber
        • 1.1 引入依赖
        • 1.2 基本使用
      • 2. WorkManager
        • 2.1 引入依赖
        • 2.2 基本使用
    • 十三、组件化架构
      • 1. 模块化设计
      • 2. 模块间通信
        • 2.1 接口暴露
        • 2.2 使用路由框架
          • ARouter引入
          • ARouter使用
    • 十四、Jetpack组件
      • 1. ViewModel
        • 1.1 基本使用
      • 2. LiveData
        • 2.1 基本使用
      • 3. DataBinding
        • 3.1 启用DataBinding
        • 3.2 基本使用
      • 4. Navigation
        • 4.1 引入依赖
        • 4.2 基本使用
    • 十五、跨平台开发框架
      • 1. Flutter模块集成
        • 1.1 添加Flutter模块
        • 1.2 配置settings.gradle
        • 1.3 添加依赖
        • 1.4 使用FlutterFragment
      • 2. KMM (Kotlin Multiplatform Mobile)
        • 2.1 项目结构
        • 2.2 共享模块build.gradle
        • 2.3 共享代码示例

在这里插入图片描述

八、响应式编程组件

1. RxJava

RxJava是一个基于观察者模式的异步编程库。

1.1 引入依赖
implementation "io.reactivex.rxjava3:rxjava:3.1.3"
implementation "io.reactivex.rxjava3:rxandroid:3.0.0"
implementation "com.squareup.retrofit2:adapter-rxjava3:2.9.0"
1.2 基本使用
// 创建Observable
val observable = Observable.create<String> { emitter ->emitter.onNext("Hello")emitter.onNext("World")emitter.onComplete()
}// 操作符链式调用
observable.map { it.length }.filter { it > 3 }.subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({ length -> println("Length: $length") },{ error -> println("Error: $error") },{ println("Completed") })// 与Retrofit结合
interface ApiService {@GET("users")fun getUsers(): Observable<List<User>>
}apiService.getUsers().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe({ users ->// 处理用户列表}, { error ->// 处理错误})

2. Kotlin协程与Flow

Kotlin协程是官方推荐的异步解决方案,Flow是响应式流实现。

2.1 基本使用
// 协程作用域
lifecycleScope.launch {val result = withContext(Dispatchers.IO) {// IO操作"Result"}// 更新UItextView.text = result
}// Flow基本使用
fun getNumbers(): Flow<Int> = flow {for (i in 1..10) {delay(100)emit(i)}
}lifecycleScope.launch {getNumbers().filter { it % 2 == 0 }.map { it * it }.collect { number ->println(number)}
}// 与Room结合
@Dao
interface UserDao {@Query("SELECT * FROM users")fun getUsers(): Flow<List<User>>
}viewModelScope.launch {userDao.getUsers().collect { users ->// 自动接收数据库变化}
}

九、测试组件

1. JUnit

Java单元测试框架,Android开发的基础测试工具。

1.1 基本使用
class ExampleUnitTest {@Testfun addition_isCorrect() {assertEquals(4, 2 + 2)}@Testfun `test user creation`() {val user = User(1, "John", 30)assertThat(user.name, `is`("John"))assertThat(user.age, greaterThan(20))}
}

2. Mockito

Mock框架,用于创建测试替身。

2.1 引入依赖
testImplementation "org.mockito:mockito-core:4.3.1"
testImplementation "org.mockito.kotlin:mockito-kotlin:4.0.0"
2.2 基本使用
class UserServiceTest {@Testfun `should return user by id`() {// 创建mockval userRepository = mock<UserRepository>()// 设置mock行为whenever(userRepository.getUser(1)).thenReturn(User(1, "John", 30))// 创建被测试对象val userService = UserService(userRepository)// 执行测试val user = userService.getUser(1)// 验证结果assertEquals("John", user.name)verify(userRepository).getUser(1)}
}

3. Espresso

UI测试框架,用于模拟用户操作。

3.1 引入依赖
androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0"
androidTestImplementation "androidx.test:runner:1.4.0"
androidTestImplementation "androidx.test:rules:1.4.0"
3.2 基本使用
@RunWith(AndroidJUnit4::class)
class MainActivityTest {@get:Ruleval activityRule = ActivityScenarioRule(MainActivity::class.java)@Testfun testLoginButton() {// 输入文本onView(withId(R.id.username)).perform(typeText("user"), closeSoftKeyboard())onView(withId(R.id.password)).perform(typeText("pass"), closeSoftKeyboard())// 点击按钮onView(withId(R.id.login)).perform(click())// 验证结果onView(withId(R.id.result)).check(matches(withText("Login successful")))}
}

十、性能优化组件

1. LeakCanary

内存泄漏检测工具。

1.1 引入依赖
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.8.1'
1.2 基本使用
// 无需初始化代码,自动工作
// 当检测到内存泄漏时,会显示通知

2. Chucker

网络请求监控工具。

2.1 引入依赖
debugImplementation "com.github.chuckerteam.chucker:library:3.5.2"
releaseImplementation "com.github.chuckerteam.chucker:library-no-op:3.5.2"
2.2 基本使用
val client = OkHttpClient.Builder().addInterceptor(ChuckerInterceptor(context)).build()

十一、安全组件

1. EncryptedSharedPreferences

加密的SharedPreferences实现。

1.1 引入依赖
implementation "androidx.security:security-crypto:1.1.0-alpha03"
1.2 基本使用
val masterKey = MasterKey.Builder(context).setKeyScheme(MasterKey.KeyScheme.AES256_GCM).build()val sharedPreferences = EncryptedSharedPreferences.create(context,"secret_shared_prefs",masterKey,EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)with(sharedPreferences.edit()) {putString("api_key", "secret-api-key")apply()
}val apiKey = sharedPreferences.getString("api_key", null)

2. SQLCipher

SQLite数据库加密解决方案。

2.1 引入依赖
implementation 'net.zetetic:android-database-sqlcipher:4.5.0'
2.2 基本使用
val factory = SupportFactory("database-password".toByteArray())
val database = SQLiteDatabase.openOrCreateDatabase(context.getDatabasePath("encrypted.db"),"database-password",null,factory
)// 或者与Room一起使用
Room.databaseBuilder(context, AppDatabase::class.java, "encrypted.db").openHelperFactory(factory).build()

十二、其他实用组件

1. Timber

日志工具,比Android原生Log更强大。

1.1 引入依赖
implementation 'com.jakewharton.timber:timber:5.0.1'
1.2 基本使用
// Application中初始化
if (BuildConfig.DEBUG) {Timber.plant(Timber.DebugTree())
}// 使用
Timber.d("Debug message")
Timber.i("User %s logged in", userName)
Timber.e(exception, "Error while fetching data")

2. WorkManager

后台任务调度库。

2.1 引入依赖
implementation "androidx.work:work-runtime-ktx:2.7.1"
2.2 基本使用
// 定义Worker
class UploadWorker(appContext: Context, workerParams: WorkerParameters) : CoroutineWorker(appContext, workerParams) {override suspend fun doWork(): Result {val data = inputData.getString("data_key")// 执行上传操作return Result.success()}
}// 调度工作
val uploadWorkRequest = OneTimeWorkRequestBuilder<UploadWorker>().setInputData(workDataOf("data_key" to "value")).setConstraints(Constraints.Builder().setRequiredNetworkType(NetworkType.CONNECTED).build()).build()WorkManager.getInstance(context).enqueue(uploadWorkRequest)// 观察工作状态
WorkManager.getInstance(context).getWorkInfoByIdLiveData(uploadWorkRequest.id).observe(this) { workInfo ->when (workInfo?.state) {WorkInfo.State.SUCCEEDED -> { /* 处理成功 */ }WorkInfo.State.FAILED -> { /* 处理失败 */ }else -> { /* 其他状态 */ }}}

十三、组件化架构

1. 模块化设计

大型项目通常采用模块化设计,常见模块划分:

  • app: 主模块,包含应用入口
  • core: 核心模块,包含基础功能
  • feature-xxx: 功能模块,按功能划分
  • data: 数据模块,包含数据源和仓库
  • domain: 领域模块,包含业务逻辑

2. 模块间通信

2.1 接口暴露
// 在core模块定义接口
interface UserService {fun getUser(id: Int): User
}// 在data模块实现
class UserServiceImpl @Inject constructor(private val userRepository: UserRepository
) : UserService {override fun getUser(id: Int): User {return userRepository.getUser(id)}
}// 在feature模块使用
class UserViewModel @Inject constructor(private val userService: UserService
) : ViewModel()
2.2 使用路由框架

如ARouter或Navigation组件。

ARouter引入
// 模块级build.gradle
kapt {arguments {arg("AROUTER_MODULE_NAME", project.getName())}
}dependencies {implementation 'com.alibaba:arouter-api:1.5.2'kapt 'com.alibaba:arouter-compiler:1.5.2'
}
ARouter使用
// 1. 初始化
ARouter.init(application)// 2. 定义路由路径
@Route(path = "/user/detail")
class UserDetailActivity : AppCompatActivity()// 3. 跳转
ARouter.getInstance().build("/user/detail").withInt("id", 123).navigation()// 4. 服务发现
val userService = ARouter.getInstance().build("/service/user").navigation() as UserService

十四、Jetpack组件

1. ViewModel

管理界面相关数据,生命周期感知。

1.1 基本使用
class MyViewModel : ViewModel() {private val _data = MutableLiveData<String>()val data: LiveData<String> = _datafun loadData() {viewModelScope.launch {val result = repository.fetchData()_data.value = result}}
}// Activity/Fragment中
private val viewModel by viewModels<MyViewModel>()override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)viewModel.data.observe(this) { data ->// 更新UI}viewModel.loadData()
}

2. LiveData

生命周期感知的数据持有者。

2.1 基本使用
val currentUser: LiveData<User> = userRepository.getUser()// 观察
currentUser.observe(this) { user ->// 更新UI
}// 转换
val userName = Transformations.map(currentUser) { user ->user.name
}// 合并
val userAndPosts = MediatorLiveData<Pair<User, List<Post>>>().apply {addSource(currentUser) { user ->value = user to (value?.second ?: emptyList())}addSource(posts) { posts ->value = (value?.first ?: User()) to posts}
}

3. DataBinding

声明式地将布局与数据绑定。

3.1 启用DataBinding
android {buildFeatures {dataBinding true}
}
3.2 基本使用
<!-- 布局文件 -->
<layout xmlns:android="http://schemas.android.com/apk/res/android"><data><variable name="user" type="com.example.User"/><variable name="viewModel" type="com.example.MyViewModel"/></data><LinearLayout><TextViewandroid:text="@{user.name}"android:onClick="@{() -> viewModel.onUserClick()}"/></LinearLayout>
</layout>
// Activity中
val binding: ActivityMainBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)binding.user = user
binding.viewModel = viewModel
binding.lifecycleOwner = this

4. Navigation

简化Fragment导航。

4.1 引入依赖
implementation "androidx.navigation:navigation-fragment-ktx:2.3.5"
implementation "androidx.navigation:navigation-ui-ktx:2.3.5"
4.2 基本使用
<!-- nav_graph.xml -->
<navigation xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"app:startDestination="@id/homeFragment"><fragmentandroid:id="@+id/homeFragment"android:name="com.example.HomeFragment"><actionandroid:id="@+id/action_home_to_detail"app:destination="@id/detailFragment"/></fragment><fragmentandroid:id="@+id/detailFragment"android:name="com.example.DetailFragment"><argumentandroid:name="itemId"app:argType="integer"/></fragment>
</navigation>
// 导航到详情页
findNavController().navigate(R.id.action_home_to_detail,bundleOf("itemId" to 123)
)// 接收参数
val args by navArgs<DetailFragmentArgs>()
val itemId = args.itemId

十五、跨平台开发框架

1. Flutter模块集成

在现有Android应用中集成Flutter模块。

1.1 添加Flutter模块
# 在Android项目同级目录
flutter create -t module --org com.example my_flutter_module
1.2 配置settings.gradle
include ':app'
setBinding(new Binding([gradle: this]))
evaluate(new File(settingsDir.parentFile,'my_flutter_module/.android/include_flutter.groovy'
))
1.3 添加依赖
dependencies {implementation project(':flutter')
}
1.4 使用FlutterFragment
val flutterFragment = FlutterFragment.createDefault()
supportFragmentManager.beginTransaction().add(R.id.fragment_container, flutterFragment).commit()

2. KMM (Kotlin Multiplatform Mobile)

使用Kotlin开发跨平台共享代码。

2.1 项目结构
project/
├── androidApp/      # Android应用模块
├── iosApp/         # iOS应用模块
└── shared/         # 共享代码模块
2.2 共享模块build.gradle
plugins {id 'org.jetbrains.kotlin.multiplatform'
}kotlin {android()ios()sourceSets {commonMain {dependencies {implementation kotlin('stdlib-common')// 其他通用依赖}}androidMain {dependencies {implementation kotlin('stdlib')// Android特定依赖}}iosMain {// iOS特定依赖}}
}
2.3 共享代码示例
// shared/src/commonMain/kotlin/Platform.kt
expect class Platform() {val platform: String
}// shared/src/androidMain/kotlin/Platform.kt
actual class Platform actual constructor() {actual val platform: String = "Android ${android.os.Build.VERSION.SDK_INT}"
}// shared/src/iosMain/kotlin/Platform.kt
actual class Platform actual constructor() {actual val platform: String = UIDevice.currentDevice.systemName() + " " + UIDevice.currentDevice.systemVersion
}

相关文章:

  • 【自我介绍前端界面分享】附源码
  • java后端开发day35--集合进阶(四)--双列集合:MapHashMapTreeMap
  • 深入剖析PHP反弹Shell:OSCP场景下的实现、原理与优化
  • sql 根据时间范围获取每日,每月,年月的模版数据
  • MOS管驱动电路以及阻值选取
  • rl中,GRPO损失函数详解。
  • VulnHub-DarkHole_2靶机渗透教程
  • DCAN,ECAN和MCAN的区别
  • 基于SpringBoot的校园二手商品在线交易系统+含项目运行说明文档
  • UniGoal 具身导航 | 通用零样本目标导航 CVPR 2025
  • ABP-Book Store Application中文讲解 - Part 0:开发环境搭建
  • 创建第一个Spring Boot项目
  • 文案提取有错别字怎么办?
  • QT之Q_PROPERTY介绍以及在QWidget中的用法
  • 武汉昊衡科技OLI光纤微裂纹检测仪:高密度光器件的精准守护者
  • 基于Python爬虫的豆瓣电影信息爬取(可以根据选择电影编号得到需要的电影信息)
  • GPLT-2025年第十届团体程序设计天梯赛总决赛题解(2025天梯赛题解,共计266分)
  • -PHP 反序列化POP 链构造魔术方法流程漏洞触发条件属性修改
  • Linux 管道理解
  • cf | Common Multiple
  • 印度加大应对力度,吊销所有巴基斯坦公民签证
  • 重庆一幼儿园回应招聘硕士幼教:统一标准,江北区学前教育岗的硬性要求
  • 格力电器:选举董明珠为公司第十三届董事会董事长
  • 湘江半程马拉松赛女配速员“跑崩”,晕倒在终点?组委会回应
  • 全球首个AI价值观数据集出炉
  • 新质生产力的宜昌解法:抢滩“高智绿”新赛道,化工产品一克卖数千元