讲师中心 微信公众号
AI工具推荐 视频效率加速

如何在子 Activity 中正确复用并扩展 ViewModel 功能

星敏小哥_1572

星敏小哥_1572

发布时间:2026-07-21 17:56:25

|

804人浏览过

|

来源于php中文网

原创

如何在子 Activity 中正确复用并扩展 ViewModel 功能

本文介绍一种面向抽象、可扩展的 viewmodel 使用模式:通过定义抽象基类 viewmodel 和泛型 baseactivity,使子 activity 能安全复用公共逻辑,同时独立实现差异化业务(如调用不同 retrofit 接口),避免代码重复与紧耦合。

本文介绍一种面向抽象、可扩展的 viewmodel 使用模式:通过定义抽象基类 viewmodel 和泛型 baseactivity,使子 activity 能安全复用公共逻辑,同时独立实现差异化业务(如调用不同 retrofit 接口),避免代码重复与紧耦合。

在 Android 架构实践中,当多个 Activity 共享基础功能(如文档列表加载、状态观察、错误处理)但需调用不同后端接口时,直接继承 QueueViewModel 并重写方法往往导致职责混乱或破坏单一职责原则。更合理的方式是分离契约与实现:定义清晰的抽象层,让每个具体 Activity 持有专属 ViewModel 实例,同时复用底层 Repository、生命周期感知机制和 UI 状态管理逻辑。

✅ 推荐方案:抽象 ViewModel + 泛型 BaseActivity

首先,定义统一的行为契约:

// 抽象 ViewModel 基类 —— 仅声明能力,不包含具体实现
abstract class BaseActivityViewModel : ViewModel() {
    abstract fun loadDocuments(search: String = "")
    abstract val documents: LiveData<List<Models.QueueDoc>>
}

接着,重构 BaseActivity 为泛型基类,支持类型安全的 ViewModel 获取:

public abstract class BaseActivity<VM extends BaseActivityViewModel> extends AppCompatActivity {
    private Class<VM> viewModelClass;

    @SuppressWarnings("unchecked")
    public BaseActivity() {
        this.viewModelClass = (Class<VM>) ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
    }

    protected ViewModelProvider.Factory getViewModelFactory() {
        return null; // 子类可选择性提供自定义 Factory
    }

    protected final VM viewModel;

    {
        ViewModelProvider provider = new ViewModelProvider(this, getViewModelFactory());
        this.viewModel = provider.get(viewModelClass);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 自动观察 documents,子类无需重复编写
        viewModel.documents.observe(this, docs -> showDocuments(docs));
    }

    protected abstract void showDocuments(List<Models.QueueDoc> docs);
}

然后,为不同业务场景创建具体 ViewModel:

class QueueViewModel(private val repository: QueueRepository) : BaseActivityViewModel() {
    private val _documents = MutableLiveData<List<Models.QueueDoc>>()
    override val documents: LiveData<List<Models.QueueDoc>> = _documents

    override fun loadDocuments(search: String) {
        repository.loadDocuments(documentTypes, search)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { _documents.value = it },
                { handleError(it) }
            )
    }
}

class AnotherQueueViewModel(private val repository: QueueRepository) : BaseActivityViewModel() {
    private val _documents = MutableLiveData<List<Models.QueueDoc>>()
    override val documents: LiveData<List<Models.QueueDoc>> = _documents

    override fun loadDocuments(search: String) {
        repository.loadAnotherDocuments(documentTypes, search) // 调用另一接口
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { _documents.value = it },
                { handleError(it) }
            )
    }
}

对应地,子 Activity 只需指定泛型并实现 UI 回调:

class MainQueueActivity : BaseActivity<QueueViewModel>() {
    override fun getViewModelFactory(): ViewModelProvider.Factory {
        return QueueViewModelFactory(documentTypes)
    }

    override fun showDocuments(docs: List<Models.QueueDoc>) {
        // 更新 RecyclerView 或其他 UI 组件
    }
}

class AnotherQueueActivity : BaseActivity<AnotherQueueViewModel>() {
    override fun getViewModelFactory(): ViewModelProvider.Factory {
        return AnotherQueueViewModelFactory(documentTypes)
    }

    override fun showDocuments(docs: List<Models.QueueDoc>) {
        // 同样复用 showDocuments 逻辑,UI 层保持一致
    }
}

⚠️ 注意事项与最佳实践

  • 避免在 ViewModel 中持有 Activity/Context 引用:确保 QueueRepository 是无状态的,所有依赖(如 Retrofit Service)通过构造注入;
  • Factory 的必要性:若 ViewModel 需要参数(如 documentTypes),必须提供自定义 ViewModelProvider.Factory,否则 ViewModelProvider(this).get(...) 将抛出异常;
  • LiveData 复用安全:documents 在基类中统一观察,子类只需关注数据展示逻辑,避免重复订阅/解订阅;
  • 扩展性保障:未来新增第三种队列类型(如 listPendingDocQueue),只需新增一个 ViewModel 实现,完全不影响现有类;
  • 测试友好:每个 ViewModel 可独立单元测试,Mock Repository 即可验证业务逻辑。

该方案兼顾了 DRY 原则与开闭原则——基类封装不变逻辑,子类专注变化点,是 MVVM 架构下多 Activity 复用 ViewModel 的推荐实践。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

讯飞绘文

讯飞绘文是一款由科大讯飞推出的一站式 AIGC 内容运营平台。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

蛙蛙写作

一款AI论文写作工具,主要用于超级AI智能写作助手,适合需要提升相关任务效率的用户。

二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

相关专题

更多
android开发三大框架
android开发三大框架

android开发三大框架是XUtil框架、volley框架、ImageLoader框架。本专题为大家提供android开发三大框架相关的各种文章、以及下载和课程。

902

2023.08.14

android是什么系统
android是什么系统

Android是一种功能强大、灵活可定制、应用丰富、多任务处理能力强、兼容性好、网络连接能力强的操作系统。本专题为大家提供android相关的文章、下载、课程内容,供大家免费下载体验。

2587

2023.08.22

android权限限制怎么解开
android权限限制怎么解开

android权限限制可以使用Root权限、第三方权限管理应用程序、ADB命令和Xposed框架解开。详细介绍:1、Root权限,通过获取Root权限,用户可以解锁所有权限,并对系统进行自定义和修改;2、第三方权限管理应用程序,用户可以轻松地控制和管理应用程序的权限;3、ADB命令,用户可以在设备上执行各种操作,包括解锁权限;4、Xposed框架,用户可以在不修改系统文件的情况下修改应用程序的行为和权限。

4877

2023.09.19

android重启应用的方法有哪些
android重启应用的方法有哪些

android重启应用有通过Intent、PendingIntent、系统服务、Runtime等方法。本专题为大家提供Android相关的文章、下载、课程内容,供大家免费下载体验。

625

2023.10.18

Android语音播放功能实现方法
Android语音播放功能实现方法

实现方法有使用MediaPlayer实现、使用SoundPool实现两种。可以根据具体的需求选择适合的方法进行实现。想了解更多语音播放的相关内容,可以阅读本专题下面的文章。

944

2024.03.01

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

40

2026.10.08

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

140

2026.09.30

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

120

2026.09.30

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

100

2026.09.30

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn