标签: android-architecture-components

如何在后台线程上执行LiveData转换?

我需要将一个LiveData对象返回的一种数据转换为后台线程上的另一种形式,以防止UI滞后.

在我的具体案例中,我有:

  • MyDBRow对象(由原始longs和Strings 组成的POJO );
  • 一个房间 DAO实例通过一个发射这些LiveData<List<MyDBRow>>; 和
  • 一个UI期望更丰富的MyRichObject对象(PO​​JO与原语膨胀成例如日期/时间对象)

所以我需要将我LiveData<List<MyDBRow>>变成一个LiveData<List<MyRichObject>>,但不是在UI线程上.

Transformations.map(LiveData<X>, Function<X, Y>)方法需要转换,但我不能使用它,因为它在主线程上执行转换:

将主线程上的给定函数应用于sourceLiveData 发出的每个值,并返回生成结果值的LiveData.

给定的函数func将在主线程上执行.

什么是进行LiveData转换的简洁方法:

  1. 离主线程的某个地方,和
  2. 仅在需要时(即仅在某些事物正在观察预期的转变时)?

android android-thread android-room android-architecture-lifecycle android-architecture-components

13
推荐指数
3
解决办法
4455
查看次数

如何删除/删除PagedListAdapter项

目前我正在使用Android架构组件进行App开发一切都与分页库一起工作现在我想删除recyclerview项目使用PagedListAdapter来填充这个我们需要添加数据源并且从数据源列表正在使用LiveData更新我想要删除列表notifyItemRemoved()中的项目正在从PagedList工作我收到此异常:

java.lang.UnsupportedOperationException


java.util.AbstractList.remove(AbstractList.java:638)
Run Code Online (Sandbox Code Playgroud)

android android-recyclerview android-architecture-components

13
推荐指数
2
解决办法
6930
查看次数

如何使用Android的架构组件完成ViewModel的活动?

我试图弄清楚如何以最佳方式完成ViewModel中的Activity.我找到了使用LiveData对象并发出"信号"的一种方法.

我怀疑这个解决方案有一个开销.那么它是正确的解决方案还是我应该使用更准确?

所以举个例子:让我们假设在一个应用程序中是一个活动MainActivity和视图模型,如下所示:

 class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val model = ViewModelProviders.of(this).get(MainViewModel::class.java)

        model.shouldCloseLiveData.observe(this, Observer { finish() })

    }
 }
Run Code Online (Sandbox Code Playgroud)

并且作为MainActivity的伴侣是MainViewModel,如下所示:

class MainViewModel(app: Application) : AndroidViewModel(app) {

  val shouldCloseLiveData = MutableLiveData<Void>()

  fun someAction(){
    shouldCloseLiveData.postValue(null)
  }

}
Run Code Online (Sandbox Code Playgroud)

android android-architecture-components

13
推荐指数
1
解决办法
2766
查看次数

如何使用新的导航架构组件在导航中禁用某些片段?

我正在尝试新的导航架构组件,我无法弄清楚如何做到这一点:

我有1个活动(MainActivity)+ 3个碎片:

  • SplashFragment(主页)
  • MainFragment
  • SignUpFragment

我想使用SplashFragment来确定我是否应该导航到MainFragment或SignUpFragment,但是一旦它到达那两个中的任何一个,你就不应该回弹到SplashFragment.我怎么能用新的导航组件做到这一点?

popBackStack在调用之前和之后尝试过navigate(R.id.action_xxx),但是它们都没有工作(这有意义:在它没有任何东西可以弹出之前;它只是关闭刚刚添加的片段).这是否意味着唯一的方法是覆盖onBackPress拦截它并确保navigateUp在这些情况下不会调用?

谢谢!

android android-architecture-components

13
推荐指数
3
解决办法
6613
查看次数

使用架构组件进行多模块导航

所以我在我当前的应用程序中为我的模块设置了这个结构.

应用模块结构

我还没有找到任何有关多模块导航的官方文档,但我发现这篇文章的内容是关于这一点的,这里是我的gradle文件的方式:

特征1 - 细节

...
implementation project(":base")
implementation project(":feature-2-detail")
...
Run Code Online (Sandbox Code Playgroud)

特征2 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...
Run Code Online (Sandbox Code Playgroud)

特征3 - 细节

