我试图在下面的代码中找到,为什么一旦我用新数据填充数据库,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
示例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接收更改.那可能吗?
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
我正在 Android 中处理这个项目,其中一个方面需要一个带有前台服务的 CountdownTimer。Stack Overflow 上的其他一些答案提到 LocalBroadcastManager 适合我的需求。
然而,Android Developers 中的文档提到它已被弃用。关于我应该在它的位置使用什么的任何建议?文档提到了使用 LiveData,但我想知道是否有更简单的替代方法。
正如我在标题中提到的,我很好奇两者之间的一般差异。你能帮忙吗?我找不到具体的区别,因为互联网上有复杂的例子。
android kotlin android-livedata kotlin-flow kotlin-stateflow
这是我第一次尝试实现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) 如何收集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)
问题是,只有第一个流被消耗,因为这种情况是“状态”,产品从未被活动/片段消耗/执行。
如何解决这个问题?我还阅读了有关组合流程的信息,这是否意味着第二个流程取决于第一个流程的运行?
PagedList<Object>用于Android的酷分页库.要使问题尽可能小:如果我有一个字符串列表,如
List<String> stringList; // it consists of 200 strings
Run Code Online (Sandbox Code Playgroud)
我想转换 stringList为PagedList<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<>但我怎么能转换list成PagedList<>?
android rx-java2 android-livedata android-architecture-components android-jetpack
我正在尝试使用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
对于片段,建议将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 ×10
android-livedata ×10
android-architecture-components ×4
kotlin ×3
kotlin-flow ×2
android-room ×1
java ×1
mvvm ×1
retrofit ×1
rx-java2 ×1
service ×1
viewmodel ×1