标签: android-architecture

MVVM中的MediatorLiveData和MutableLiveData有什么区别

我搜索了很多但没有找到问题的清晰答案:

  1. MediatorLiveData和MutableLiveData有什么区别?

  2. 使用其中任何一种的合适条件是什么.

android android-livedata android-architecture

51
推荐指数
4
解决办法
1万
查看次数

在新的Android推荐架构中,BoundService + LiveData + ViewModel最佳实践

我一直在努力思考将Android服务放在新的Android推荐架构中的位置.我提出了许多可能的解决方案,但我无法决定哪一个是最好的方法.

我做了很多研究,我找不到任何有用的指导方针或教程.我发现关于将服务放置在我的应用程序架构中的唯一提示是@JoseAlcerreca Medium post

理想情况下,ViewModels不应该对Android有任何了解.这提高了可测试性,泄漏安全性和模块化.一般的经验法则是确保ViewModel中没有android.*导入(例如android.arch.*).这同样适用于演示者.

根据这一点,我应该将我的Android服务置于我的架构组件层次结构的顶层,与我的活动和碎片处于同一级别.这是因为Android服务是Android框架的一部分,所以ViewModels不应该知道它们.

现在,我将简要介绍一下我的场景,但只是为了让全景更清晰,而不是因为我想要这个特定场景的答案.

  • 我有一个Android应用程序,其中包含MainActivity,其中包含许多片段,所有这些片段都绑定在BottomNavBar中.
  • 我有一个绑定到myActivity的蓝牙服务及其中一个片段(因为我希望服务与Activty具有相同的生命周期,但我也希望直接从我的片段与它进行交互).
  • 该片段与BluetoothService交互以获取两种类型的信息:
    • 有关蓝牙连接状态的信息.不需要坚持.
    • 来自蓝牙设备的数据(在这种情况下,它是比例,因此重量和身体构成).需要坚持下去.

以下是我能想到的3种不同架构:

AndroidService中的LiveData Android服务范围内的LiveData

  • 具有连接状态和来自蓝牙设备的重量测量值的LiveData位于BluetoothService内.
  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • Fragment观察LiveData有关连接的状态并相应地调整UI(例如,如果状态已连接,则启用按钮).
  • Fragment观察新重量测量的LiveData.如果新的权重测量来自BluetoothDevice,则Fragment会告诉自己的ViewModel保存新数据.它通过Repository类完成.

片段和AndroidService之间共享ViewModel 共享ViewModel arch

  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • BluetoothService更新共享ViewModel中的蓝牙相关LiveData.
  • Fragment在自己的ViewModel中观察LiveData.

服务ViewModel 服务ViewMOdel拱门

  • Fragment可以触发BluetoothService中的操作(例如scanDevices)
  • BluetoothService在其自己的ViewModel中更新蓝牙相关的LiveData.
  • Fragment在自己的ViewModel和BluetoothService ViewModel中观察LiveData.

我很确定我应该将它们放在架构之上并将它们视为一个Activity/Fragment,因为BoundServices是Android Framework的一部分,它们由Android操作系统管理,并且它们与其他活动和片段绑定.在这种情况下,我不知道与LiveData,ViewModels和Activities/Fragments交互的最佳方式是什么.

有些人可能认为它们应该被视为一个数据源(因为在我的情况下,它使用蓝牙从一个规模获取数据),但我不认为这是一个好主意,因为我在上一段中所说的都是特别是因为它在这里所说的:

避免将应用的入口点(如活动, 服务和广播接收器)指定为数据源.相反,它们应该只与其他组件协调以检索与该入口点相关的数据子集.每个应用程序组件都是相当短暂的,具体取决于用户与其设备的交互以及系统的整体当前运行状况.

所以,最后,我的问题是:

我们应该在哪里放置我们的Android(绑定)服务以及它们与其他架构组件的关系?这些替代品中的任何一种都是好方法吗?

android android-service android-architecture android-architecture-components android-jetpack

28
推荐指数
1
解决办法
3284
查看次数

Androidx和数据绑定

我正在将Android P测试的依赖项迁移到androidx依赖项.由于一些不太清楚的原因,我的项目不再编译(并且我不会提供细节以避免明显的问题).我发现(通过gradlew dependencies)数据绑定使用"oldschool"依赖android.arch.lifecycle:runtime:1.0.3而不是androidx.lifecycle:lifecycle-runtime:2.0.0-beta01.我想这可能是一个原因.

