java - 房间数据库不需要新的线程来进行长时间的查询操作

标签 java android multithreading android-room android-jetpack

到处都是相同的信息,长时间的操作需要在其他线程中运行,不同于 UI 线程,例如 - 数据库操作。
...这是真的,如果我尝试将某些内容保存到数据库中,我会得到:

Cannot access database on the main thread since it may potentially lock the UI for a long period of time.

这是我的问题,为什么我能够从 UI 的数据库中获取所有数据? :)
(我的数据库没有 .allowMainThreadQueries()

这是来自谷歌文档的一些修改代码:

View 模型:

public class LocationsViewModel extends AndroidViewModel {

    private LocationRepository locationRepository;
    private LiveData<List<LocationModel>> allLocationsLiveData;

    public LiveData<List<LocationModel>> getAllLocationsLiveData() {
        return allLocationsLiveData;
    }

    public LocationsViewModel(@NonNull Application application) {
        super(application);
        locationRepository = new LocationRepository(application);
        allLocationsLiveData = locationRepository.getAllLocation();
    }
}

存储库:

public class LocationRepository {

    private final LocationDao locationDao;
    private LiveData<List<LocationModel>> allLocation;

    LiveData<List<LocationModel>> getAllLocation() {
        return allLocation;
    }

    LocationRepository(Application application){
        LocationsDatabase db = LocationsDatabase.getDatabase(application);
        locationDao = db.locationDao();
        allLocation = locationDao.getAllLocations();
    }

}

fragment 中的初始化方法:

private void initData() {
    locationsViewModel = ViewModelProviders.of(this).get(LocationsViewModel.class);
    locationsViewModel.getAllLocationsLiveData().observe(this, new Observer<List<LocationModel>>() {
        @Override
        public void onChanged(@Nullable List<LocationModel> locations) {
            mAdapter.setLocationList(locations);
        }
    });
}

道:

@Dao
public interface LocationDao {
    @Insert(onConflict = OnConflictStrategy.IGNORE)
    void insert(LocationModel... locations);

    @Query("SELECT * FROM LocationModel")
    LiveData<List<LocationModel>> getAllLocations();
}

那么为什么我能够从 UI 获取 FromDatabse,但需要其他线程来保存?

最佳答案

您使用 LiveData,它实际上在后台线程上运行。

它不是同步发生的,所以它不会发生在主线程上。

您订阅更改,这些更改在后台线程上计算,然后仅在主线程上提供给您的 Activity/Fragment。

当您尝试保存某些内容时,您不会使用 LiveData(您也不应该使用它,所以一切都很好),因此它在主线程上运行。这是不应该的。
因此,您需要在新线程中运行它,创建 AsyncTask 或类似的东西。

关于java - 房间数据库不需要新的线程来进行长时间的查询操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53467104/

相关文章:

java - 带有 2 种纯色的进度条

java - 从 Android NDK SIGSEGV 调用 Java 方法

java - 在Micronaut的声明式客户端中传递自定义 header

android - 如何使用 AlarmManager 和广播接收器发送文本?

java - 如何为 android 创建 vector 可绘制对象?

java - requestLocationUpdates 中的 minDistance 参数

java - 简单循环时间复杂度内的递归函数

.net - 使用与 Parallel.ForEach 同时运行的计时器防止线程池饥饿

c++ - 在 C++/CLI 代码中包含的代码中使用 <thread>。寻找更好的解决方案

vb.net - backgroundWorker仅在取消时更新进度