我正在尝试使用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
我正在使用回收器显示Room wrapped DB的内容的屏幕上.适配器从ViewModel获取LiveData,该ViewModel隐藏Room DAO对象上的查询调用.因此,LiveData对象实际上是一个ComputableLiveData对象,它知道Room DB的更改.
现在我想在屏幕上添加过滤器选项.我在何处/如何在Room-LiveData-ViewModel设置中实现此功能?
适配器或ViewModel应该"postfilter"结果在LiveData中吗?我是否应该为每次过滤器更改从房间重新查询数据?我可以重用底层(可计算)LiveData吗?如果没有,我是否真的应该为每个过滤器更改创建新的LiveData?
我正在试验Room数据库。我不希望我的数据被观察到,我只想从数据库中获取一次数据。如何使用 MVVM 实现这一目标?
我面临的问题:如果我尝试在没有数据的情况下获取数据AsyncTask:无法访问主线程上的数据库,因为它可能会长时间锁定 UI(如预期),如果我使用AsyncTask,该方法返回 nullList作为方法在AsyncTask完成之前返回。
道类:
@Query("SELECT * FROM student_table where StudentName = :studentName")List<Student> getStudentWithSameName(String studentName);
Run Code Online (Sandbox Code Playgroud)
存储库:
public List<Student> getAllStudentWithSameName(String studentName) {
new GetAllStudentWithSameNameAsyncTask(studentDao).execute(studentName);
return studentsWithSameName;
}
private class GetAllStudentWithSameNameAsyncTask extends AsyncTask< String,Void, List<Student> > {
StudentDao studentDao;
public GetAllStudentWithSameNameAsyncTask(StudentDao studentDao) {
this.studentDao = studentDao;
}
@Override
protected List<Student> doInBackground(String... strings) {
List<Student> students = studentDao.getStudentWithSameName(strings[0]);
return students;
}
@Override
protected void onPostExecute(List<Student> students) {
studentsWithSameName = …Run Code Online (Sandbox Code Playgroud) 两种情况:
1. Session data - For example the logged in User details, or some other session data.
2. Global/stateless data - A repository with retrofit client.
Run Code Online (Sandbox Code Playgroud)
对于情况 1:最简单的方法是使用某种单例 "DataManager/LoginManger" ,但单例很糟糕(测试,随着时间的推移状态不可预测......)另一种方法是使用 Application 类,这也是坏的。
那么我们在哪里存储这些数据呢?
对于案例 2:一个简单的存储库,其中包含对 Retrofit 客户端或其他客户端的引用。
使用它作为单例更有意义,因为这个类是不可变的/无状态的。我们只想创建一次改造客户端。但是.. 测试?
3 . 另外,如果我们想获取 location 怎么办?我们可以在 ViewModel 中使用 LiveData 来负责。但是 ViewModel 的范围是某个视图/活动。所以这意味着如果我们更改视图(例如从抽屉中输入设置,而主页的视图模型正在获取位置),一旦检索到位置数据,我们将丢失位置数据,然后当用户返回主页时,我们不仅要向他们显示位置,还必须重新请求位置。
我还没有找到任何方式来处理所有这些情况。似乎没有明确的答案。
我正在尝试了解 android 中的 ViewModel 和 LiveData 概念。我正在做一个练习项目,但是当我implementation 'androidx.lifecycle:lifecycle-extensions-ktx:2.0.0-alpha1'在我的应用程序级别的 gradle 文件中添加一行时,它显示了我
无法解决:androidx.lifecycle:lifecycle-extensions-ktx:2.0.0-alpha1。
我在 google 上搜索了解决方案,我找到了这个答案,它在我只编译 viewmodel 库时有效,但如果我使用与 相同的方法编译扩展库implementation group: 'androidx.lifecycle', name:'lifecycle-extensions-ktx', version: '2.0.0-alpha1',它会显示与上面相同的错误。我也试图找到它的Maven仓库网站在这里,但我并没有对如何编译它的任何信息。
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 28
defaultConfig {
applicationId "***************"
minSdkVersion 19
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar']) …Run Code Online (Sandbox Code Playgroud) android kotlin android-livedata android-viewmodel android-architecture-components
我使用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
我似乎找不到这个起源DataBinding NullPointerException。当使用Android Navigation Architecture导航到a Fragment并重复导航时,我最终将获得以下堆栈跟踪
java.lang.NullPointerException: Attempt to invoke direct method 'void androidx.databinding.ViewDataBinding.handleFieldChange(int, java.lang.Object, int)' on a null object reference
at androidx.databinding.ViewDataBinding.access$800(ViewDataBinding.java:64)
at androidx.databinding.ViewDataBinding$LiveDataListener.onChanged(ViewDataBinding.java:1592)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:113)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:126)
at androidx.lifecycle.LiveData$ObserverWrapper.activeStateChanged(LiveData.java:424)
at androidx.lifecycle.LiveData$LifecycleBoundObserver.onStateChanged(LiveData.java:376)
at androidx.lifecycle.LifecycleRegistry$ObserverWithState.dispatchEvent(LifecycleRegistry.java:355)
at androidx.lifecycle.LifecycleRegistry.forwardPass(LifecycleRegistry.java:293)
at androidx.lifecycle.LifecycleRegistry.sync(LifecycleRegistry.java:333)
at androidx.lifecycle.LifecycleRegistry.moveToState(LifecycleRegistry.java:138)
at androidx.lifecycle.LifecycleRegistry.handleLifecycleEvent(LifecycleRegistry.java:124)
at androidx.fragment.app.Fragment.performStart(Fragment.java:2485)
at androidx.fragment.app.FragmentManagerImpl.moveToState(FragmentManager.java:1494)
at androidx.fragment.app.FragmentManagerImpl.addAddedFragments(FragmentManager.java:2646)
at androidx.fragment.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2416)
at androidx.fragment.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2372)
at androidx.fragment.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2273)
at androidx.fragment.app.FragmentManagerImpl$1.run(FragmentManager.java:733)
at android.os.Handler.handleCallback(Handler.java:789)
at android.os.Handler.dispatchMessage(Handler.java:98)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6938)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Run Code Online (Sandbox Code Playgroud)
看起来它与LiveData异常中所述的生命周期有关。我猜想出于内存原因清除onPause …
android nullpointerexception android-livedata android-architecture-navigation
我有一个垂直滚动的回收视图(verticalRV)。此回收站视图(horizontalRV)中的每个项目都是一个水平回收站视图。
在 verticalRV itemViewHodler 内部,我试图从视图模型中获取数据并观察是否有任何变化并相应地更新 horizontalRV 适配器。
但是观察者是onChanged方法没有被调用。
我已经实现了 LifecycleOwner 接口来管理带有 livedata 的视图持有者的生命周期,并相应地从 verticalRV 的适配器中设置状态
public class VeritcalRVHolderItem implements LifecycleOwner {
private static final String TAG = LDFeedListAdapterHolder.class.getSimpleName();
private final FragmentActivity activity;
private final RvHorizontalListAdapter adapter;
private RecyclerView rvHorizontalList;
public VeritcalRVHolderItem(Context context, View itemView, FragmentActivity activity) {
super(context, itemView);
this.activity = activity;
rvHorizontalList = itemView.findViewById(R.id.rvHorizontalList);
LinearLayoutManager layout = new LinearLayoutManager(getContext(), LinearLayout.HORIZONTAL, false);
rvHorizontalList.setLayoutManager(layout);
adapter = new RvHorizontalListAdapter(this.activity);
rvHorizontalList.setAdapter(adapter);
LDViewModel LDViewModel = ViewModelProviders.of(activity).get(LDViewModel.class);
LDViewModel.getTopicsForFeed().observe(this, new Observer<List<Topic>>() {
@Override
public …Run Code Online (Sandbox Code Playgroud) android mvvm viewmodel android-recyclerview android-livedata
我添加了一些代码以使我的问题更清楚。
改造界面:
public interface JsonPlaceHolderAPI {
public static final String BASE_URL = "https://jsonplaceholder.typicode.com/";
@GET("todos/{number}")
Call<ResponseBody> getJsonResponse(@Path("number") String number);
}
Run Code Online (Sandbox Code Playgroud)
存储库:--> fetchResponse() 将 Viewmodel 的 MutableLiveData 作为参数并使用它来更新其值,然后触发 View 更改其 UI。
public class Repository {
private final JsonPlaceHolderAPI api;
public Repository() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.build();
api = retrofit.create(JsonPlaceHolderAPI.class);
}
public void fetchResponse(String number, final MutableLiveData<CharSequence> mld){
final MutableLiveData<CharSequence> ml = new MutableLiveData<>();
api.getJsonResponse(number).enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
mld.setValue(response.body().string());
} catch …Run Code Online (Sandbox Code Playgroud) 我想将LiveData与Kotlin一起使用,并且值不应为null.你怎么处理这个?也许LiveData的包装?在这里寻找好的模式..作为一个例子:
class NetworkDefinitionProvider : MutableLiveData<NetworkDefinition>() {
val allDefinitions = mutableListOf(RinkebyNetworkDefinition(), MainnetNetworkDefinition(), RopstenNetworkDefinition())
init {
value = allDefinitions.first()
}
fun setCurrent(value: NetworkDefinition) {
setValue(value)
}
}
Run Code Online (Sandbox Code Playgroud)
我知道访问时值不会为空 - 但我总是要检查null或者让这些丑陋!
android kotlin android-livedata android-architecture-components
android ×10
android-livedata ×10
android-architecture-components ×5
kotlin ×3
mvvm ×3
android-room ×2
android-architecture-navigation ×1
singleton ×1
viewmodel ×1