如何使用异步任务侦听器返回并暂停Coroutine?
我要做的是以下内容:
- 使用调色板从API加载代理图标
- ,确定什么是充满活力的Swatch
- 设置此背景RGB颜色,然后将其保存到数据库
- 数据库中,将更新,更新流程并推动新的流程UI
- UI的更新会选择它,然后将其设置为回收器视图,
但是,我正在努力使其在我的存储库中工作。我的功能看起来像这样:
suspend fun updateAgentBackground(agent: Agent, successResult: SuccessResult) {
if (agent.backgroundRgb == null) {
withContext(Dispatchers.IO) {
Palette.Builder(successResult.drawable.toBitmap()).generate { palette ->
val rgb = palette?.vibrantSwatch?.rgb
if (rgb != null) {
val agentWithBackground = agent.copy(backgroundRgb = rgb)
agentDao.insertAgent(agentWithBackground.toAgentEntity())
}
}
}
}
}
但是,它在 agentdao.intertagent()
上在运行时崩溃,因为它说它在主线程上运行了DB操作。我也无法将此方法包裹在 generate()
带有 withContext(dispatchers.io)
的回调中,因为它不在coroutine主体中。
这就是 palette.builder()。generate()
函数在源代码中的样子:
@NonNull
public AsyncTask<Bitmap, Void, Palette> generate(
@NonNull final PaletteAsyncListener listener) {
if (listener == null) {
throw new IllegalArgumentException("listener can not be null");
}
return new AsyncTask<Bitmap, Void, Palette>() {
@Override
@Nullable
protected Palette doInBackground(Bitmap... params) {
try {
return generate();
} catch (Exception e) {
Log.e(LOG_TAG, "Exception thrown during async generate", e);
return null;
}
}
@Override
protected void onPostExecute(@Nullable Palette colorExtractor) {
listener.onGenerated(colorExtractor);
}
}.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, mBitmap);
}
public interface PaletteAsyncListener {
void onGenerated(@Nullable Palette palette);
}
因此,我将其传递给它 paletteasynclistener
,它 hurn hurn oster > ongererated()
。我以某种方式希望这种方法暂停Coroutine,并以更新的背景返回 Agent
。或以某种方式能够在此回调中调用我的DB方法 AgentDao.Intertagent()
在主线程中。
我可以以某种方式混合并匹配源代码如何使用 asynctask
与我的coroutines使用?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
asynctask
在API级别30中弃用,请考虑使用Kotlin Coroutines或其他 Kotlin并发实用程序。如果没有asynctask
它将看起来像这样的东西:在
palette.builder
class:in储存库中:
也在
agentdao
标记函数insertagent
insertagent < /code> as <代码>暂停
:AsyncTask
was deprecated in API level 30, consider using Kotlin Coroutines instead or other Kotlin concurrency utilities. WithoutAsyncTask
it will look something like this:In
Palette.Builder
class:In repository:
Also in the
AgentDao
mark functioninsertAgent
assuspend
:如果由于某种原因无法修改调色板的源代码。Builder类,则可以编写这样的暂停适应功能。
sustendCancellableCoroutine
是通过暂停Coroutine并为您直接使用暂停的延续来将基于回调的功能转换为悬挂功能。回调发射时恢复Coroutine,并在恢复之前取消Coroutine,取消工作。然后,您的其他函数可以同步写入,并在必要时使用
withContext
:确保您将标记
AgentDao.InterTagent()
将其标记为suppend
功能,因此您可以在Coroutine中的任何地方致电,而不必担心呼叫线程。上面的代码假定
tobitmap()
是非障碍物。如果阻止它,则应用context()将其包裹在适当的中。
If for some reason you cannot modify the source code of the Palette.Builder class, you could write a suspending adapting function like this.
suspendCancellableCoroutine
is for converting callback-based functions into suspend functions by suspending the coroutine and giving you the suspended continuation to work with directly. Resume the coroutine when the callback fires, and cancel the work if the coroutine is cancelled before it resumed.Then your other function can be written in a synchronous way and use
withContext
where necessary:Make sure you mark
AgentDao.insertAgent()
as asuspend
function so you can call if anywhere in a coroutine without worrying about calling thread.Above code assumes
toBitmap()
is non-blocking. If it blocks, you should wrap it in an appropriatewithContext()
.