背景:
我在 Android (Java) 项目中使用 Room 持久性库来支持本地数据缓存。查询或保存数据时,Room 在专用线程上运行。
Problem:
如果 Room 管理的这些线程之一引发异常,则整个应用程序将崩溃。如果数据不一致(例如数据与当前架构不匹配),则可能会发生这种情况。这是很有问题的。我宁愿自己处理此类异常并擦除本地数据库中的所有数据 - 这比给用户留下一个完全损坏且无法修复的应用程序要好。
异常示例:
2020-01-22 12:45:08.252 9159-11043/com.xyz E/AndroidRuntime: FATAL EXCEPTION: arch_disk_io_1
Process: com.xyz, PID: 9159
java.lang.RuntimeException: Exception while computing database live data.
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:92)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "primary" (class com.xyz.model.remotedatasource.sampleApi.entities.ProfileImage), not marked as ignorable (2 known properties: "isPrimary", "url"])
at [Source: (byte[])":)
... -1, column: 402] (through reference chain: com.xyz.model.remotedatasource.sampleApi.entities.Candidate["profileImages"]->java.util.ArrayList[0]->com.xyz.model.remotedatasource.sampleApi.entities.ProfileImage["primary"])
at com.xyz.model.localdatasource.Converters.deserialize(Converters.java:113)
at com.xyz.model.localdatasource.Converters.toCandidate(Converters.java:73)
at com.xyz.model.localdatasource.LocalDao_Impl$4.call(LocalDao_Impl.java:270)
at com.xyz.model.localdatasource.LocalDao_Impl$4.call(LocalDao_Impl.java:217)
at androidx.room.RoomTrackingLiveData$1.run(RoomTrackingLiveData.java:90)
... 3 more
数据访问对象 (DAO) 示例:
public interface LocalDao {
@Query("SELECT * FROM Match")
LiveData<List<Match>> getMatches();
@Insert(onConflict = REPLACE)
void saveMatches(List<Match> matches);
}
Question
由于 Room 在后台线程中执行许多操作,我希望有一种方法来注册自定义错误处理程序。你知道如何实现这一目标吗?如果没有,您对发生此类异常时如何自动擦除数据库还有其他建议吗?
我不认为你可以对这些做些什么,它假设模式是正确的,但如果数据或模式有问题,那么你可以在插入或对它们执行任何操作时处理类似的事情。
只需将 DAO 函数标记为可抛出方法并在调用方处理可能的错误即可。
public interface LocalDao {
@Query("SELECT * FROM Match")
LiveData<List<Match>> getMatches() throws Exception;
@Insert(onConflict = REPLACE)
void saveMatches(List<Match> matches) throws Exception;
@Query("DELETE FROM Match")
public void nukeTable();
}
现在在调用方只需调用此处理异常即可。
public getMatches(){
//... some code
try{
//some code goes here
dao.getMatches();
}catch(Exception exp){
//if something happens bad then nuke the table on background thread
dao.nukeTable()
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)