gpt4 book ai didi

kotlin-multiplatform - 如何在Multiplatform Ktor 和Coil 之间共享HttpClient?

转载 作者:行者123 更新时间:2023-12-05 03:39:22 35 4
gpt4 key购买 nike

我想使用 Coil 图像库从 api 加载图像,并使用之前设置的相同 cookie。因此,我想对我的 Ktor 网络调用和使用 Coil 加载图像使用相同的 HttpClient。

如何在 Ktor 和 Coil 之间共享同一个 HttpClient?我想,我需要以某种方式调整依赖关系,但我无法解决这个问题。

我在共享模块中的 KtorApiImpl

class KtorApiImpl(log: Kermit) : KtorApi {
val baseUrl = BuildKonfig.baseUrl

// If this is a constructor property, then it gets captured
// inside HttpClient config and freezes this whole class.
@Suppress("CanBePrimaryConstructorProperty")
private val log = log

override val client = HttpClientProvider().getHttpClient().config {
install(JsonFeature) {
serializer = KotlinxSerializer()
}
install(Logging) {
logger = object : Logger {
override fun log(message: String) {
log.v("Network") { message }
}
}

level = LogLevel.INFO
}
}

init {
ensureNeverFrozen()
}

override fun HttpRequestBuilder.apiUrl(path: String) {
url {
takeFrom(baseUrl)
encodedPath = path
}
}

override fun HttpRequestBuilder.json() {
contentType(ContentType.Application.Json)
}

androidMain 中的实际 HttpClientProvider

var cookieJar: CookieJar = object : CookieJar {
private val cookieStore: HashMap<String, List<Cookie>> = HashMap()

override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
cookieStore[url.host] = cookies
}

override fun loadForRequest(url: HttpUrl): List<Cookie> {
val cookies = cookieStore[url.host]
return cookies ?: ArrayList()
}
}


actual class HttpClientProvider actual constructor() {
actual fun getHttpClient(): HttpClient {
return HttpClient(OkHttp) {
engine {
preconfigured = getOkHttpClient()
}
}
}
}

private fun getOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.cookieJar(cookieJar)
.build()
}

androidApp 中的 ImageLoaderFactory - 如何使用 HttpClient 而不是创建新的?

class CoilImageLoaderFactory(private val context: Context) : ImageLoaderFactory {
override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(context)
.availableMemoryPercentage(0.25) // Use 25% of the application's available memory.
.crossfade(true) // Show a short crossfade when loading images from network or disk.
.componentRegistry {
add(ByteArrayFetcher())
}
.okHttpClient {
// Create a disk cache with "unlimited" size. Don't do this in production.
// To create the an optimized Coil disk cache, use CoilUtils.createDefaultCache(context).
val cacheDirectory = File(context.filesDir, "image_cache").apply { mkdirs() }
val cache = Cache(cacheDirectory, Long.MAX_VALUE)

// Lazily create the OkHttpClient that is used for network operations.
OkHttpClient.Builder()
.cache(cache)
.build()
}
.build()
}

}

androidApp 中的 Koin 依赖

@Suppress("unused")
class MainApp : Application() {

override fun onCreate() {
super.onCreate()
initKoin(
module {
single<Context> { this@MainApp }
single<AppInfo> { AndroidAppInfo }
single { CoilImageLoaderFactory(get<Context>())}
single<SharedPreferences> {
get<Context>().getSharedPreferences("MAIN_SETTINGS", Context.MODE_PRIVATE)
}
single {
{ Log.i("Startup", "Hello from Android/Kotlin!") }
}
}
)
}
}

然后是主事件

class MainActivity : AppCompatActivity() { 
val loaderFactory: CoilImageLoaderFactory by inject()

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
CompositionLocalProvider(LocalImageLoader provides loaderFactory.newImageLoader()) {
MainTheme {
ProvideWindowInsets {
Surface {
MainScreen()
}
}
}
}
}
}
}

最佳答案

我使用 ImageLoader 访问了 OkHttpClient

class CoilImageLoaderFactory(private val context: Context) : ImageLoaderFactory, KoinComponent {
val ktorApiImpl: KtorApi by inject()

override fun newImageLoader(): ImageLoader {
return ImageLoader.Builder(context)
.componentRegistry {
add(ByteArrayFetcher())
}
.okHttpClient {
val config = ktorApiImpl.client.engine.config as OkHttpConfig
config.preconfigured as OkHttpClient

}


.build()
}

关于kotlin-multiplatform - 如何在Multiplatform Ktor 和Coil 之间共享HttpClient?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68592479/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com