Код: Выделить всё
@Entity(tableName = "files")
data class FileEntity(
@PrimaryKey(autoGenerate = false)
val url: String,
val fileName: String
)
Код: Выделить всё
@Dao
interface FilesDao {
@Query(value = "SELECT * FROM files ORDER BY fileName")
suspend fun getFiles(): List
}
Код: Выделить всё
@Database(entities = [FileEntity::class], version = 1, exportSchema = false)
abstract class AppDatabase : RoomDatabase() {
abstract val filesDao: FilesDao
}
Код: Выделить всё
@Module
@InstallIn(SingletonComponent::class)
object RoomModule {
@Provides
@Singleton
fun provideAppDatabase(
@ApplicationContext context: Context
): AppDatabase = Room.databaseBuilder(
context, AppDatabase::class.java, "app_database"
).build()
@Provides
@Singleton
fun provideFilesDao(
appDatabase: AppDatabase
): FilesDao = appDatabase.filesDao
}
Код: Выделить всё
data class FileModel(
val url: String,
val fileName: String
)
Код: Выделить всё
interface FilesDataSource {
suspend fun getFiles(): List
}
class FilesDataSourceImpl @Inject constructor(
private val filesDao: FilesDao
) : FilesDataSource {
override suspend fun getFiles(): List{
val filesEntity = filesDao.getFiles()
return filesEntity.toFilesModel()
}
private fun List.toFilesModel() = map { fileEntity ->
FileModel(
url = fileEntity.url,
fileName = fileEntity.fileName
)
}
}
Код: Выделить всё
@EntryPoint
@InstallIn(SingletonComponent::class)
interface ContentProviderEntryPoint {
// var appDatabase: AppDatabase
var filesDao: FilesDao
}
Код: Выделить всё
class MyProvider : ContentProvider() {
private val appContext: Context by lazy {
context?.applicationContext ?: throw IllegalStateException()
}
private val files: List by lazy {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context = appContext,
entryPoint = ContentProviderEntryPoint::class.java
)
hiltEntryPoint.filesDao.getFiles() // this is a suspend function and I have no idea how to deal...
}
override fun onCreate(): Boolean {
return true
}
override fun query(
uri: Uri,
projection: Array?,
selection: String?,
selectionArgs: Array?,
sortOrder: String?
): Cursor {
TODO()
}
override fun getType(uri: Uri): String {
TODO()
}
override fun openAssetFile(
uri: Uri,
mode: String
): AssetFileDescriptor? {
TODO()
}
override fun insert(
uri: Uri,
values: ContentValues?
): Uri = throw UnsupportedOperationException()
override fun delete(
uri: Uri,
selection: String?,
selectionArgs: Array?
): Int = throw UnsupportedOperationException()
override fun update(
uri: Uri,
values: ContentValues?,
selection: String?,
selectionArgs: Array?
): Int = throw UnsupportedOperationException()
}
Дополнительно:
Я видел несколько примеров, когда в классе DAO создавалась новая функция (не приостановленная) для возврата курсора. Например:
Код: Выделить всё
@Dao
interface FilesDao {
@Query(value = "SELECT * FROM files")
fun getFilesCursor(): Cursor
// other suspend functions for datasource layer
}
Код: Выделить всё
class MyProvider : ContentProvider() {
private val appContext: Context by lazy {
context?.applicationContext ?: throw IllegalStateException()
}
private val filesCursor: Cursor by lazy {
val hiltEntryPoint = EntryPointAccessors.fromApplication(
context = appContext,
entryPoint = ContentProviderEntryPoint::class.java
)
hiltEntryPoint.filesDao.getFilesCursor()
}
override fun onCreate(): Boolean {
println(filesCursor) // just to see the output, but this throw an IllegalStateException
return true
}
// ...
}
Моя цель с помощью ContentProvider — предоставить стикеры (файлы) для WhatsApp. У меня уже есть рабочая версия приложения, которая считывает контент непосредственно из JSON-файла, следуя той же логике, что и Hilt, проблема в том, что теперь, когда я перехожу на Room который использует приостановленные функции Я не могу справиться с этой ситуацией.
Подробнее здесь: https://stackoverflow.com/questions/733 ... ntprovider
Мобильная версия