...
implementation project(":base")
implementation project(":feature-1-detail")
...
Run Code Online (Sandbox Code Playgroud)

这是我的导航图:

特征1 - 细节

<navigation ...
    android:id="@+id/graph_feature_1_id">
    <include app:graph="@navigation/graph_feature_2" />
    <fragment ...
        android:id="@+id/nav_feature_1">
        <action ...
            app:destination="@+id/graph_feature_2_id" />

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

特征2 - 细节

<navigation ...
    android:id="@+id/graph_feature_2_id">
    <include app:graph="@navigation/graph_feature_1" />
    <fragment ...
        android:id="@+id/nav_feature_2">
        <action ...
            app:destination="@+id/graph_feature_1_id" />

    </fragment>
</navigation>
Run Code Online (Sandbox Code Playgroud)

特征3 - 细节

<navigation ...
    android:id="@+id/graph_feature_3_id">
    <include app:graph="@navigation/graph_feature_1" />
    <fragment ...
        android:id="@+id/nav_feature_3"> …
Run Code Online (Sandbox Code Playgroud)

android android-architecture-components android-architecture-navigation

13
推荐指数
2
解决办法
2609
查看次数

测试LiveData转换?

我使用Android架构组件和反应式方法构建了一个启动画面.我从Preferences LiveData对象返回fun isFirstLaunchLD(): SharedPreferencesLiveData<Boolean>.我有ViewModel将LiveData传递给视图并更新首选项

val isFirstLaunch = Transformations.map(preferences.isFirstLaunchLD()) { isFirstLaunch ->
    if (isFirstLaunch) {
        preferences.isFirstLaunch = false
    }
    isFirstLaunch
}
Run Code Online (Sandbox Code Playgroud)

在我的片段中,我从ViewModel观察LiveData

    viewModel.isFirstLaunch.observe(this, Observer { isFirstLaunch ->
        if (isFirstLaunch) {
            animationView.playAnimation()
        } else {
            navigateNext()
        }
    })
Run Code Online (Sandbox Code Playgroud)

我想现在测试我的ViewModel,看看是否正确更新了isFirstLaunch.我该怎么测试呢?我是否正确分离了所有图层?你会对这个示例代码进行什么样的测试?

android android-testing android-livedata android-architecture-components android-jetpack

13
推荐指数
2
解决办法
711
查看次数

如何在Jetpack中使用导航启动第二个活动

你知道它现在是正式的:谷歌正式推荐单一活动应用程序架构.但这里有一种困难.我们有各种活动.所以,当我想用​​多个活动实现导航时,但我失败了.

他们说:如果多个活动共享相同的布局,则可以组合导航图,将导航调用替换为活动目标,以直接在两个导航图之间导航调用.在这里

所以我创造了这个:

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:startDestination="@+id/nav_graph_firstActvity">

<activity
    android:id="@+id/nav_graph_firstActvity"
    android:name="io.androidedu.FirstActivity"
    android:label="First Activity">

    <action
        android:id="@+id/nav_graph_actFirstActvity"
        app:destination="@id/nav_graph_secondActvity" />
</activity>

<activity
    android:id="@+id/nav_graph_secondActvity"
    android:name="io.androidedu.SecondActivity"
    android:label="Second Activity" />
Run Code Online (Sandbox Code Playgroud)

之后我在这里找不到任何多个活动的样本. 有一些样本:

Navigation.findNavController(view).navigate(R.id.nav_graph_actFirstActvity)
Run Code Online (Sandbox Code Playgroud)

但是findNavController()等待一个视图,而不是一个活动.

我怎么能解决这个问题呢?

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

12
推荐指数
1
解决办法
5953
查看次数

PagedListAdapter.submitList()在更新现有项目时表现得很奇怪

这个主题的小故事:应用程序只是在确认后用对话框更新点击行的值.在房间数据库上使用分页方案.

添加或删除项目时,将获取最新数据集并将其传递给submitList方法,然后可以看到所有更改并运行良好.

问题从那里开始,如果现有项目更新,则再次正确获取最新数据集并传递给submitList,但这次似乎没有变化.

当我调试DIFF_CALLBACK并抓住我的项目时areItemsTheSame,newHistoryoldHistory值是一样的!(怎么样!)

submitList方法中可能有任何错误?

  • 房间v.:2.1.0-alpha02
  • Paging v.:2.1.0-beta01

