【发布时间】:2019-03-12 02:40:14
【问题描述】:
问题
我实现了 Android 架构库,并通过它从房间数据库中恢复数据,使用 MVVM(模型视图视图模型),每当我每次启动应用程序时使用观察者查看 LiveDada 时,都会出现明显的延迟回收站视图中的项目加载。
图片说明了当应用统计信息和项目加载时显示延迟时的含义。
我想要它做什么
我想用 LiveData 实现的是this,而我能够实现这一点的方法是在我的 Dao 中我使用 Query 来获取所有数据并将其作为 List 传递,而不是使用 LiveData 然后在存储库将其转换为 MutableLiveData,然后将其传递给数据库,然后在我的片段中将其作为 LiveData 进行观察,但使用这种方法实际上不会在删除或插入时更新,除非我重新启动应用程序。
有什么办法可以解决这个问题吗?
我很想使用 LiveData。
这是我的 DevicesDao 界面:
@Dao
public interface DevicesDao {
@Insert
void insert(Devices... devices);
@Query("SELECT * FROM devices")
LiveData<List<Devices>> getDevices();
/*
@Query("SELECT * FROM devices")
List<Devices> getDevices();
*/
@Delete
void delete(Devices... device);
@Update
void update(Devices... device);
}
数据库:
@Database(entities = {Devices.class}, version = 1)
public abstract class DevicesDatabase extends RoomDatabase {
private static final String DATABASE_NAME = "devices_registered";
private static DevicesDatabase instance;
public abstract DevicesDao devicesDao();
public static DevicesDatabase getInstance(final Context context) {
if (instance == null) {
synchronized (DevicesDatabase.class) {
if (instance == null) {
instance = Room.databaseBuilder(
context.getApplicationContext(),
DevicesDatabase.class,
DATABASE_NAME)
.fallbackToDestructiveMigration()
.build();
}
}
}
return instance;
}
}
存储库:
public class DevicesRepository {
private final DevicesDao devicesDao;
public DevicesRepository(Application application) {
DevicesDatabase db = DevicesDatabase.getInstance(application);
devicesDao = db.devicesDao();
}
public void addDevices(Devices devices) {
new InsertDeviceAsync(devicesDao).execute(devices);
}
public void updateDevice(Devices devices) {
new UpdateDeviceAsync(devicesDao).execute(devices);
}
public void deleteDevice(Devices devices) {
new DeleteDeviceAsync(devicesDao).execute(devices);
}
//Gets all data from SQLite
public LiveData<List<Devices>> getAllDevices() {
return devicesDao.getDevices();
}
/*
public LiveData<List<Devices>> getAllDevices() {
MutableLiveData<List<Devices>> devices = new MutableLiveData<>();
try {
devices.setValue(new GetDeviceAsync(devicesDao).execute().get());
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return devices;
}
*/
}
查看模型文件:
public class HomeFragmentViewModel extends AndroidViewModel {
private final DevicesRepository devicesRepository;
private LiveData<List<Devices>> devices;
public HomeFragmentViewModel(@NotNull Application application) {
super(application);
devicesRepository = new DevicesRepository(application);
devices = devicesRepository.getAllDevices();
}
public LiveData<List<Devices>> getAllDevices() {
return devices;
}
public void addNewDevice(Devices devices) {
devicesRepository.addDevices(devices);
}
public void deleteDevice(Devices devices) {
devicesRepository.deleteDevice(devices);
}
public void editDevice(Devices devices) {
devicesRepository.updateDevice(devices);
}
}
最后,我片段中的观察者:
///////Other code
//Implements ViewModel to HomeFragment
homeFragmentViewModel = ViewModelProviders.of(this).get(HomeFragmentViewModel.class);
homeFragmentViewModel.getAllDevices().observe(getViewLifecycleOwner(), devicesList -> {
//Validation tool
validationUtil = new ValidationUtil(devicesList);
//Adds to adapter
adapter.submitList(devicesList);
/////// Other code
});
感谢您的宝贵时间!!!
【问题讨论】:
-
我认为这应该进入代码审查堆栈交换。您的代码看起来不错,延迟几乎不明显,因为您必须初始化 dao 并进行查询。
-
@m0skit0 好的,将进入代码审查。谢谢!
-
你试过adapter.notifyDataSetChanged()吗?但是您还需要在片段中本地复制您的列表并将该本地列表传递给您的适配器。
-
@Amirjodat 我试图避免将数据复制到片段中的列表中,但我会尝试这样做。在我的 recyclerview 适配器中,我使用 ListAdapter,它不使用 notifySetDataChanged。相反,它会根据已编辑的文件对范围进行排序。
-
更新:即使添加带有我的列表副本的适配器也会得到相同的结果。
标签: android architecture android-livedata