知道如何强制使用新的包名/依赖项吗?

android android-support-library android-databinding android-architecture androidx

12
推荐指数
3
解决办法
9327
查看次数

在 MVVM Android 中使用共享首选项的最佳实践?

我一直在寻找在 Android 的 MVVM 架构中使用共享首选项的最佳方法,但我只能找到一些片段,因此没有清晰的图像来以最佳方式做到这一点。因此我有几个问题:

  1. 我应该在应用程序上保留 SharedPrefs 的单例实例吗?
  2. ViewModel 和 Repository 应该使用共享首选项吗?
  3. 在哪里使用它们?假设有一个 Fragment、一个 ViewModel 和一个存储库。我应该从 ViewModel 中控制 Fragment 和 Repository 的 SharedPrefs 还是每个人都应该单独处理?例如,用户单击按钮来保存设置。从片段保存到 SP 中?从 ViewModel 调用方法以保存在 SP 中?或者进一步重定向到 Reposioty 以使用 SP?

(*SP = 共享首选项)

我真的很高兴获得一些有关 MVVM Android 中 SharePreferences 最佳实践的建议

android mvvm sharedpreferences android-architecture

9
推荐指数
1
解决办法
4203
查看次数

如何在模块化Android应用程序中共享依赖项

我有一个以模块化方式构建的Android项目.我按照干净的架构,通过在多个Gradle模块之间划分源代码来模块化项目.

这是App的结构.

在此输入图像描述

此层次结构中的顶层模块App是其他模块所不依赖的模块,是应用程序的主要模块.下级模块domaindata不依赖于上App模块,其中所述App模块包括datadomain模块.我在app模块的build.gradle中添加了以下代码

    implementation project(':domain')
    api project(':data')
Run Code Online (Sandbox Code Playgroud)

现在,我在维护每个模块的依赖关系时遇到了一些问题.由于它们中的每一个都是一个单独的android模块,因此每个模块都有自己的模块build.gradle.该App模块可以使用datadomain模块中的类.但是,我有一些通用的类,(例如一些注释,实用程序,广播类,Dagger范围等),我想在所有模块中使用它们.但这些是我面临的问题

  • 由于这些类都包含在主模块中app,我不能在我访问这些datadomain,因为这些模块不依赖于更高层app
  • 我在所有层中使用的任何库(例如:RxJava)都需要包含在build.gradle每个模块中

作为解决方案,我想添加一个更多的android模块,比如common哪个将包含我所有的通用类以及我在所有模块中使用的库.

我的所有其它模块app,domain以及data将具有该模块作为一个依赖.

implementation project(':common')
Run Code Online (Sandbox Code Playgroud)

因此,任何全局库和类都将添加到此模块中,并且每个单独的模块将只具有特定于模块的类.

这是一个好方法吗?或者有没有办法有效地解决这个问题?

java android android-gradle-plugin clean-architecture android-architecture

8
推荐指数
1
解决办法
677
查看次数

使用导航架构组件实现时如何在选项卡布局的选项卡中添加向左或向右滑动

在 TabLayout 的 Tabs 中实现滑动的一种方法是使用 viewpager。使用导航架构组件进行导航尚不清楚如何使用viewpager。如果我们不使用 viewpager,那么在 TabLayout 的选项卡中实现向左或向右滑动的推荐方法是什么。

android android-architecture android-architecture-components android-jetpack android-architecture-navigation

7
推荐指数
0
解决办法
913
查看次数

android viewmodels之间的相互通信

我有一个客户详细信息页面,它从“客户”表加载客户详细信息,并允许对某些详细信息进行一些编辑,其中一个是客户的位置。客户的位置是从“位置”表加载下拉项目的微调器。

所以我目前的实现是我有一个 CustomerActivity,它有一个 CustomerViewModel 和 LocationViewModel

public class CustomerActivity extends AppCompatActivity {
    ...
   onCreate(@Nullable Bundle savedInstanceState) {
      ...
      customerViewModel.getCustomer(customerId).observe(this, new Observer<Customer>() {
         @Override
        public void onChanged(@Nullable Customer customer) {
            // bind to view via databinding
        }
      });

      locationViewModel.getLocations().observe(this, new Observer<Location>() {
         @Override
        public void onChanged(@Nullable List<Location> locations) {
           locationSpinnerAdapter.setLocations(locations);
        }
      });
   }
}
Run Code Online (Sandbox Code Playgroud)

