标签: android-livedata

Room - LiveData观察器在数据库更新时不会触发

我试图在下面的代码中找到,为什么一旦我用新数据填充数据库,Room的LiveData observable就不会给我新的转变.

这是我的活动的onCreate方法:

shiftsViewModel = ViewModelProviders.of(this).get(ShiftsViewModel.class);
shiftsViewModel
            .getShifts()
            .observe(this, this::populateAdapter);
Run Code Online (Sandbox Code Playgroud)

这是populateAdapter方法:

private void populateAdapter(@NonNull final List<Shift> shifts){

    recyclerView.setAdapter(new SimpleItemRecyclerViewAdapter(shifts));
}
Run Code Online (Sandbox Code Playgroud)

我还有以下代码填充数据库(我使用RxJava在IO线程上完成工作,因为Room需要在主线程之外调用它的代码):

@Override
public Observable<List<Shift>> persistShifts(@NonNull final List<Shift> shifts){

    return Observable.fromCallable(() -> {

        appDatabase.getShiftDao().insertAll(shifts);
        return shifts;
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread());
}
Run Code Online (Sandbox Code Playgroud)

在我开始观察我的shiftViewModel之后调用persistShifts时出现的问题.我希望我的观察者(LiveData)会被所有新添加的班次触发.事实证明,观察者被触发了,但是返回了一个空的移位列表.使其"工作"的唯一方法是,如果我离开活动(因此销毁当前的ViewModel)并再次输入.这次viewModel的LiveData为我提供了之前保持的所有变化,正如预期的那样.

这是代码的其余部分:

@Entity
public class Shift{

   @PrimaryKey
   private long id;

   private String start;
   private String end;
   private String startLatitude;
   private String startLongitude;
   private String endLatitude;
   private String endLongitude;
   private String image;
   ...
Run Code Online (Sandbox Code Playgroud)

DAO:

@Dao
public interface ShiftDAO {

   @Query("SELECT * FROM …
Run Code Online (Sandbox Code Playgroud)

android viewmodel android-room android-livedata android-architecture-components

17
推荐指数
1
解决办法
7087
查看次数

Android LiveData - 如何在不同的活动上重用相同的ViewModel?

示例ViewModel:

public class NameViewModel extends ViewModel {
    // Create a LiveData with a String
    private MutableLiveData<String> mCurrentName;

    public MutableLiveData<String> getCurrentName() {
        if (mCurrentName == null) {
            mCurrentName = new MutableLiveData<>();
        }
        return mCurrentName;
    }

}
Run Code Online (Sandbox Code Playgroud)

主要活动:

mModel = ViewModelProviders.of(this).get(NameViewModel.class);

// Create the observer which updates the UI.
final Observer<String> nameObserver = textView::setText;

// Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
mModel.getCurrentName().observe(this, nameObserver);
Run Code Online (Sandbox Code Playgroud)

我想调用mModel.getCurrentName().setValue(anotherName);第二个活动并使MainActivity接收更改.那可能吗?

java android android-livedata

17
推荐指数
2
解决办法
1万
查看次数

发射和发射源与 LiveData 有什么区别?(如在实时用例中)

emit接受data类而emitSource接受LiveData<T>( T -> data)。考虑以下示例:-我有两种类型的调用:-

suspend fun getData(): Data // returns directly data
Run Code Online (Sandbox Code Playgroud)

而另一个;

suspend fun getData(): LiveData<Data> // returns live data instead
Run Code Online (Sandbox Code Playgroud)

对于第一种情况,我可以使用:-

liveData {
   emit(LOADING)
   emit(getData())
}
Run Code Online (Sandbox Code Playgroud)

我的问题:使用上述方法可以解决我的问题,为什么我们还需要emitSource(liveData)

任何使用该emitSource方法的好用例都会清楚地表明!

android android-livedata android-architecture-components android-jetpack kotlin-coroutines

17
推荐指数
4
解决办法
5963
查看次数

LocalBroadcastManager 已被弃用。我应该用什么代替它?

我正在 Android 中处理这个项目,其中一个方面需要一个带有前台服务的 CountdownTimer。Stack Overflow 上的其他一些答案提到 LocalBroadcastManager 适合我的需求。

然而,Android Developers 中的文档提到它已被弃用。关于我应该在它的位置使用什么的任何建议?文档提到了使用 LiveData,但我想知道是否有更简单的替代方法。

service android localbroadcastmanager android-livedata

17
推荐指数
1
解决办法
4614
查看次数

StateFlow 和 LiveData 有什么区别?

正如我在标题中提到的,我很好奇两者之间的一般差异。你能帮忙吗?我找不到具体的区别,因为互联网上有复杂的例子。

  1. 在性能方面有哪些差异?
  2. 在哪些场景下有优势?
  3. 将 StateFlow 与 Kotlin Flow 结合使用是有利的。但是在使用 LiveData 的项目中不切换到 StateFlow 会有什么风险呢?
  4. Google 是否会弃用 LiveData?:)

android kotlin android-livedata kotlin-flow kotlin-stateflow

17
推荐指数
1
解决办法
5253
查看次数

如何使用ViewModel和LiveData进行改进API调用

这是我第一次尝试实现MVVM架构,而且我对进行API调用的正确方法感到有些困惑.

目前,我只是尝试从IGDB API进行简单查询,并输出日志中第一项的名称.

我的活动设置如下:

public class PopularGamesActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_popular_games);


        PopularGamesViewModel popViewModel = ViewModelProviders.of(this).get(PopularGamesViewModel.class);
        popViewModel.getGameList().observe(this, new Observer<List<Game>>() {
            @Override
            public void onChanged(@Nullable List<Game> gameList) {
                String firstName = gameList.get(0).getName();
                Timber.d(firstName);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

我的视图模型设置如下:

public class PopularGamesViewModel extends AndroidViewModel {

    private static final String igdbBaseUrl = "https://api-endpoint.igdb.com/";
    private static final String FIELDS = "id,name,genres,cover,popularity";
    private static final String ORDER = "popularity:desc";
    private static final int LIMIT = 30;

    private LiveData<List<Game>> mGameList; …
Run Code Online (Sandbox Code Playgroud)

android mvvm retrofit android-livedata android-jetpack

16
推荐指数
1
解决办法
9378
查看次数

Android中如何收集多个状态流

如何收集activity中的两个状态流?因为我只消耗了第一个流量。

例如,viewmodel内部是这样的:

class ExampleViewModel: ViewModel(){
    private val state = MutableStateFlow<HomeMainFragmentState>(HomeMainFragmentState.Init)
    private val products = MutableStateFlow<List<ProductEntity>>(mutableListOf())


    //to be consumed
    fun getState() : StateFlow<HomeMainFragmentState> = state
    fun getProducts() : StateFlow<List<ProductEntity>> = products
}
Run Code Online (Sandbox Code Playgroud)

然后在我看来是这样的:

private fun observe(){
      viewLifecycleOwner.lifecycleScope.launch {
      viewLifecycleOwner.lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED){
            viewModel.getState().collect { state -> handleState(state) }
            viewModel.getProducts().collect{ products -> handleProducts(products) }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是,只有第一个流被消耗,因为这种情况是“状态”产品从未被活动/片段消耗/执行。

如何解决这个问题?我还阅读了有关组合流程的信息,这是否意味着第二个流程取决于第一个流程的运行?

android kotlin android-livedata kotlin-flow

16
推荐指数
2
解决办法
1万
查看次数

如何将List <Object>转换为PagedList <Object>,反之亦然?

PagedList<Object>用于Android的酷分页库.要使问题尽可能小:如果我有一个字符串列表,如

  List<String> stringList; // it consists of 200 strings
Run Code Online (Sandbox Code Playgroud)

我想转换 stringListPagedList<String>类似的类型

  PagedList<String> pagedStringList;
Run Code Online (Sandbox Code Playgroud)

而且,如果我有一个PagedList<Object>如何将其转换为List<Object>?我经历了这个以供参考

如果我尝试相反的方式....

我怎么能转换List<Object>DataSource.Factory<Integer, Object>..所以间接我可以把它转换成PagedList<>

DataSource.Factory<Integer, Object>我可以转换为PagedList<>但我怎么能转换listPagedList<>

android rx-java2 android-livedata android-architecture-components android-jetpack

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

LiveData.无法分配给'value':setter受保护/*受保护,package*/用于合成扩展

我正在尝试使用Android文档中描述的LiveData实现DB Observer .

只要我在Kotlin编程,我就会调整函数(最初用Java编写).

在尝试保存数据时,我发现了这个问题.

Cannot assign to ‘value’: the setter is protected/*protected and package*/ for synthetic extension in ‘<library Grade: android.arch.livecycle:livedata-core-1.1.1>’
Run Code Online (Sandbox Code Playgroud)

有人有这个问题吗?

这是我的代码:

视图模型:

class ProfileViewModel: ViewModel() {

    object FirstName: MutableLiveData<String>()

    fun getCurrentName(): LiveData<String> {
        return FirstName
    }
}
Run Code Online (Sandbox Code Playgroud)

分段

class ProfileFragment{

    private lateinit var model: ProfileViewModel

    // this is called onViewCreated. inputFirstName is an Edittext.
    override fun setUp() {
        model = ViewModelProviders.of(this).get(ProfileViewModel::class.java)

        val nameObserver = Observer<String> { firstName ->
            inputFirstName.text = SpannableStringBuilder(firstName)
        }

        model.getCurrentName().observe(this, nameObserver)
    } …
Run Code Online (Sandbox Code Playgroud)

android kotlin android-livedata android-architecture-components

15
推荐指数
1
解决办法
4402
查看次数

将viewModel观察者放在dialogFragment中的位置?

对于片段,建议将liveData观察者放在onActivityCreated方法中.这适用于片段,但当我将其应用于dialogFragment时,我收到以下错误:

java.lang.IllegalStateException:当getView()为null时,即在onCreateView()之前或onDestroyView()之后,无法访问Fragment View的LifecycleOwner.

从这个问题我在创建时读取了dialogFragment的生命周期:

onAttach
onCreate
onCreateDialog
onCreateView
onActivityCreated
onStart
onResume
Run Code Online (Sandbox Code Playgroud)

因此,将观察者放在onActivityCreated中应该没有问题,因为它在onCreateView或onCreateDialog之后.我使用后者,因为我使用自己的布局的Alertdialog.

这是我的观察者的代码:

mScheduleViewModel.getTeachers().observe(getViewLifecycleOwner(), new Observer<List<String>>() {
        @Override
        public void onChanged(@Nullable List<String> strings) {
            mStringList = strings;
            aclInputvalue.setThreshold(2);
            aclAdapter.setList(strings);
            aclAdapter.notifyDataSetChanged();
            ....
}
Run Code Online (Sandbox Code Playgroud)

此代码模式在片段中正常工作,但在dialogFragment中不起作用.我必须将lifecycleOwner设置为'this'.

那么为什么我会收到错误?

android android-livedata

15
推荐指数
1
解决办法
4182
查看次数