What I'm trying to do is the following:
- Load an Agent icon from an API
- Using Palette, determine what is the vibrant swatch
- Set this background RGB color and save it into the database
- Database will be updated, updating the flow and pushing the new updates to the UI
- UI picks it up, which then gets set into a recycler view
However, I'm struggling to get it working in my repository. My function looks like this:
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())
}
}
}
}
}
However, it crashes at runtime on agentDao.insertAgent() because it says it's running the DB operation on the main thread. I also cannot wrap this method within the generate() callback with withContext(Dispatchers.IO) since it's not in a coroutine body.
This is what the Palette.Builder().generate() function looks like in the source code:
@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);
}
So I'm passing it the PaletteAsyncListener which just has one function onGenerated(). I somehow want this method to suspend the coroutine, returning to me the Agent with the updated background. Or somehow to be able to call my DB method agentDao.insertAgent() within this callback off the main thread.
Can I somehow mix and match how the source code is using AsyncTask with my coroutines?