初始化后,observe从房间中提取列表并传递给mHistoryAdapter.submitList(it).然后,如果我更新一个项目,观察再次被触发(我在param中看到更新的值it)并传递给submitList.

不幸的是,适配器不会改变......

    mResolvedAddressViewModel = ViewModelProviders.of(this).get(ResolvedAddressViewModel::class.java)
    mResolvedAddressViewModel.getAddresses(false).observe(this, Observer {
        mHistoryAdapter.submitList(it)
    })
Run Code Online (Sandbox Code Playgroud)

所有部件

模型

@Parcelize
@Entity
data class ResolvedAddress(
    @PrimaryKey var id: String = UUID.randomUUID().toString(),
    var requestedLat: Double = 0.0,
    var requestedLon: Double = 0.0,
    var requestedAddress: String = "",
    var lat: Double,
    var lon: Double,
    var address: String,
    var country: String,
    var countryCode: String,
    var city: …
Run Code Online (Sandbox Code Playgroud)

android android-architecture-components android-paging androidx

12
推荐指数
1
解决办法
2252
查看次数

SetupWithNavController 不适用于工具栏

我正在尝试将工具栏绑定到导航控制器,为此我使用以下代码:

NavigationUI.setupWithNavController(toolbar, NavHostFragment.findNavController(nav_host))
Run Code Online (Sandbox Code Playgroud)

在菜单文件中,我提供了应用程序应导航到的片段的 ID,如下所示:

<item
    android:id="@+id/menuFragment"
    android:orderInCategory="100"
    android:title="@string/action_settings"
    app:showAsAction="never" />
Run Code Online (Sandbox Code Playgroud)

我有一个简单的导航图文件,如下所示:

<navigation 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:id="@+id/nav_graph"
    app:startDestination="@id/homeFragment">

    <fragment
        android:id="@+id/homeFragment"
        android:name="com.vapoyan.myapplication.HomeFragment"
        android:label="fragment_home"
        tools:layout="@layout/fragment_home" >
        <action
            android:id="@+id/action_homeFragment_to_menuFragment"
            app:destination="@id/menuFragment" />
    </fragment>

    <fragment
        android:id="@+id/menuFragment"
        android:name="com.vapoyan.myapplication.MenuFragment"
        android:label="fragment_menu"
        tools:layout="@layout/fragment_menu" />
</navigation>
Run Code Online (Sandbox Code Playgroud)

有没有人有经验或可以建议我如何解决问题,导航组件是否支持工具栏?

任何示例代码或参考?

android kotlin android-architecture-components androidx

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

是observeForever 生命周期意识吗?

我正在使用 MVVM,并且已经对其进行了不同的实现,但仍然让我怀疑的一件事是如何从我的 ViewModel 的存储库 (Firebase) 获取数据,而不将任何生命周期附加到 ViewModel。

我已经observeForever()从 ViewModel实现了,但我认为这不是一个好主意,因为我认为我应该通过回调或转换从我的存储库到我的 ViewModel 进行通信。

我在这里留下一个例子,我从 Firebase 获取设备并更新我的 UI,如果我们能在这里看到,我正在观察来自 UI 的 repo 的数据,但从 ViewModel 我也在观察来自 repo 的数据,这就是我真正怀疑我是否使用正确方法的地方,因为我不知道如果我的视图被破坏是否observeForever()会被清除onCleared(),所以如果视图死亡,它不会让观察者保持活动状态。

用户界面

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        button.setOnClickListener {
            val deviceId = editText.text.toString().trim()
            observeData(deviceId)
        }
    }

    fun observeData(deviceId:String){
        viewModel.fetchDeviceData(deviceId).observe(this, Observer {
            textView.text = "Tipo: ${it.devType}"
        })
Run Code Online (Sandbox Code Playgroud)

视图模型

class MainViewmodel: ViewModel() {

    private val repo = Repo()
    fun fetchDeviceData(deviceId:String):LiveData<Device>{
        val mutableData = MutableLiveData<Device>()
        repo.getDeviceData(deviceId).observeForever {
            mutableData.value = it
        }

        return mutableData …
Run Code Online (Sandbox Code Playgroud)

android mvvm kotlin android-livedata android-architecture-components

12
推荐指数
1
解决办法
6937
查看次数