我的问题是如何使用“客户”表中的值设置位置微调器,因为两个视图模型执行顺序的 onChanged 可能不同(有时客户加载速度更快,而其他位置加载速度更快)。

我考虑过仅在客户加载后加载位置,但是无论如何我可以在使用“客户”表中的值填充客户的位置微调器时同时加载两者?

android mvvm android-architecture

6
推荐指数
1
解决办法
3177
查看次数

已定义依赖功能,但未设置包ID.您可能缺少基本功能中的功能依赖项

我正在关注其中一个用于制作即时应用的Google Codelabs.

我正在尝试创建topeka-ui(即时应用程序的UI功能模块).

当我尝试运行其中一个即时应用程序模块时,它说:

已定义依赖功能,但未设置包ID.您可能缺少基本功能中的功能依赖项.

android android-instant-apps android-architecture

5
推荐指数
5
解决办法
2742
查看次数

使用两个(或多个)片段在单个活动上实现MVP

我正在开发一个显示列表的小应用程序,当单击某个项目时,它会打开一个包含项目详细信息的辅助屏幕.我想实现MVP作为我的应用程序的架构,当我有一个包含2个片段的单个活动时,我一直在努力弄清楚如何做到这一点.

有些问题出现了,当点击列表中的项目时,会向第一个演示者发送回调,但此时,谁负责打开第二个片段?让主持人"互相交谈"?我应该通过活动吗?

一直在寻找具有实现MVP的多个片段的单个活动的示例,但是还找不到类似的东西.

(是的,它可以以其他方式完成,但应用程序的目的是学习在具有多个片段的单个活动上实施MVP)

感谢任何帮助!谢谢!

android android-fragments android-mvp android-architecture

5
推荐指数
1
解决办法
1806
查看次数

将数据从一个ViewModel传递到另一个Android MVVM

你们有一个与设计有关的问题。

因此,我一直在遵循Google编写的《应用程序架构指南》,使用Kotlin,MVVM和数据绑定来构建我的应用程序。我正在使用Google规定的Jetpack组件(导航,实时数据等)。

问题是,在开发过程中,很多时候我需要将数据从一个片段传输到另一个片段。之前,我曾经创建片段的实例并添加复杂数据,然后移至片段,如下所示:

class Frag1: Fragment(){

    ...
    fun openFrag2(){
        val frg2 = frag2.newInstance(complexDataObj)
        childFragmentManager.addFragment(frg2,TAG)
    }
}

class Frag2: Fragment(){
    var cd: ComplexDataClass = null
    companion object{
    fun newInstance(complexData: ComplexDataClass): Fragment{
        val frag = ActivityFragment()
        frag.cd = complexData
        return frag
    }
    ....
}
Run Code Online (Sandbox Code Playgroud)

导航目的地之间传递数据应该是像这样或以使用共享视图模型也被同一文档中提到。>>

通常,强烈建议您仅在目标之间传递最少的数据量。例如,您应该传递键来检索对象,而不要传递对象本身,因为所有保存状态的总空间在Android上受到限制。如果您需要传递大量数据,请考虑使用在片段之间共享数据中所述的ViewModel。

这可行。

我的问题是,使用体系结构的主要原因之一是关注点分离。这样我们就可以编写干净且可维护的代码。根据我的理解,sharedviewmodel的这种用法无法达到目的,因为这会导致大型ViewModel类。

我将尝试使用非常常见的情况来解释问题。

我有一个带有数据列表的片段。列表中的每个项目都对应一个用户。当我们点击一​​个项目时,它将移至用户详细信息屏幕,如果我们点击编辑按钮,则应移至可编辑详细信息的编辑屏幕。

             View User Frag
             ____                 ____________
            |    |               |            |
 List Frag  |    |               |            |
 ______     |____|               |            |
|______| /
|______|/ …
Run Code Online (Sandbox Code Playgroud)

android mvvm android-architecture android-jetpack android-jetpack-navigation

5
推荐指数
1
解决办法
98
查看次数