Я работаю над проектом Android, который строго следует многомодульной многоуровневой архитектуре на основе функций. Приложение разделено на функции, и каждая функция имеет свои собственные уровни пользовательского интерфейса, домена и данных.
Уровень пользовательского интерфейса зависит от уровня домена, который содержит только варианты использования и интерфейсы репозитория. Уровень домена реализован как чистый модуль Kotlin и не ссылается ни на какие классы платформы Android.
Уровень данных реализует эти интерфейсы репозитория, поэтому он зависит от уровня домена. И уровень пользовательского интерфейса, и уровень данных являются модулями библиотеки Android.
Проблема в том, что уровень данных загружает изображения из локального хранилища с помощью API MediaStore и представляет их в виде растрового изображения. Поскольку Bitmap является классом платформы Android, на него нельзя ссылаться на уровне домена при этой настройке.
Фрагмент структуры папок

Код фрагмент
Код: Выделить всё
private val semaphore = Semaphore(2) // it required due to i do async operation and without it MediaMetaData throw error and crash app.
suspend fun getImageVideoThumbnail(
context: Context,
uri: Uri,
size: Size = Size(200, 200)
): Bitmap? = withContext(Dispatchers.IO) {
var bitmap: Bitmap? = null
val cr = context.contentResolver
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
bitmap = cr.loadThumbnail(uri, size, null)
} else {
cr.query(uri, null, null, null, null)?.use { cursor ->
val idCol = cursor.getColumnIndexOrThrow(MediaStore.Video.Media._ID)
while (cursor.moveToNext()) {
val id = cursor.getLong(idCol)
bitmap = MediaStore.Video.Thumbnails.getThumbnail(
cr,
id,
MediaStore.Video.Thumbnails.MINI_KIND,
null
)
break
}
}
}
bitmap
} catch (e: Exception) {
// e.printStackTrace()
getFrame(context , uri , size)
}
}
suspend fun getFrame(context: Context, uri: Uri , size : Size): Bitmap? = withContext(Dispatchers.IO) {
semaphore.withPermit {
val retriever = MediaMetadataRetriever()
try {
retriever.setDataSource(context, uri)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
retriever.getScaledFrameAtTime(
0,
MediaMetadataRetriever.OPTION_CLOSEST_SYNC,
size.width, size.height
)
} else {
retriever.frameAtTime?.let { src ->
src.scale(size.width, size.height).also { src.recycle() }
}
}
} catch (e: Exception) {
null
} finally {
retriever.release()
}
}
}
Мне нужен практичный и удобный способ предоставления данных изображения из уровня данных на уровень пользовательского интерфейса в проекте только для Android, который соответствует чистой архитектуре, где уровень домена реализован как чистый модуль Kotlin.
В частности, я хочу ясности относительно того, должен ли уровень домена:
- открывать классы данных платформы Android, такие как Растровое изображение или
- предоставляет данные, независимые от платформы (например, пути к файлам или URI), и позволяет уровню пользовательского интерфейса обрабатывать декодирование изображений.
Подробнее здесь: https://stackoverflow.com/questions/798 ... ule-androi
Мобильная версия