比方说,我需要定期(每3秒)读取一些RealmObject
的列表,并且我想将这些对象映射到将用于填充列表内容的简单数据对象。
对于那些想知道的人,有三个原因:
ViewHolder
中视图的值和行为(可见性)的复杂性ListAdapter
,它需要提供DiffUtilCallback
并将在UI之外的其他线程上执行,因此无法在其方法中进行所需的计算,因为它们将从没有在其中创建它们的线程。 我不能简单地以简单的方式使用协程,因为协程将从执行中的一个可用线程跳转到另一个线程,因为我(并且确实如此)最终会收到“领域已关闭” 异常。 / p>
我想出的唯一解决方案是使用仅使用一个线程newSingleThreadContext("RealmSingleThreadContext")
的调度程序:
class RealmSingleThreadContext {
val ctx = NewSingleThreadedContext("RealmSingleThreadContext")
lateinit var realm : Realm
init {
// opening Realm connection for thread "RealmSingleThreadContext"
GlobalScope.launch(ctx) { realm = Realm.getDefaultInstance() }
}
fun close() {
GlobalScope.launch(ctx) { if (!realm.isClosed()) realm.close() }
}
}
此类通过Dagger作为Singleton提供,最终,在后台,我将有一个线程为整个应用程序进行映射,而我的“ main” viewModel将在其onClosed
方法中调用{此类的{1}}方法。
这是我的用法:
close()
唯一的问题是函数class HomeViewModel @Inject constructor(/* other */var realmSingleThreadContext: RealmSingleThreadContext) {
var topLiveEventsUI: MutableLiveData<List<EventPreviewUI>> = MutableLiveData(listOf())
fun useRealmInBckg() {
viewModeScope.launch(realmSingleThreadContext.ctx) {
topLiveEventsUI.postValue(eventsReadUseCase.getTopLiveEvents()
.map{ mapper.map(it) }
}
}
}
具有newSingleThreadContext(name: String)
批注,因此这意味着它将很快被删除。
我的问题是:除了使用这个废弃的Dispatcher之外,还有谁能提出其他解决方案?
答案 0 :(得分:1)
使用Java执行程序创建您自己的单线程调度程序非常容易:
$mods = array();
foreach($fields as $field) {
$mods[$field['name']][] = $field['rating'];
}
<table>
<tr>
<?php
if($mods) {
foreach($mods as $key=>$value) {
?>
<td><?php echo $key; ?></td>
<td><?php echo (array_sum($value)/count($value)); ?></td>
<?php
}
}
?>