Ich arbeite an einem Projekt, bei dem ausschließlich Multimodulfunktionen nach Ebenenarch verwendet werden. Bedeutet, dass die App in Funktionen unterteilt ist und jede Funktion über eine eigene Benutzeroberfläche, Domäne und Datenschicht verfügt.
Die UI-Schicht hängt von der Domänenschicht ab, bei der es sich um eine reine Kotlin-Bibliothek gemäß dem folgenden Standard handelt. Und die Domänenschicht hat nur Anwendungsfall und Repository (reine Schnittstelle).
Die Datenschicht implementiert dieses Repo, was bedeutet, dass die Datenschicht von der Domänenschicht abhängt. Und die Datenschicht und die UI-Schicht sind Android-Bibliotheken, aber die Domänenschicht ist eine reine Kotlin-Bibliothek, was bedeutet, dass von dort aus keine Andorid-bezogenen Dinge darauf zugreifen können.
Jetzt gibt es in der Datenschicht eine Liste von Bildern in Form einer Bitmap. Aber Bitmap ist Android-Ding, aber die Domänenschicht kann dies nicht haben und kann nicht darauf zugreifen.
So kann die UI-Ebene Bitmap von der Datenschicht über die Domänenschicht erhalten.
Ausschnitt der Ordnerstruktur

Codeausschnitt
Code: Select all
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()
}
}
}
Ich möchte nur eine Möglichkeit schaffen, dass die UI-Ebene eine Bildliste abrufen kann, ohne die Integrität der Domänenebene zu beeinträchtigen. Ich denke darüber nach, ByteArray anstelle von Bitmap zu verwenden und die Datenschicht an die Domänenschicht weiterzugeben. Und von der Domänenschicht zur UI-Schicht. In der Ui-Ebene wird dieses ByteArray in Bitmap rekonstruiert. Ich denke, ist der beste Weg oder nicht?
Wie lässt sich dieses Architekturproblem am besten angehen?
Mobile version