From 33b041c31a6f8cc8a1e3ad881042be426380295a Mon Sep 17 00:00:00 2001 From: Sebastian Aigner Date: Wed, 4 Nov 2020 20:56:12 +0100 Subject: [PATCH] ImageViewer: Use Ktor and expect/actual to make common source set pure Kotlin (#51) * Add IDE resolution warning for examples sharing JVM & Android code. * Use Ktor to remove JVM-specific networking code from common source set Fix resolution for Picture class via expect/actual mechanism Co-authored-by: Sebastian Aigner --- examples/imageviewer/common/build.gradle.kts | 4 ++- .../example/imageviewer/model/Picture.kt | 2 +- .../example/imageviewer/utils/Coroutines.kt | 9 ++++++ .../imageviewer/model/ImageRepository.kt | 30 ++++--------------- .../example/imageviewer/model/Miniatures.kt | 9 +++--- .../example/imageviewer/utils/Coroutines.kt | 7 +++++ .../example/imageviewer/utils/Network.kt | 25 +++++++++++----- .../example/imageviewer/model/Picture.kt | 2 +- .../example/imageviewer/utils/Coroutines.kt | 9 ++++++ 9 files changed, 59 insertions(+), 38 deletions(-) create mode 100644 examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/utils/Coroutines.kt create mode 100644 examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Coroutines.kt create mode 100644 examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/Coroutines.kt diff --git a/examples/imageviewer/common/build.gradle.kts b/examples/imageviewer/common/build.gradle.kts index d67363227f..a788a938e6 100755 --- a/examples/imageviewer/common/build.gradle.kts +++ b/examples/imageviewer/common/build.gradle.kts @@ -9,24 +9,26 @@ plugins { kotlin { android() jvm("desktop") - sourceSets { named("commonMain") { dependencies { api(compose.runtime) api(compose.foundation) api(compose.material) + implementation("io.ktor:ktor-client-core:1.4.1") } } named("androidMain") { dependencies { api("androidx.appcompat:appcompat:1.1.0") api("androidx.core:core-ktx:1.3.1") + implementation("io.ktor:ktor-client-cio:1.4.1") } } named("desktopMain") { dependencies { api(compose.desktop.common) + implementation("io.ktor:ktor-client-cio:1.4.1") } } } diff --git a/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/Picture.kt b/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/Picture.kt index 39faf183cb..50a9f33b0d 100755 --- a/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/Picture.kt +++ b/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/model/Picture.kt @@ -2,7 +2,7 @@ package example.imageviewer.model import android.graphics.Bitmap -data class Picture( +actual data class Picture( var source: String = "", var name: String = "", var image: Bitmap, diff --git a/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/utils/Coroutines.kt b/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/utils/Coroutines.kt new file mode 100644 index 0000000000..ab006ef147 --- /dev/null +++ b/examples/imageviewer/common/src/androidMain/kotlin/example/imageviewer/utils/Coroutines.kt @@ -0,0 +1,9 @@ +package example.imageviewer.utils + +import kotlinx.coroutines.CoroutineScope +import kotlin.coroutines.CoroutineContext + +actual fun runBlocking( + context: CoroutineContext, + block: suspend CoroutineScope.() -> T +): T = kotlinx.coroutines.runBlocking(context, block) \ No newline at end of file diff --git a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/ImageRepository.kt b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/ImageRepository.kt index dddcc59159..14178fa238 100755 --- a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/ImageRepository.kt +++ b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/ImageRepository.kt @@ -16,36 +16,18 @@ package example.imageviewer.model import example.imageviewer.core.Repository -import java.io.BufferedReader -import java.io.InputStreamReader -import java.net.HttpURLConnection -import java.net.URL +import example.imageviewer.utils.ktorHttpClient +import example.imageviewer.utils.runBlocking +import io.ktor.client.request.* class ImageRepository( private val httpsURL: String ) : Repository> { override fun get(): MutableList { - val list: MutableList = ArrayList() - try { - val url = URL(httpsURL) - val connection: HttpURLConnection = url.openConnection() as HttpURLConnection - connection.connectTimeout = 5000 - connection.connect() - - val read = BufferedReader(InputStreamReader(connection.inputStream)) - - var line: String? = read.readLine() - while (line != null) { - list.add(line) - line = read.readLine() - } - read.close() - return list - } catch (e: Exception) { - e.printStackTrace() + return runBlocking { + val content = ktorHttpClient.get(httpsURL) + content.lines().toMutableList() } - - return list } } diff --git a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/Miniatures.kt b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/Miniatures.kt index f1bb7e2ac2..4daaca3940 100755 --- a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/Miniatures.kt +++ b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/model/Miniatures.kt @@ -14,20 +14,21 @@ package example.imageviewer.model +expect class Picture class Miniatures( - private var list: MutableList = ArrayList() + private var list: List = emptyList() ) { fun get(index: Int): Picture { return list[index] } fun getMiniatures(): List { - return ArrayList(list) + return list.toList() } fun setMiniatures(list: List) { - this.list = ArrayList(list) + this.list = list.toList() } fun size(): Int { @@ -35,6 +36,6 @@ class Miniatures( } fun clear() { - list = ArrayList() + list = emptyList() } } \ No newline at end of file diff --git a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Coroutines.kt b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Coroutines.kt new file mode 100644 index 0000000000..d35b09543e --- /dev/null +++ b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Coroutines.kt @@ -0,0 +1,7 @@ +package example.imageviewer.utils + +import kotlinx.coroutines.CoroutineScope +import kotlin.coroutines.CoroutineContext +import kotlin.coroutines.EmptyCoroutineContext + +expect fun runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T \ No newline at end of file diff --git a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Network.kt b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Network.kt index d477814b3a..c2d5a23bfa 100755 --- a/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Network.kt +++ b/examples/imageviewer/common/src/commonMain/kotlin/example/imageviewer/utils/Network.kt @@ -14,13 +14,24 @@ package example.imageviewer.utils -import java.net.InetAddress +import io.ktor.client.* +import io.ktor.client.request.* +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.async + +//import java.net.InetAddress fun isInternetAvailable(): Boolean { - return try { - val ipAddress: InetAddress = InetAddress.getByName("google.com") - !ipAddress.equals("") - } catch (e: Exception) { - false + return runBlocking { + try { + ktorHttpClient.head("http://google.com") + true + } catch (e: Exception) { + println(e.message) + false + } } -} \ No newline at end of file +} + +val ktorHttpClient = HttpClient {} \ No newline at end of file diff --git a/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/Picture.kt b/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/Picture.kt index d9afed5bbc..1113afb440 100755 --- a/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/Picture.kt +++ b/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/model/Picture.kt @@ -2,7 +2,7 @@ package example.imageviewer.model import java.awt.image.BufferedImage -data class Picture( +actual data class Picture( var source: String = "", var name: String = "", var image: BufferedImage, diff --git a/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/Coroutines.kt b/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/Coroutines.kt new file mode 100644 index 0000000000..ab006ef147 --- /dev/null +++ b/examples/imageviewer/common/src/desktopMain/kotlin/example/imageviewer/utils/Coroutines.kt @@ -0,0 +1,9 @@ +package example.imageviewer.utils + +import kotlinx.coroutines.CoroutineScope +import kotlin.coroutines.CoroutineContext + +actual fun runBlocking( + context: CoroutineContext, + block: suspend CoroutineScope.() -> T +): T = kotlinx.coroutines.runBlocking(context, block) \ No newline at end of file