├── app ├── .gitignore ├── src │ └── main │ │ ├── res │ │ ├── values │ │ │ ├── strings.xml │ │ │ ├── dimens.xml │ │ │ ├── colors.xml │ │ │ └── styles.xml │ │ ├── mipmap-hdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ │ ├── ic_launcher.png │ │ │ └── ic_launcher_round.png │ │ ├── mipmap-anydpi-v26 │ │ │ ├── ic_launcher.xml │ │ │ └── ic_launcher_round.xml │ │ ├── layout │ │ │ ├── activity_main.xml │ │ │ └── fragment_main.xml │ │ ├── drawable-v24 │ │ │ └── ic_launcher_foreground.xml │ │ └── drawable │ │ │ └── ic_launcher_background.xml │ │ ├── java │ │ └── com │ │ │ └── kine │ │ │ └── test │ │ │ ├── ConfigUtils.kt │ │ │ ├── model │ │ │ ├── Post.kt │ │ │ ├── CreateUserResponse.kt │ │ │ ├── User.kt │ │ │ └── UserListResponse.kt │ │ │ ├── MainActivity.kt │ │ │ └── TestFragment.kt │ │ └── AndroidManifest.xml ├── proguard-rules.pro └── build.gradle ├── kine ├── .gitignore ├── gradle.properties ├── src │ └── main │ │ └── java │ │ └── com │ │ └── kine │ │ ├── request │ │ ├── SimpleRequestBody.kt │ │ ├── MultiPartBody.kt │ │ ├── MultiPartStringBody.kt │ │ ├── MultiPartFileBody.kt │ │ ├── RequestDataFields.kt │ │ ├── StringRequestBody.kt │ │ ├── ContentType.kt │ │ ├── RequestBody.kt │ │ ├── RequestFields.kt │ │ ├── UploadRequestFields.kt │ │ ├── DownloadRequestFields.kt │ │ ├── EncodedRequestBody.kt │ │ └── MultiPartRequestBody.kt │ │ ├── connections │ │ └── ConnectionChecker.kt │ │ ├── interceptors │ │ ├── PreNetworkKineInterceptor.kt │ │ └── KineInterceptor.kt │ │ ├── cache │ │ ├── KineCache.kt │ │ └── KineCacheControl.kt │ │ ├── timer │ │ ├── Timer.kt │ │ ├── TimerManager.kt │ │ └── SimpleTimer.kt │ │ ├── exceptions │ │ ├── NoInternetException.kt │ │ ├── TimeoutException.kt │ │ ├── UnknownException.kt │ │ ├── NoClientFoundException.kt │ │ ├── NoConverterFoundException.kt │ │ ├── NullResponseException.kt │ │ ├── NullResponseBodyException.kt │ │ ├── OfflineException.kt │ │ ├── UrlMalformedException.kt │ │ ├── HttpStatusCodeException.kt │ │ ├── MisMatchClientException.kt │ │ ├── MisMatchConverterException.kt │ │ └── ParseException.kt │ │ ├── response │ │ ├── KineResponseListener.kt │ │ ├── KineError.kt │ │ └── KineResponse.kt │ │ ├── executor │ │ ├── CallbackExecutor.kt │ │ ├── PriorityRunnable.kt │ │ ├── PriorityThreadFactory.kt │ │ ├── KineExecutorManager.kt │ │ ├── ExecutorSupplier.kt │ │ ├── PriorityThreadPoolExecutor.kt │ │ └── DefaultPriorityExecutorSupplier.kt │ │ ├── extensions │ │ ├── File.kt │ │ ├── Any.kt │ │ ├── List.kt │ │ ├── Class.kt │ │ └── Url.kt │ │ ├── internal │ │ ├── DefaultKineClass.kt │ │ ├── IRequestManager.kt │ │ └── KineClass.kt │ │ ├── converters │ │ ├── Converter.kt │ │ ├── FileDownloadConverter.kt │ │ └── RawResponseConverter.kt │ │ ├── client │ │ └── KineClient.kt │ │ ├── log │ │ ├── JavaLog.kt │ │ ├── Log.kt │ │ ├── LogLevel.kt │ │ └── Logger.kt │ │ ├── policies │ │ ├── Priority.kt │ │ ├── RetryPolicy.kt │ │ └── DefaultRetryPolicy.kt │ │ └── Kine.kt └── build.gradle ├── kine-gson ├── .gitignore ├── gradle.properties ├── src │ └── main │ │ └── java │ │ └── com │ │ └── kine │ │ └── converters │ │ ├── GsonConverter.kt │ │ └── extensions │ │ └── Gson.kt └── build.gradle ├── kine-json ├── .gitignore ├── build.gradle └── src │ ├── main │ └── java │ │ └── com │ │ └── kine │ │ ├── converters │ │ └── JsonConverter.kt │ │ └── extensions │ │ └── Url.kt │ └── test │ └── java │ └── com │ └── kine │ └── JsonApiTest.kt ├── kine-moshi ├── .gitignore ├── gradle.properties ├── src │ └── main │ │ └── java │ │ └── com │ │ └── kine │ │ └── converters │ │ ├── extensions │ │ └── Moshi.kt │ │ └── MoshiConverter.kt └── build.gradle ├── kine-okhttp ├── .gitignore ├── gradle.properties ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── kine │ │ │ ├── converters │ │ │ └── OkioConverter.kt │ │ │ └── client │ │ │ ├── FileProgressRequestBody.kt │ │ │ └── extensions │ │ │ └── Extensions.kt │ └── test │ │ └── java │ │ └── com │ │ └── kine │ │ └── client │ │ ├── OkHttpGetTest.kt │ │ ├── OkHttpHeadTest.kt │ │ ├── OkHttpPutTest.kt │ │ ├── OkHttpPostTest.kt │ │ ├── OkHttpPatchTest.kt │ │ └── OkHttpDeleteTest.kt └── build.gradle ├── kine-android ├── .gitignore ├── consumer-rules.pro ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── kine │ │ └── android │ │ ├── request │ │ └── JsonRequestBody.kt │ │ ├── connections │ │ ├── SimpleConnectionChecker.kt │ │ └── Utils.kt │ │ ├── timer │ │ └── AndroidTimer.kt │ │ ├── executor │ │ ├── PriorityThreadFactory.kt │ │ ├── MainThreadExecutor.kt │ │ └── AndroidPriorityExecutorSupplier.kt │ │ ├── log │ │ └── Log.kt │ │ ├── converters │ │ └── JsonConverter.kt │ │ ├── cache │ │ └── Cache.kt │ │ └── extensions │ │ └── Url.kt ├── proguard-rules.pro └── build.gradle ├── kine-coroutine ├── .gitignore ├── gradle.properties ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── kine │ └── coroutine │ └── Coroutine.kt ├── kine-imageloader ├── .gitignore ├── consumer-rules.pro ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── kine │ │ └── imageloader │ │ ├── interceptors │ │ └── BitmapCacheInterceptor.kt │ │ ├── BitmapKineClass.kt │ │ ├── converter │ │ └── BitmapConverter.kt │ │ ├── policies │ │ └── MemoryPolicy.kt │ │ ├── cache │ │ └── MemoryCache.kt │ │ └── extensions │ │ └── Imageloader.kt ├── proguard-rules.pro └── build.gradle ├── kine-livedata ├── .gitignore ├── consumer-rules.pro ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── kine │ │ └── android │ │ └── LiveData.kt ├── proguard-rules.pro └── build.gradle ├── kine-rxjava2 ├── .gitignore ├── consumer-rules.pro ├── gradle.properties ├── src │ └── main │ │ ├── AndroidManifest.xml │ │ └── java │ │ └── com │ │ └── kine │ │ └── rxnetworking │ │ └── RxJava2.kt ├── build.gradle └── proguard-rules.pro ├── kine-rxjava3 ├── .gitignore ├── gradle.properties ├── build.gradle └── src │ └── main │ └── java │ └── com │ └── kine │ └── rxjava3 │ └── RxJava3.kt ├── kine-okhttplegacy ├── .gitignore ├── gradle.properties ├── src │ ├── main │ │ └── java │ │ │ └── com │ │ │ └── kine │ │ │ ├── converters │ │ │ └── OkioConverter.kt │ │ │ └── client │ │ │ ├── FileProgressRequestBody.kt │ │ │ └── extensions │ │ │ └── Extensions.kt │ └── test │ │ └── java │ │ └── com │ │ └── kine │ │ └── client │ │ ├── OkHttpGetTest.kt │ │ ├── OkHttpHeadTest.kt │ │ ├── OkHttpPutTest.kt │ │ ├── OkHttpPostTest.kt │ │ ├── OkHttpPatchTest.kt │ │ └── OkHttpDeleteTest.kt └── build.gradle ├── logo.png ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── settings.gradle ├── .github └── workflows │ └── main_release.yml ├── bintray.gradle ├── gradle.properties ├── CODE_OF_CONDUCT.md ├── publish.gradle └── publish1.gradle /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-gson/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-json/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-moshi/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-okhttp/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine/gradle.properties: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /kine-android/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-android/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kine-coroutine/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-imageloader/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-livedata/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-livedata/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kine-rxjava2/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-rxjava2/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kine-rxjava3/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-imageloader/consumer-rules.pro: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /kine-okhttplegacy/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /kine-gson/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=2.8.6.0 2 | -------------------------------------------------------------------------------- /kine-livedata/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=2.2.0.0 2 | -------------------------------------------------------------------------------- /kine-moshi/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=1.9.3.0 2 | -------------------------------------------------------------------------------- /kine-okhttp/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=4.8.1.0 2 | -------------------------------------------------------------------------------- /kine-rxjava2/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=2.2.19.0 2 | -------------------------------------------------------------------------------- /kine-rxjava3/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=3.0.6.0 2 | -------------------------------------------------------------------------------- /kine-coroutine/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=1.3.8.0 2 | -------------------------------------------------------------------------------- /kine-okhttplegacy/gradle.properties: -------------------------------------------------------------------------------- 1 | libraryVersion=3.12.12.0 2 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/logo.png -------------------------------------------------------------------------------- /kine-livedata/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Kine 3 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/SimpleRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | class SimpleRequestBody:RequestBody() -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-hdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-mdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/MultiPartBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | open class MultiPartBody (val value:T,val contentType:String?) -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TechDev009/Kine/HEAD/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/ConfigUtils.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test 2 | 3 | object ConfigUtils { 4 | const val dummyBaseUrl = "https://reqres.in/api/" 5 | } -------------------------------------------------------------------------------- /kine-android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/connections/ConnectionChecker.kt: -------------------------------------------------------------------------------- 1 | package com.kine.connections 2 | 3 | interface ConnectionChecker { 4 | fun isConnected(): Boolean 5 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/interceptors/PreNetworkKineInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.interceptors 2 | 3 | abstract class PreNetworkKineInterceptor:KineInterceptor() -------------------------------------------------------------------------------- /kine-imageloader/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /kine-imageloader/src/main/java/com/kine/imageloader/interceptors/BitmapCacheInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.imageloader.interceptors 2 | 3 | class BitmapCacheInterceptor { 4 | } -------------------------------------------------------------------------------- /kine-rxjava2/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | / 5 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/MultiPartStringBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | class MultiPartStringBody(value:String, contentType:String?=null): MultiPartBody(value, contentType) -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/cache/KineCache.kt: -------------------------------------------------------------------------------- 1 | package com.kine.cache 2 | 3 | import java.io.File 4 | 5 | /** 6 | * interface for caching response. 7 | */ 8 | class KineCache (val file: File, val cacheSize:Long) 9 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/MultiPartFileBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import java.io.File 4 | 5 | class MultiPartFileBody(value: File, contentType:String?=null): MultiPartBody(value, contentType) -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/timer/Timer.kt: -------------------------------------------------------------------------------- 1 | package com.kine.timer 2 | 3 | interface Timer { 4 | 5 | fun clone():Timer 6 | 7 | fun start() 8 | 9 | fun stop():Long 10 | 11 | fun time():Long 12 | } -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10dp 4 | 10dp 5 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/NoInternetException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class NoInternetException(msg: String?="Please check your internet connection"):Exception(msg) 6 | { 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/response/KineResponseListener.kt: -------------------------------------------------------------------------------- 1 | @file:JvmName("ResponseListenerKt") 2 | 3 | package com.kine.response 4 | 5 | 6 | typealias OnSuccess = ((KineResponse) -> Unit) 7 | 8 | typealias OnError = ((KineError) -> Unit) -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #6200EE 4 | #3700B3 5 | #03DAC5 6 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/CallbackExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | import java.util.concurrent.Executor 4 | 5 | class CallbackExecutor:Executor { 6 | override fun execute(command: Runnable) { 7 | command.run() 8 | } 9 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/extensions/File.kt: -------------------------------------------------------------------------------- 1 | package com.kine.extensions 2 | 3 | import java.net.URLConnection 4 | 5 | fun String.getMimeType(): String { 6 | return URLConnection.getFileNameMap().getContentTypeFor(this)?:"application/octet-stream" 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/TimeoutException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class TimeoutException (msg: String?="timeout error"): Exception(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/UnknownException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class UnknownException(msg: String?="unknown error"): Exception(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/NoClientFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | class NoClientFoundException(msg: String?= "no kineClient found" + 4 | "please set at least one client through Kine class or individual request") : IllegalStateException(msg) -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Aug 19 00:29:13 IST 2020 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip 7 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/NoConverterFoundException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | class NoConverterFoundException(msg: String?="no converter specified, please set at least one converter" 4 | + "through Kine class or through individual request") : IllegalStateException(msg) -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/extensions/Any.kt: -------------------------------------------------------------------------------- 1 | package com.kine.extensions 2 | 3 | import com.kine.executor.KineExecutorManager 4 | 5 | 6 | fun Any.onCallbackThread(action: () -> Unit) { 7 | KineExecutorManager.executorSupplier.forCallbackTasks().execute { 8 | action() 9 | } 10 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/internal/DefaultKineClass.kt: -------------------------------------------------------------------------------- 1 | package com.kine.internal 2 | 3 | class DefaultKineClass(clazz: Class) : KineClass(clazz) { 4 | 5 | override fun isAssignableFrom(t: Class<*>): Boolean { 6 | return clazz.isAssignableFrom(t).apply { 7 | } 8 | } 9 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/NullResponseException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class NullResponseException(msg: String?="null response from client"): NullPointerException(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/converters/Converter.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters 2 | 3 | import com.kine.request.RequestFields 4 | import kotlin.jvm.Throws 5 | 6 | interface Converter { 7 | @Throws(Throwable::class) 8 | fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? 9 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/NullResponseBodyException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class NullResponseBodyException(msg: String?="null response from server"): NullPointerException(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/OfflineException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class OfflineException(msg: String?="request called with offline only mode but no cached response found"): Exception(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/UrlMalformedException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class UrlMalformedException(msg: String?="url is not properly formatted or not a url at all"): NullPointerException(msg) { 6 | constructor(e: Exception):this(e.localizedMessage?:e.message) 7 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/timer/TimerManager.kt: -------------------------------------------------------------------------------- 1 | package com.kine.timer 2 | 3 | object TimerManager { 4 | private var timer: Timer = SimpleTimer() 5 | 6 | fun start(): Timer { 7 | return timer.clone().apply { start()} 8 | } 9 | 10 | fun time(): Long { 11 | return timer.time() 12 | } 13 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/HttpStatusCodeException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class HttpStatusCodeException(msg: String?="unsuccessful status code from server ",code:Int): Exception(msg+code) { 6 | constructor(e: Exception,code:Int):this(e.localizedMessage?:e.message,code) 7 | } -------------------------------------------------------------------------------- /app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/request/JsonRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.request 2 | 3 | import com.kine.request.ContentType 4 | import com.kine.request.StringRequestBody 5 | import org.json.JSONObject 6 | 7 | class JsonRequestBody(jsonObject: JSONObject?):StringRequestBody(jsonObject?.toString(),ContentType.JSON.toString()) -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/model/Post.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test.model 2 | 3 | import com.google.gson.annotations.SerializedName 4 | 5 | data class Post ( 6 | 7 | @SerializedName("userId") val userId : Int, 8 | @SerializedName("id") val id : Int, 9 | @SerializedName("title") val title : String, 10 | @SerializedName("body") val body : String 11 | ) -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/MisMatchClientException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | class MisMatchClientException(msg: String?= "no kineClient found that can handle this type of request, " + 4 | "please set at least one client that can " + 5 | "handle this type of request" + " " + "through Kine class or individual request") : IllegalStateException(msg) -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/PriorityRunnable.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | import com.kine.policies.Priority 4 | 5 | open class PriorityRunnable(private val priority: Priority) : Runnable { 6 | override fun run() { 7 | // nothing to do here. 8 | } 9 | 10 | fun getPriority(): Priority { 11 | return priority 12 | } 13 | 14 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/PriorityThreadFactory.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | 4 | import java.util.concurrent.ThreadFactory 5 | 6 | class PriorityThreadFactory(private val threadPriority: Int) : ThreadFactory { 7 | override fun newThread(runnable: Runnable): Thread { 8 | return Thread(runnable).apply { priority = threadPriority } 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/interceptors/KineInterceptor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.interceptors 2 | 3 | import com.kine.request.RequestFields 4 | import com.kine.response.KineResponse 5 | import kotlin.jvm.Throws 6 | 7 | abstract class KineInterceptor { 8 | @Throws(Throwable::class) 9 | abstract fun intercept(requestFields: RequestFields, clazz: Class):KineResponse? 10 | 11 | } -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':kine-json' 2 | include ':kine-livedata' 3 | include ':kine-okhttplegacy' 4 | include ':kine-rxjava3' 5 | include ':kine-coroutine' 6 | include ':kine-rxjava2' 7 | include ':kine-moshi' 8 | include ':kine-okhttp' 9 | include ':kine-imageloader' 10 | include ':kine-android' 11 | include ':kine-gson' 12 | include ':kine' 13 | include ':app' 14 | rootProject.name = "Kine" -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/RequestDataFields.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | 4 | /** 5 | * An RequestDataFields. This class is used to hold request param information associated with a single HTTP request. 6 | */ 7 | data class RequestDataFields(val reqTAG: String, var url: String, val method: Int, 8 | val body : RequestBody, val headers: HashMap?) -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/connections/SimpleConnectionChecker.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.connections 2 | 3 | import android.content.Context 4 | import com.kine.connections.ConnectionChecker 5 | 6 | class SimpleConnectionChecker(private val context: Context) : ConnectionChecker { 7 | override fun isConnected(): Boolean { 8 | return Utils.isConnected(context) 9 | } 10 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/StringRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | open class StringRequestBody(var body:String?=null, mediaType:String = ContentType.JSON.toString()):RequestBody(mediaType) { 4 | 5 | fun setBody(body: String? = null, mediaType: String = ContentType.JSON.toString()) { 6 | 7 | this.body = body 8 | this.mediaType = mediaType 9 | } 10 | 11 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/MisMatchConverterException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.IllegalArgumentException 4 | 5 | class MisMatchConverterException(msg:String= "the converter passed cannot handle " + "this type of response returned by this request" + 6 | ", please set a converter that can " + "handle this type of response" + 7 | " " + "through converter() method"):IllegalArgumentException(msg) -------------------------------------------------------------------------------- /kine-imageloader/src/main/java/com/kine/imageloader/BitmapKineClass.kt: -------------------------------------------------------------------------------- 1 | package com.kine.imageloader 2 | 3 | import android.graphics.Bitmap 4 | import com.kine.internal.KineClass 5 | 6 | class BitmapKineClass : KineClass(Bitmap::class.java) { 7 | override fun isAssignableFrom(t: Class<*>): Boolean { 8 | return t.isAssignableFrom(ByteArray::class.java) || t.isAssignableFrom(Bitmap::class.java) 9 | } 10 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/extensions/List.kt: -------------------------------------------------------------------------------- 1 | package com.kine.extensions 2 | 3 | /** 4 | * Returns the first element matching the given [predicate], or `null` if element was not found. 5 | */ 6 | public inline fun Iterable.firstResultOrNull(predicate: (T) -> F?): F? { 7 | for (element in this) { 8 | (predicate(element))?.apply { 9 | return this 10 | } 11 | } 12 | return null 13 | } -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | -------------------------------------------------------------------------------- /kine-moshi/src/main/java/com/kine/converters/extensions/Moshi.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters.extensions 2 | 3 | 4 | import com.squareup.moshi.Moshi 5 | import java.lang.reflect.Type 6 | 7 | inline fun Moshi.fromJsonArray(response: String,clazz: Class): List? { 8 | val type: Type = com.squareup.moshi.Types.newParameterizedType(MutableList::class.java, clazz) 9 | return this.adapter>(type).fromJson(response) 10 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/exceptions/ParseException.kt: -------------------------------------------------------------------------------- 1 | package com.kine.exceptions 2 | 3 | import java.lang.Exception 4 | 5 | class ParseException( 6 | msg: String? = "Parsing response failed,check if your specified converter can handle" + 7 | "the response type and if not set a converter that can handle the needed response type" 8 | ) : Exception(msg) { 9 | constructor(e: Throwable) : this(e.localizedMessage ?: e.message) 10 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/internal/IRequestManager.kt: -------------------------------------------------------------------------------- 1 | 2 | package com.kine.internal 3 | 4 | import com.kine.request.RequestFields 5 | import com.kine.response.KineResponse 6 | 7 | /** 8 | * abstract internal class that takes care of caching , parsing and check other params for a request 9 | */ 10 | internal interface IRequestManager { 11 | 12 | fun executeRequest(requestFields: RequestFields, clazz: KineClass):KineResponse? 13 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/ContentType.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | /** 4 | * Helper class for content-type(media-type). 5 | */ 6 | 7 | enum class ContentType(private val value:String) { 8 | JSON("application/json; charset=utf-8"), STRING("text/plain; charset=utf-8"), 9 | ENCODED("application/x-www-form-urlencoded"),MULTIPART_FORM("multipart/form-data"); 10 | 11 | override fun toString(): String { 12 | return value 13 | } 14 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/extensions/Class.kt: -------------------------------------------------------------------------------- 1 | package com.kine.extensions 2 | 3 | internal fun String.getClassInstance(default:F): T { 4 | return this.getClassInstanceOrNull()?:default 5 | } 6 | @Suppress("UNCHECKED_CAST") 7 | internal fun String.getClassInstanceOrNull(): T? { 8 | return try { 9 | Class.forName(this).newInstance() as T 10 | }catch (exception: ClassNotFoundException) { 11 | // exception.printStackTrace() 12 | null 13 | } 14 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/timer/SimpleTimer.kt: -------------------------------------------------------------------------------- 1 | package com.kine.timer 2 | 3 | class SimpleTimer:Timer { 4 | var time:Long=0 5 | override fun clone(): Timer { 6 | return SimpleTimer() 7 | } 8 | 9 | override fun start() { 10 | time = System.currentTimeMillis() 11 | } 12 | 13 | override fun stop(): Long { 14 | return System.currentTimeMillis() - time 15 | } 16 | 17 | override fun time(): Long { 18 | return System.currentTimeMillis() 19 | } 20 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/cache/KineCacheControl.kt: -------------------------------------------------------------------------------- 1 | package com.kine.cache 2 | 3 | import java.util.concurrent.TimeUnit 4 | 5 | class KineCacheControl(var networkPolicy:Int = NO_CACHE_CONTROL, val cacheMaxAge:Int=0, val timeUnit: TimeUnit){ 6 | companion object{ 7 | const val NO_CACHE_CONTROL = 0 8 | const val FORCE_CACHE = 1 9 | const val FORCE_NETWORK = 2 10 | const val NO_CACHE = 3 11 | const val NO_STORE = 4 12 | const val CACHE_FOR_TIME =5 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/converters/FileDownloadConverter.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters 2 | 3 | import com.kine.request.RequestFields 4 | import java.io.File 5 | 6 | 7 | class FileDownloadConverter : Converter { 8 | @Suppress("UNCHECKED_CAST") 9 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 10 | if (clazz.isAssignableFrom(File::class.java) && response is File) { 11 | return response as J 12 | } 13 | return null 14 | } 15 | 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | 6 | class MainActivity : AppCompatActivity() { 7 | override fun onCreate(savedInstanceState: Bundle?) { 8 | super.onCreate(savedInstanceState) 9 | setContentView(R.layout.activity_main) 10 | supportFragmentManager.beginTransaction().replace( 11 | R.id.container, 12 | TestFragment() 13 | ).commit() 14 | 15 | } 16 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/KineExecutorManager.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | import com.kine.extensions.getClassInstance 4 | 5 | 6 | object KineExecutorManager { 7 | val executorSupplier: ExecutorSupplier = getDefaultExecutorSupplier() 8 | private const val androidExecutorClass = "com.kine.android.executor.AndroidPriorityExecutorSupplier" 9 | private fun getDefaultExecutorSupplier(): ExecutorSupplier { 10 | return androidExecutorClass.getClassInstance(DefaultPriorityExecutorSupplier()) 11 | } 12 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/client/KineClient.kt: -------------------------------------------------------------------------------- 1 | package com.kine.client 2 | 3 | import com.kine.request.RequestFields 4 | import com.kine.response.KineResponse 5 | 6 | /** 7 | * kineClient for making the actual HTTP request to server. 8 | */ 9 | abstract class KineClient constructor(){ 10 | 11 | abstract fun canHandleRequest(url: String, method: Int): Boolean 12 | 13 | @Throws(Throwable::class) 14 | abstract fun execute(requestFields: RequestFields, clazz: Class): KineResponse 15 | 16 | abstract fun cancelAllRequests(tag: String?=null) 17 | 18 | } -------------------------------------------------------------------------------- /kine-gson/src/main/java/com/kine/converters/GsonConverter.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters 2 | 3 | import com.google.gson.Gson 4 | import com.kine.request.RequestFields 5 | 6 | class GsonConverter(private var gson: Gson = Gson()) : Converter { 7 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 8 | return when (response) { 9 | is String -> { 10 | gson.fromJson(response, clazz) 11 | } 12 | else -> { 13 | null 14 | } 15 | } 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /kine/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine' 6 | PUBLISH_VERSION = '1.0.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 13 | dependencies { 14 | implementation fileTree(dir: "libs", include: ["*.jar"]) 15 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 16 | } 17 | -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/timer/AndroidTimer.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.timer 2 | 3 | import android.os.SystemClock 4 | import com.kine.timer.Timer 5 | 6 | class AndroidTimer :Timer{ 7 | var time:Long=0 8 | override fun clone(): Timer { 9 | return AndroidTimer() 10 | } 11 | 12 | override fun start() { 13 | time = SystemClock.elapsedRealtime() 14 | } 15 | 16 | override fun stop(): Long { 17 | return SystemClock.elapsedRealtime() - time 18 | } 19 | 20 | override fun time(): Long { 21 | return SystemClock.elapsedRealtime() 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /kine-moshi/src/main/java/com/kine/converters/MoshiConverter.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters 2 | 3 | import com.kine.request.RequestFields 4 | import com.squareup.moshi.Moshi 5 | 6 | 7 | class MoshiConverter(private var moshi: Moshi = Moshi.Builder().build()) : Converter { 8 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 9 | 10 | return when (response) { 11 | is String -> { 12 | moshi.adapter(clazz).fromJson(response) 13 | } 14 | else -> { 15 | null 16 | } 17 | } 18 | } 19 | 20 | } -------------------------------------------------------------------------------- /kine-gson/src/main/java/com/kine/converters/extensions/Gson.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters.extensions 2 | 3 | import com.google.gson.Gson 4 | import com.google.gson.reflect.TypeToken 5 | import java.lang.reflect.Type 6 | import java.util.ArrayList 7 | 8 | inline fun Gson.fromJsonArray(response: String):ArrayList{ 9 | val listType = object : TypeToken?>() {}.type 10 | return this.fromJson(response, listType) 11 | } 12 | fun Gson.getArrayType(): Type { 13 | return object : TypeToken>() {}.type 14 | } 15 | fun J.getGsonArrayType(): Type { 16 | return object : TypeToken>() {}.type 17 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/model/CreateUserResponse.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test.model 2 | 3 | import com.google.gson.annotations.Expose 4 | import com.google.gson.annotations.SerializedName 5 | import com.squareup.moshi.JsonClass 6 | 7 | @JsonClass(generateAdapter = true) 8 | class CreateUserResponse { 9 | @SerializedName("name") 10 | @Expose 11 | var name: String? = null 12 | 13 | @SerializedName("job") 14 | @Expose 15 | var job: String? = null 16 | 17 | @SerializedName("id") 18 | @Expose 19 | var id: String? = null 20 | 21 | @SerializedName("createdAt") 22 | @Expose 23 | var createdAt: String? = null 24 | 25 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/internal/KineClass.kt: -------------------------------------------------------------------------------- 1 | package com.kine.internal 2 | 3 | 4 | /** 5 | * Helper class for checking generic instance type . 6 | */ 7 | open class KineClass(val clazz: Class) { 8 | companion object { 9 | inline operator fun invoke() = 10 | KineClass(T::class.java) 11 | } 12 | 13 | open fun isAssignableFrom(t: Any): Boolean { 14 | return isAssignableFrom(t.javaClass) 15 | } 16 | open fun isAssignableFrom(t: Class<*>): Boolean { 17 | return clazz.isAssignableFrom(t).apply { 18 | println(if (this) "Correct type" else "Wrong type") 19 | } 20 | } 21 | } -------------------------------------------------------------------------------- /kine-livedata/src/main/java/com/kine/android/LiveData.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import com.kine.KineRequest 5 | 6 | 7 | fun KineRequest.RequestOptionsBuilder.responseAs(clazz: Class, liveData:MutableLiveData) { 8 | return build().execute(clazz,onSuccess = { response-> 9 | liveData.value = response.body 10 | },onError = {e->}) 11 | } 12 | 13 | fun KineRequest.RequestOptionsBuilder.responseBackgroundAs(clazz: Class, liveData:MutableLiveData) { 14 | val response = build().execute(clazz) 15 | if(response?.body!=null) { 16 | liveData.postValue(response.body) 17 | } 18 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/ExecutorSupplier.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | import java.util.concurrent.Executor 4 | import java.util.concurrent.ThreadPoolExecutor 5 | 6 | interface ExecutorSupplier { 7 | /* 8 | * returns the thread pool executor for networking task 9 | */ 10 | fun forNetworkTasks(): ThreadPoolExecutor 11 | 12 | /* 13 | * returns the thread pool executor for light weight background task like parsing 14 | */ 15 | fun forParsingTasks(): ThreadPoolExecutor 16 | 17 | /* 18 | * returns the thread pool executor for executing callback on (Main Thread in Android case) 19 | */ 20 | fun forCallbackTasks(): Executor 21 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/RequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | 4 | /** 5 | * This class is used to hold requestBody information associated with a single HTTP request. 6 | * 7 | */ 8 | abstract class RequestBody(var mediaType: String = ContentType.JSON.toString()) { 9 | 10 | 11 | fun setContentType(mediaType: String = ContentType.JSON.toString()) { 12 | /* if(bodyParams!=null || encodedBodyParams!=null){ 13 | throw IllegalArgumentException("Only one type of params is allowed either params String with contentType or hashMap") 14 | }*/ 15 | this.mediaType = mediaType 16 | } 17 | 18 | /* abstract fun toRequestBody(): T*/ 19 | 20 | } -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/executor/PriorityThreadFactory.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.executor 2 | 3 | 4 | import android.os.Process 5 | import android.util.Log 6 | import java.util.concurrent.ThreadFactory 7 | 8 | class PriorityThreadFactory(private val threadPriority: Int) : ThreadFactory { 9 | override fun newThread(runnable: Runnable): Thread { 10 | Log.e("called","android") 11 | val wrapperRunnable = Runnable { 12 | try { 13 | Process.setThreadPriority(threadPriority) 14 | } catch (t: Throwable) { 15 | } 16 | runnable.run() 17 | } 18 | return Thread(wrapperRunnable) 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/model/User.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test.model 2 | 3 | import com.google.gson.annotations.Expose 4 | import com.google.gson.annotations.SerializedName 5 | import com.squareup.moshi.JsonClass 6 | @JsonClass(generateAdapter = true) 7 | class User { 8 | @SerializedName("id") 9 | @Expose 10 | var id: Int? = null 11 | 12 | @SerializedName("email") 13 | @Expose 14 | var email: String? = null 15 | 16 | @SerializedName("first_name") 17 | @Expose 18 | var firstName: String? = null 19 | 20 | @SerializedName("last_name") 21 | @Expose 22 | var lastName: String? = null 23 | 24 | @SerializedName("avatar") 25 | @Expose 26 | var avatar: String? = null 27 | 28 | } -------------------------------------------------------------------------------- /kine-moshi/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-moshi' 6 | PUBLISH_VERSION = '1.9.3.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 13 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 14 | 15 | dependencies { 16 | implementation fileTree(dir: "libs", include: ["*.jar"]) 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 18 | implementation("com.squareup.moshi:moshi:1.9.3") 19 | implementation project(':kine') 20 | } -------------------------------------------------------------------------------- /kine-rxjava3/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-rxjava3' 6 | PUBLISH_VERSION = '3.0.6.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 13 | 14 | dependencies { 15 | implementation fileTree(dir: "libs", include: ["*.jar"]) 16 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 17 | implementation 'io.reactivex.rxjava3:rxjava:3.0.6' 18 | implementation project(':kine') 19 | } -------------------------------------------------------------------------------- /kine-rxjava2/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-rxjava2' 6 | PUBLISH_VERSION = '2.2.19.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 13 | 14 | dependencies { 15 | implementation fileTree(dir: "libs", include: ["*.jar"]) 16 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 17 | implementation "io.reactivex.rxjava2:rxjava:2.2.19" 18 | implementation project(':kine') 19 | } -------------------------------------------------------------------------------- /app/src/main/java/com/kine/test/model/UserListResponse.kt: -------------------------------------------------------------------------------- 1 | package com.kine.test.model 2 | 3 | import com.google.gson.annotations.Expose 4 | import com.google.gson.annotations.SerializedName 5 | import com.squareup.moshi.JsonClass 6 | 7 | @JsonClass(generateAdapter = true) 8 | class UserListResponse { 9 | @SerializedName("page") 10 | @Expose 11 | var page: Int? = null 12 | 13 | @SerializedName("per_page") 14 | @Expose 15 | var perPage: Int? = null 16 | 17 | @SerializedName("total") 18 | @Expose 19 | var total: Int? = null 20 | 21 | @SerializedName("total_pages") 22 | @Expose 23 | var totalPages: Int? = null 24 | 25 | @SerializedName("data") 26 | @Expose 27 | var users: List? = null 28 | 29 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 16 | 17 | -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/executor/MainThreadExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.executor 2 | 3 | import android.os.Build 4 | import android.os.Handler 5 | import android.os.Looper 6 | import java.util.concurrent.Executor 7 | 8 | 9 | class MainThreadExecutor : Executor { 10 | private val handler: Handler = Handler(Looper.getMainLooper()) 11 | override fun execute(runnable: Runnable) { 12 | val isUiThread = if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) 13 | Looper.getMainLooper().isCurrentThread 14 | else Thread.currentThread() == Looper.getMainLooper().thread 15 | if(isUiThread){ 16 | runnable.run() 17 | }else { 18 | handler.post(runnable) 19 | } 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /kine-gson/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | apply plugin: 'kotlin-kapt' 4 | ext { 5 | PUBLISH_GROUP_ID = 'com.kine' 6 | PUBLISH_ARTIFACT_ID = 'kine-gson' 7 | PUBLISH_VERSION = '2.8.6.0' 8 | } 9 | tasks.withType(Javadoc).all { 10 | enabled = false 11 | } 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 13 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 14 | 15 | dependencies { 16 | implementation fileTree(dir: "libs", include: ["*.jar"]) 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 18 | implementation 'com.google.code.gson:gson:2.8.6' 19 | implementation project(':kine') 20 | 21 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/RequestFields.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import com.kine.cache.KineCacheControl 4 | import com.kine.client.KineClient 5 | import com.kine.converters.Converter 6 | import com.kine.policies.Priority 7 | import com.kine.policies.RetryPolicy 8 | import java.util.concurrent.Executor 9 | 10 | 11 | /**` 12 | * An RequestFields. This class is used to store all information associated with a single HTTP request. 13 | */ 14 | open class RequestFields(val kineClient: KineClient?, val converter: Converter?, 15 | val dataFields: RequestDataFields, var priority: Priority, var retryPolicy: RetryPolicy?, 16 | val kineCacheControl: KineCacheControl, val logLevel: Int, var executor: Executor) -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/connections/Utils.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.connections 2 | 3 | import android.annotation.SuppressLint 4 | import android.content.Context 5 | import android.net.ConnectivityManager 6 | 7 | object Utils { 8 | /** 9 | * checks Network connectivity 10 | * 11 | * @param context the context to check 12 | * @return true/false 13 | */ 14 | @Suppress("DEPRECATION") 15 | fun isConnected(context: Context?): Boolean { 16 | context ?: return true 17 | val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 18 | @SuppressLint("MissingPermission") val netInfo = cm.activeNetworkInfo 19 | return netInfo != null && netInfo.isConnected 20 | } 21 | 22 | } -------------------------------------------------------------------------------- /kine-coroutine/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | 4 | ext { 5 | PUBLISH_GROUP_ID = 'com.kine' 6 | PUBLISH_ARTIFACT_ID = 'kine-coroutine' 7 | PUBLISH_VERSION = '1.3.8.0' 8 | } 9 | tasks.withType(Javadoc).all { 10 | enabled = false 11 | } 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 13 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 14 | 15 | 16 | dependencies { 17 | implementation fileTree(dir: 'libs', include: ['*.jar']) 18 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 19 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8" 20 | implementation project(':kine') 21 | } 22 | 23 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/log/JavaLog.kt: -------------------------------------------------------------------------------- 1 | package com.kine.log 2 | 3 | class JavaLog :Log{ 4 | override fun e(tag: String?, message: String, exception: java.lang.Exception?) { 5 | println("$tag $message "+exception?.localizedMessage) 6 | } 7 | 8 | override fun v(tag: String?, message: String) { 9 | println("$tag $message") 10 | } 11 | 12 | override fun wtf(tag: String?, message: String) { 13 | println("$tag $message") 14 | } 15 | 16 | override fun d(tag: String?, message: String) { 17 | println("$tag $message") 18 | } 19 | 20 | override fun i(tag: String?, message: String) { 21 | println("$tag $message") 22 | } 23 | 24 | override fun w(tag: String?, message: String) { 25 | println("$tag $message") 26 | } 27 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/policies/Priority.kt: -------------------------------------------------------------------------------- 1 | package com.kine.policies 2 | 3 | /** 4 | * Priority levels 5 | */ 6 | enum class Priority { 7 | /** 8 | * NOTE: DO NOT CHANGE ORDERING OF THOSE CONSTANTS UNDER ANY CIRCUMSTANCES. 9 | * Doing so will make ordering incorrect. 10 | */ 11 | /** 12 | * Lowest priority level. Used for prefetches of data. 13 | */ 14 | LOW, 15 | 16 | /** 17 | * Medium priority level. Used for warming of data that might soon get visible. 18 | */ 19 | MEDIUM, 20 | 21 | /** 22 | * Highest priority level. Used for data that are currently visible on screen. 23 | */ 24 | HIGH, 25 | 26 | /** 27 | * Highest priority level. Used for data that are required instantly(mainly for emergency). 28 | */ 29 | IMMEDIATE 30 | } -------------------------------------------------------------------------------- /kine-coroutine/src/main/java/com/kine/coroutine/Coroutine.kt: -------------------------------------------------------------------------------- 1 | package com.kine.coroutine 2 | 3 | import com.kine.KineRequest 4 | import com.kine.internal.DefaultKineClass 5 | import com.kine.response.KineResponse 6 | import kotlinx.coroutines.* 7 | import kotlin.coroutines.CoroutineContext 8 | 9 | suspend fun KineRequest.RequestOptionsBuilder.responseAsCoroutine(clazz: Class, scope: CoroutineContext = Dispatchers.IO): KineResponse? { 10 | return build().responseAsCoroutine(clazz, scope) 11 | } 12 | 13 | suspend fun KineRequest.responseAsCoroutine( 14 | clazz: Class, 15 | scope: CoroutineContext = Dispatchers.IO 16 | ): KineResponse? { 17 | val response: KineResponse? 18 | withContext(scope) { 19 | response = execute(DefaultKineClass(clazz)) 20 | } 21 | return response 22 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/UploadRequestFields.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import com.kine.cache.KineCacheControl 4 | import com.kine.client.KineClient 5 | import com.kine.converters.Converter 6 | import com.kine.extensions.ProgressListener 7 | import com.kine.policies.Priority 8 | import com.kine.policies.RetryPolicy 9 | import java.util.concurrent.Executor 10 | 11 | class UploadRequestFields(val progressListener:ProgressListener?, kineClient: KineClient?, converter: Converter?, 12 | requestDataFields: RequestDataFields, priority: Priority, retryPolicy: RetryPolicy?, 13 | kineCacheControl: KineCacheControl, logLevel: Int, executor: Executor 14 | ) 15 | :RequestFields(kineClient, converter, requestDataFields, priority, retryPolicy, kineCacheControl, logLevel,executor){ 16 | 17 | } -------------------------------------------------------------------------------- /kine-android/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/log/Log.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.log 2 | 3 | import android.util.Log 4 | 5 | class Log:com.kine.log.Log { 6 | override fun e(tag: String?, message: String, exception: java.lang.Exception?) { 7 | Log.e(tag, message, exception) 8 | } 9 | 10 | override fun v(tag: String?, message: String) { 11 | Log.v(tag, message) 12 | 13 | } 14 | 15 | override fun wtf(tag: String?, message: String) { 16 | Log.wtf(tag, message) 17 | 18 | } 19 | 20 | override fun d(tag: String?, message: String) { 21 | Log.d(tag, message) 22 | 23 | } 24 | 25 | override fun i(tag: String?, message: String) { 26 | Log.i(tag, message) 27 | 28 | } 29 | 30 | override fun w(tag: String?, message: String) { 31 | Log.w(tag, message) 32 | 33 | } 34 | } -------------------------------------------------------------------------------- /kine-livedata/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /kine-rxjava2/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /kine-imageloader/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /kine-okhttp/src/main/java/com/kine/converters/OkioConverter.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.kine.converters 4 | 5 | import com.kine.request.RequestFields 6 | import okio.BufferedSource 7 | import okio.ByteString 8 | 9 | 10 | class OkioConverter : RawResponseConverter() { 11 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 12 | return when { 13 | response is ByteString && clazz.isAssignableFrom(ByteString::class.java) -> { 14 | response as J 15 | } 16 | response is BufferedSource && clazz.isAssignableFrom(BufferedSource::class.java) -> { 17 | response as J 18 | } 19 | else -> { 20 | super.convert(response, requestFields, clazz) 21 | } 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /kine-okhttplegacy/src/main/java/com/kine/converters/OkioConverter.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.kine.converters 4 | 5 | import com.kine.request.RequestFields 6 | import okio.BufferedSource 7 | import okio.ByteString 8 | 9 | 10 | class OkioConverter : RawResponseConverter() { 11 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 12 | return when { 13 | response is ByteString && clazz.isAssignableFrom(ByteString::class.java) -> { 14 | response as J 15 | } 16 | response is BufferedSource && clazz.isAssignableFrom(BufferedSource::class.java) -> { 17 | response as J 18 | } 19 | else -> { 20 | super.convert(response, requestFields, clazz) 21 | } 22 | } 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/DownloadRequestFields.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import com.kine.cache.KineCacheControl 4 | import com.kine.client.KineClient 5 | import com.kine.converters.Converter 6 | import com.kine.extensions.ProgressListener 7 | import com.kine.policies.Priority 8 | import com.kine.policies.RetryPolicy 9 | import java.io.File 10 | import java.util.concurrent.Executor 11 | 12 | class DownloadRequestFields(val file: File, val progressListener:ProgressListener, kineClient: KineClient?, 13 | converter: Converter?, requestDataFields: RequestDataFields, priority: Priority, retryPolicy: RetryPolicy?, 14 | kineCacheControl: KineCacheControl, logLevel: Int, executor: Executor) 15 | :RequestFields(kineClient, converter, requestDataFields, priority, retryPolicy, kineCacheControl, logLevel,executor){ 16 | 17 | } -------------------------------------------------------------------------------- /kine-imageloader/src/main/java/com/kine/imageloader/converter/BitmapConverter.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.kine.imageloader.converter 4 | 5 | import android.graphics.Bitmap 6 | import android.graphics.BitmapFactory 7 | import com.kine.converters.Converter 8 | import com.kine.request.RequestFields 9 | 10 | class BitmapConverter :Converter{ 11 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 12 | if(clazz.isAssignableFrom(Bitmap::class.java)){ 13 | return when (response) { 14 | is ByteArray -> { 15 | BitmapFactory.decodeByteArray(response, 0, response.size) as J 16 | } 17 | else -> { 18 | null 19 | } 20 | } 21 | } 22 | return null 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/log/Log.kt: -------------------------------------------------------------------------------- 1 | package com.kine.log 2 | 3 | interface Log { 4 | fun e(tag: String?, message: String, exception: java.lang.Exception? = null) { 5 | if(exception!=null) { 6 | exception.printStackTrace() 7 | println("$tag $message " + exception.localizedMessage) 8 | }else{ 9 | println("$tag $message ") 10 | } 11 | } 12 | 13 | fun v(tag: String?, message: String) { 14 | println("$tag $message") 15 | } 16 | 17 | fun wtf(tag: String?, message: String) { 18 | println("$tag $message") 19 | } 20 | 21 | fun d(tag: String?, message: String) { 22 | println("$tag $message") 23 | } 24 | 25 | fun i(tag: String?, message: String) { 26 | println("$tag $message") 27 | } 28 | 29 | fun w(tag: String?, message: String) { 30 | println("$tag $message") 31 | } 32 | } -------------------------------------------------------------------------------- /kine-imageloader/src/main/java/com/kine/imageloader/policies/MemoryPolicy.kt: -------------------------------------------------------------------------------- 1 | package com.kine.imageloader.policies 2 | 3 | /** Designates the policy to use when dealing with memory cache. */ 4 | enum class MemoryPolicy(val index: Int) { 5 | /** Skips memory cache lookup when processing a request. */ 6 | CACHE(1 shl 0), 7 | 8 | /** 9 | * Skips storing the final result into memory cache. Useful for one-off requests 10 | * to avoid evicting other bitmaps from the cache. 11 | */ 12 | STORE(1 shl 1); 13 | 14 | companion object { 15 | @JvmStatic 16 | fun shouldReadFromMemoryCache(memoryPolicy: Int): Boolean { 17 | return memoryPolicy and CACHE.index != 0 18 | } 19 | 20 | @JvmStatic 21 | fun shouldWriteToMemoryCache(memoryPolicy: Int): Boolean { 22 | return memoryPolicy and STORE.index != 0 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /kine-okhttp/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-okhttp' 6 | PUBLISH_VERSION = '4.8.1.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 13 | dependencies { 14 | implementation fileTree(dir: "libs", include: ["*.jar"]) 15 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 16 | implementation project(':kine') 17 | implementation("com.squareup.okhttp3:okhttp:4.9.0") 18 | implementation("com.squareup.okio:okio:2.8.0") 19 | testImplementation("com.squareup.okhttp3:mockwebserver:4.8.1") 20 | testImplementation 'junit:junit:4.13' 21 | 22 | } -------------------------------------------------------------------------------- /kine-okhttplegacy/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-okhttplegacy' 6 | PUBLISH_VERSION = '3.12.12.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 13 | dependencies { 14 | implementation fileTree(dir: "libs", include: ["*.jar"]) 15 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 16 | implementation("com.squareup.okhttp3:okhttp:3.12.12") 17 | implementation("com.squareup.okio:okio:1.17.5") 18 | implementation project(':kine') 19 | 20 | testImplementation("com.squareup.okhttp3:mockwebserver:3.12.12") 21 | testImplementation 'junit:junit:4.13' 22 | } -------------------------------------------------------------------------------- /kine-json/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'java-library' 2 | apply plugin: 'kotlin' 3 | ext { 4 | PUBLISH_GROUP_ID = 'com.kine' 5 | PUBLISH_ARTIFACT_ID = 'kine-json' 6 | PUBLISH_VERSION = '1.0.0.0' 7 | } 8 | tasks.withType(Javadoc).all { 9 | enabled = false 10 | } 11 | 12 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 13 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 14 | 15 | dependencies { 16 | implementation fileTree(dir: "libs", include: ["*.jar"]) 17 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 18 | implementation 'org.json:json:20200518' 19 | implementation project(':kine') 20 | testImplementation("com.squareup.okhttp3:mockwebserver:4.8.1") 21 | testImplementation 'junit:junit:4.13' 22 | testImplementation 'org.json:json:20200518' 23 | testImplementation project(':kine-okhttp') 24 | } 25 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/policies/RetryPolicy.kt: -------------------------------------------------------------------------------- 1 | package com.kine.policies 2 | 3 | /** 4 | * Retry policy for a request. 5 | */ 6 | interface RetryPolicy { 7 | 8 | 9 | /** 10 | * Returns the current timeout (used for logging). 11 | */ 12 | fun getCurrentTimeout(): Int 13 | 14 | /** 15 | * Returns the total retry count (used for logging). 16 | */ 17 | fun getRetryCount(): Int 18 | 19 | /** 20 | * Returns the total retry count (used for logging). 21 | */ 22 | fun setCurrentTimeout(timeOut: Int) 23 | 24 | /** 25 | * Returns the backoff multiplier for the policy. 26 | */ 27 | fun getBackoffMultiplier(): Float 28 | 29 | fun isSame(retryPolicy: RetryPolicy): Boolean { 30 | return (getCurrentTimeout() == retryPolicy.getCurrentTimeout() && getRetryCount() == retryPolicy.getRetryCount() && 31 | getBackoffMultiplier() == retryPolicy.getBackoffMultiplier()) 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/response/KineError.kt: -------------------------------------------------------------------------------- 1 | package com.kine.response 2 | 3 | import com.kine.exceptions.NoInternetException 4 | import com.kine.exceptions.NullResponseBodyException 5 | import com.kine.exceptions.NullResponseException 6 | import com.kine.exceptions.ParseException 7 | 8 | class KineError(val exception:Throwable) { 9 | fun printStackTrace() { 10 | exception.printStackTrace() 11 | } 12 | 13 | fun message(): String? { 14 | return exception.localizedMessage?:exception.message 15 | } 16 | fun isNoInternetError(): Boolean { 17 | return exception is NoInternetException 18 | } 19 | fun isNullResponseError(): Boolean { 20 | return exception is NullResponseException 21 | } 22 | fun isNullResponseBodyError(): Boolean { 23 | return exception is NullResponseBodyException 24 | } 25 | fun isParsingError(): Boolean { 26 | return exception is ParseException 27 | } 28 | fun isHttpStatusCodeError(): Boolean { 29 | return exception is Exception 30 | } 31 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/converters/RawResponseConverter.kt: -------------------------------------------------------------------------------- 1 | package com.kine.converters 2 | 3 | import com.kine.request.RequestFields 4 | import java.io.InputStream 5 | import java.io.Reader 6 | 7 | open class RawResponseConverter:Converter { 8 | @Suppress("UNCHECKED_CAST") 9 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 10 | return when { 11 | response is String && clazz.isAssignableFrom(String::class.java) -> { 12 | response as J 13 | } 14 | response is ByteArray && clazz.isAssignableFrom(ByteArray::class.java) -> { 15 | response as J 16 | } 17 | response is InputStream && clazz.isAssignableFrom(InputStream::class.java) -> { 18 | response as J 19 | } 20 | response is Reader && clazz.isAssignableFrom(Reader::class.java) -> { 21 | response as J 22 | } 23 | else -> { 24 | null 25 | } 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /kine-json/src/main/java/com/kine/converters/JsonConverter.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.kine.converters 4 | 5 | import com.kine.request.RequestFields 6 | import org.json.JSONArray 7 | import org.json.JSONObject 8 | 9 | 10 | class JsonConverter : RawResponseConverter() { 11 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 12 | if (response is String) { 13 | return when { 14 | clazz.isAssignableFrom(String::class.java) -> { 15 | response as J 16 | } 17 | clazz.isAssignableFrom(JSONObject::class.java) -> { 18 | JSONObject(response) as J 19 | } 20 | clazz.isAssignableFrom(JSONArray::class.java) -> { 21 | JSONArray(response) as J 22 | } 23 | else -> { 24 | null 25 | } 26 | } 27 | } else { 28 | return super.convert(response, requestFields, clazz) 29 | } 30 | } 31 | 32 | } -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/converters/JsonConverter.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("UNCHECKED_CAST") 2 | 3 | package com.kine.android.converters 4 | 5 | import com.kine.converters.RawResponseConverter 6 | import com.kine.request.RequestFields 7 | import org.json.JSONArray 8 | import org.json.JSONObject 9 | 10 | 11 | class JsonConverter : RawResponseConverter() { 12 | override fun convert(response: Any, requestFields: RequestFields, clazz: Class): J? { 13 | if (response is String) { 14 | return when { 15 | clazz.isAssignableFrom(String::class.java) -> { 16 | response as J 17 | } 18 | clazz.isAssignableFrom(JSONObject::class.java) -> { 19 | JSONObject(response) as J 20 | } 21 | clazz.isAssignableFrom(JSONArray::class.java) -> { 22 | JSONArray(response) as J 23 | } 24 | else -> { 25 | null 26 | } 27 | } 28 | } else { 29 | return super.convert(response, requestFields, clazz) 30 | } 31 | } 32 | 33 | } -------------------------------------------------------------------------------- /.github/workflows/main_release.yml: -------------------------------------------------------------------------------- 1 | name: Release 2 | 3 | on: 4 | push: 5 | tags: 6 | - 'v*' 7 | 8 | jobs: 9 | 10 | release: 11 | name: Create Release 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - name: Checkout code 16 | uses: actions/checkout@v2 17 | 18 | - name: Set release name 19 | run: echo ::set-env name=RELEASE_NAME::$(echo ${GITHUB_REF:11}) 20 | 21 | - name: Create release 22 | id: create_release 23 | uses: actions/create-release@v1 24 | env: 25 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 26 | with: 27 | tag_name: ${{ github.ref }} 28 | release_name: ${{ env.RELEASE_NAME }} 29 | draft: false 30 | prerelease: false 31 | 32 | publish: 33 | name: Publish Build 34 | runs-on: ubuntu-latest 35 | 36 | steps: 37 | - name: Checkout code 38 | uses: actions/checkout@v2 39 | 40 | - name: Configure JDK 41 | uses: actions/setup-java@v1 42 | with: 43 | java-version: 1.8 44 | 45 | - name: Publish library 46 | env: 47 | bintrayUser: ${{ secrets.BINTRAYUSERNAME }} 48 | bintrayApiKey: ${{ secrets.BINTRAYAPIKEY }} 49 | run: gradle install bintrayUpload 50 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/EncodedRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import java.util.* 4 | 5 | class EncodedRequestBody(var bodyParams: HashMap = hashMapOf(), var encodedBodyParams: HashMap = hashMapOf()) 6 | :RequestBody(ContentType.ENCODED.toString()) { 7 | 8 | 9 | fun setBody(bodyParams: HashMap? = null) { 10 | 11 | this.mediaType = ContentType.ENCODED.toString() 12 | this.bodyParams = bodyParams?: hashMapOf() 13 | } 14 | fun setBodyEncoded(encodedBodyParams: HashMap? = null) { 15 | 16 | this.mediaType = ContentType.ENCODED.toString() 17 | this.encodedBodyParams = encodedBodyParams?: hashMapOf() 18 | } 19 | fun setBody(bodyParams: HashMap? = null, 20 | encodedBodyParams: HashMap? = null) { 21 | 22 | this.mediaType = ContentType.ENCODED.toString() 23 | this.bodyParams = bodyParams?: hashMapOf() 24 | this.encodedBodyParams = encodedBodyParams?: hashMapOf() 25 | } 26 | 27 | fun addBodyParam(key: String, value: String) { 28 | bodyParams[key] = value 29 | } 30 | fun addBodyParamEncoded(key: String, value: String) { 31 | encodedBodyParams[key] = value 32 | } 33 | } -------------------------------------------------------------------------------- /kine-rxjava2/src/main/java/com/kine/rxnetworking/RxJava2.kt: -------------------------------------------------------------------------------- 1 | package com.kine.rxnetworking 2 | 3 | import com.kine.KineRequest 4 | import com.kine.internal.DefaultKineClass 5 | import com.kine.response.KineResponse 6 | import io.reactivex.Flowable 7 | import io.reactivex.Observable 8 | import io.reactivex.Single 9 | 10 | 11 | fun KineRequest.RequestOptionsBuilder.toSingle(callback:Class): Single?> { 12 | return build().toSingle(callback) 13 | } 14 | fun KineRequest.toSingle(callback:Class): Single?> { 15 | return Single.fromCallable { 16 | this.execute(DefaultKineClass(callback)) 17 | } 18 | } 19 | fun KineRequest.RequestOptionsBuilder.toFlowable(callback:Class): Flowable?> { 20 | return build().toFlowable(callback) 21 | } 22 | fun KineRequest.toFlowable(callback:Class): Flowable?> { 23 | return Flowable.fromCallable { 24 | this.execute(DefaultKineClass(callback)) 25 | } 26 | } 27 | fun KineRequest.RequestOptionsBuilder.toObservable(callback:Class): Observable?> { 28 | return build().toObservable(callback) 29 | } 30 | fun KineRequest.toObservable(callback:Class): Observable?> { 31 | return Observable.fromCallable { 32 | this.execute(DefaultKineClass(callback)) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/log/LogLevel.kt: -------------------------------------------------------------------------------- 1 | package com.kine.log 2 | /** 3 | * This class is used to filter responses for logging. 4 | */ 5 | object LogLevel { 6 | const val NO_LEVEL = -2 7 | const val NO_LOGS = -1 8 | const val INFO = 0 9 | const val VERBOSE = 1 10 | const val DEBUG = 2 11 | const val WARNING = 3 12 | const val ERROR = 4 13 | fun isVerbose(logLevel: Int, localLevel: Int): Boolean { 14 | return if (localLevel == NO_LEVEL) { 15 | logLevel >= VERBOSE 16 | } else localLevel >= VERBOSE 17 | } 18 | 19 | fun isInfo(logLevel: Int, localLevel: Int): Boolean { 20 | return if (localLevel == NO_LEVEL) { 21 | logLevel >= INFO 22 | } else localLevel >= INFO 23 | } 24 | 25 | fun isDebug(logLevel: Int, localLevel: Int): Boolean { 26 | return if (localLevel == NO_LEVEL) { 27 | logLevel >= DEBUG 28 | } else localLevel >= DEBUG 29 | } 30 | 31 | fun isWarning(logLevel: Int, localLevel: Int): Boolean { 32 | return if (localLevel == NO_LEVEL) { 33 | logLevel >= WARNING 34 | } else localLevel >= WARNING 35 | } 36 | 37 | fun isError(logLevel: Int, localLevel: Int): Boolean { 38 | return if (localLevel == NO_LEVEL) { 39 | logLevel >= ERROR 40 | } else localLevel >= ERROR 41 | } 42 | } -------------------------------------------------------------------------------- /kine-livedata/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | ext { 5 | PUBLISH_GROUP_ID = 'com.kine' 6 | PUBLISH_ARTIFACT_ID = 'kine-livedata' 7 | PUBLISH_VERSION = '2.2.0.0' 8 | } 9 | android { 10 | compileSdkVersion 30 11 | buildToolsVersion "29.0.3" 12 | 13 | defaultConfig { 14 | minSdkVersion 16 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | consumerProguardFiles "consumer-rules.pro" 20 | } 21 | 22 | buildTypes { 23 | release { 24 | minifyEnabled false 25 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 26 | } 27 | } 28 | tasks.withType(Javadoc).all { 29 | enabled = false 30 | } 31 | } 32 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 33 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 34 | dependencies { 35 | implementation fileTree(dir: "libs", include: ["*.jar"]) 36 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 37 | implementation project(':kine') 38 | implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.2.0" 39 | 40 | } -------------------------------------------------------------------------------- /kine-rxjava3/src/main/java/com/kine/rxjava3/RxJava3.kt: -------------------------------------------------------------------------------- 1 | package com.kine.rxjava3 2 | 3 | import com.kine.KineRequest 4 | import com.kine.internal.DefaultKineClass 5 | import com.kine.response.KineResponse 6 | import io.reactivex.rxjava3.core.Flowable 7 | import io.reactivex.rxjava3.core.Observable 8 | import io.reactivex.rxjava3.core.Single 9 | 10 | fun KineRequest.RequestOptionsBuilder.toSingle(callback:Class): Single?> { 11 | return build().toSingle(callback) 12 | } 13 | fun KineRequest.toSingle(callback:Class): Single?> { 14 | return Single.fromCallable { 15 | this.execute(DefaultKineClass(callback)) 16 | } 17 | } 18 | fun KineRequest.RequestOptionsBuilder.toFlowable(callback:Class): Flowable?> { 19 | return build().toFlowable(callback) 20 | } 21 | fun KineRequest.toFlowable(callback:Class): Flowable?> { 22 | return Flowable.fromCallable { 23 | this.execute(DefaultKineClass(callback)) 24 | } 25 | } 26 | fun KineRequest.RequestOptionsBuilder.toObservable(callback:Class): Observable?> { 27 | return build().toObservable(callback) 28 | } 29 | fun KineRequest.toObservable(callback:Class): Observable?> { 30 | return Observable.fromCallable { 31 | this.execute(DefaultKineClass(callback)) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /kine-imageloader/src/main/java/com/kine/imageloader/cache/MemoryCache.kt: -------------------------------------------------------------------------------- 1 | package com.kine.imageloader.cache 2 | 3 | import android.graphics.Bitmap 4 | import java.util.* 5 | 6 | /** caching class 7 | */ 8 | class MemoryCache { 9 | private var maxSize = DEFAULT_CACHE_SIZE 10 | private var entries: HashMap = HashMap() 11 | 12 | fun get(key: String): Bitmap? { 13 | if (entries.containsKey(key)) { 14 | return entries[key] 15 | } 16 | return null 17 | } 18 | 19 | fun put(key: String, cacheEntry: Bitmap) { 20 | 21 | synchronized(entries) { entries.put(key, cacheEntry) } 22 | } 23 | 24 | 25 | fun remove(key: String) { 26 | synchronized(entries) { 27 | if (entries.containsKey(key)) { 28 | entries.remove(key) 29 | } 30 | } 31 | } 32 | 33 | fun clear() { 34 | entries.clear() 35 | } 36 | 37 | private val currentSize: Int 38 | get() { 39 | return entries.size 40 | } 41 | 42 | companion object { 43 | private val TAG = MemoryCache::class.java.name 44 | 45 | /* 46 | * Get max available VM memory, exceeding this amount will throw an OutOfMemory exception. 47 | * and use 1/30th of the available memory for this memory cache. 48 | */ 49 | val DEFAULT_CACHE_SIZE = (Runtime.getRuntime().maxMemory() / 30).toInt() 50 | } 51 | 52 | } -------------------------------------------------------------------------------- /kine-imageloader/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | ext { 5 | PUBLISH_GROUP_ID = 'com.kine' 6 | PUBLISH_ARTIFACT_ID = 'kine-imageloader' 7 | PUBLISH_VERSION = '1.0.0.0' 8 | } 9 | android { 10 | compileSdkVersion 29 11 | buildToolsVersion "29.0.3" 12 | 13 | defaultConfig { 14 | minSdkVersion 16 15 | targetSdkVersion 29 16 | versionCode 1 17 | versionName "1.0" 18 | 19 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 20 | consumerProguardFiles "consumer-rules.pro" 21 | } 22 | 23 | buildTypes { 24 | release { 25 | minifyEnabled false 26 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 27 | } 28 | } 29 | tasks.withType(Javadoc).all { 30 | enabled = false 31 | } 32 | } 33 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/publish.gradle' 34 | apply from: 'https://raw.githubusercontent.com/AnkitAgrawal967/Kine/master/bintray.gradle' 35 | 36 | dependencies { 37 | implementation fileTree(dir: "libs", include: ["*.jar"]) 38 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 39 | implementation 'androidx.core:core-ktx:1.3.2' 40 | implementation project(':kine') 41 | implementation project(':kine-android') 42 | } -------------------------------------------------------------------------------- /bintray.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.jfrog.bintray' 2 | 3 | if (project.hasProperty("android")) { 4 | apply plugin: 'com.github.dcendents.android-maven' 5 | } 6 | 7 | group = publishedGroupId 8 | def bintrayUser = '' 9 | def bintrayApiKey = '' 10 | def bintrayPassword = '' 11 | // Bintray 12 | if (project.rootProject.file('local.properties').exists()) { 13 | Properties properties = new Properties() 14 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 15 | bintrayUser = properties.getProperty("bintray.user") 16 | bintrayApiKey = properties.getProperty("bintray.apikey") 17 | bintrayPassword = properties.getProperty("bintray.gpg.password") 18 | } else { 19 | bintrayUser = System.getenv("bintrayUser") 20 | bintrayApiKey = System.getenv("bintrayApiKey") 21 | bintrayPassword = System.getenv("bintrayApiKey") 22 | } 23 | 24 | bintray { 25 | user = bintrayUser 26 | key = bintrayApiKey 27 | publications = ['MyPublication'] 28 | configurations = ['archives'] 29 | pkg { 30 | repo = bintrayRepo 31 | name = bintrayName 32 | desc = libraryDescription 33 | websiteUrl = siteUrl 34 | vcsUrl = gitUrl 35 | licenses = allLicenses 36 | publish = true 37 | publicDownloadNumbers = true 38 | version { 39 | desc = libraryDescription 40 | gpg { 41 | sign = true //Determines whether to GPG sign the files. The default is false 42 | passphrase = bintrayPassword 43 | //Optional. The passphrase for GPG signing' 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /kine-android/src/main/java/com/kine/android/cache/Cache.kt: -------------------------------------------------------------------------------- 1 | package com.kine.android.cache 2 | 3 | import com.kine.response.KineResponse 4 | 5 | /** 6 | * interface for caching response. 7 | */ 8 | interface Cache { 9 | operator fun get(key: String): CacheEntry? 10 | fun remove(key: String) 11 | fun clear() 12 | fun put(key: String, cacheEntry: CacheEntry?) 13 | 14 | class CacheEntry(kineResponse: KineResponse, cacheTime: Long, reqTAG: String, timeStampMillis: Long) { 15 | 16 | val cacheDuration: Long 17 | 18 | val url: String 19 | 20 | val timeStampMillis: Long 21 | 22 | /** 23 | * data from this kineResponse. 24 | */ 25 | val data: String? 26 | 27 | /** 28 | * The HTTP status code. 29 | */ 30 | @JvmField 31 | val statusCode: Int 32 | 33 | /** 34 | * KineResponse headers. 35 | */ 36 | val headers: Map 37 | 38 | /** 39 | * Network roundtrip time in milliseconds. 40 | */ 41 | @JvmField 42 | val networkTimeMs: Long 43 | 44 | /** 45 | * Network roundtrip time in milliseconds. 46 | */ 47 | val loadedFrom: Int 48 | 49 | init { 50 | data = kineResponse.body 51 | headers = kineResponse.headers 52 | networkTimeMs = kineResponse.networkTimeMs 53 | loadedFrom = kineResponse.loadedFrom 54 | statusCode = kineResponse.statusCode 55 | cacheDuration = cacheTime 56 | url = reqTAG 57 | this.timeStampMillis = timeStampMillis 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /kine-okhttp/src/main/java/com/kine/client/FileProgressRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.client 2 | 3 | 4 | import com.kine.extensions.ProgressListener 5 | import okhttp3.MediaType 6 | import okhttp3.RequestBody 7 | import okio.* 8 | import java.io.IOException 9 | 10 | internal class FileProgressRequestBody( 11 | private val requestBody: RequestBody, 12 | private val progressListener: ProgressListener? 13 | ) : RequestBody() { 14 | 15 | override fun contentType(): MediaType? { 16 | return requestBody.contentType() 17 | } 18 | 19 | @Throws(IOException::class) 20 | override fun contentLength(): Long { 21 | return requestBody.contentLength() 22 | } 23 | 24 | @Throws(IOException::class) 25 | override fun writeTo(sink: BufferedSink) { 26 | if (progressListener == null) { 27 | requestBody.writeTo(sink) 28 | return 29 | } 30 | val progressSink = wrapSink(sink).buffer() 31 | requestBody.writeTo(progressSink) 32 | progressSink.flush() 33 | } 34 | 35 | private fun wrapSink(sink: Sink): Sink { 36 | return object : ForwardingSink(sink) { 37 | var bytesWritten = 0L 38 | var contentLength = 0L 39 | 40 | @Throws(IOException::class) 41 | override fun write(source: Buffer, byteCount: Long) { 42 | super.write(source, byteCount) 43 | if (contentLength == 0L) { 44 | contentLength = contentLength() 45 | } 46 | bytesWritten += byteCount 47 | progressListener?.invoke(bytesWritten, contentLength) 48 | 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /kine-okhttplegacy/src/main/java/com/kine/client/FileProgressRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.client 2 | 3 | 4 | import com.kine.extensions.ProgressListener 5 | import okhttp3.MediaType 6 | import okhttp3.RequestBody 7 | import okio.* 8 | import java.io.IOException 9 | 10 | internal class FileProgressRequestBody( 11 | private val requestBody: RequestBody, 12 | private val progressListener: ProgressListener? 13 | ) : RequestBody() { 14 | 15 | override fun contentType(): MediaType? { 16 | return requestBody.contentType() 17 | } 18 | 19 | @Throws(IOException::class) 20 | override fun contentLength(): Long { 21 | return requestBody.contentLength() 22 | } 23 | 24 | @Throws(IOException::class) 25 | override fun writeTo(sink: BufferedSink) { 26 | if (progressListener == null) { 27 | requestBody.writeTo(sink) 28 | return 29 | } 30 | val progressSink = Okio.buffer(wrapSink(sink)) 31 | requestBody.writeTo(progressSink) 32 | progressSink.flush() 33 | } 34 | 35 | private fun wrapSink(sink: Sink): Sink { 36 | return object : ForwardingSink(sink) { 37 | var bytesWritten = 0L 38 | var contentLength = 0L 39 | 40 | @Throws(IOException::class) 41 | override fun write(source: Buffer, byteCount: Long) { 42 | super.write(source, byteCount) 43 | if (contentLength == 0L) { 44 | contentLength = contentLength() 45 | } 46 | bytesWritten += byteCount 47 | progressListener?.invoke(bytesWritten, contentLength) 48 | 49 | } 50 | } 51 | } 52 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/executor/PriorityThreadPoolExecutor.kt: -------------------------------------------------------------------------------- 1 | package com.kine.executor 2 | 3 | import com.kine.policies.Priority 4 | import java.util.concurrent.* 5 | 6 | 7 | class PriorityThreadPoolExecutor( 8 | corePoolSize: Int, maximumPoolSize: Int, keepAliveTime: Long, 9 | unit: TimeUnit?, threadFactory: ThreadFactory? 10 | ) : 11 | ThreadPoolExecutor( 12 | corePoolSize, 13 | maximumPoolSize, 14 | keepAliveTime, 15 | unit, 16 | PriorityBlockingQueue(), 17 | threadFactory 18 | ) { 19 | override fun submit(task: Runnable): Future<*> { 20 | val futureTask = PriorityFutureTask(task as PriorityRunnable) 21 | execute(futureTask) 22 | return futureTask 23 | } 24 | 25 | private class PriorityFutureTask(private val priorityRunnable: PriorityRunnable) : 26 | FutureTask(priorityRunnable, null), 27 | Comparable { 28 | 29 | /* 30 | * compareTo() method is defined in interface java.lang.Comparable and it is used 31 | * to implement natural sorting on java classes. natural sorting means the the sort 32 | * order which naturally applies on object e.g. lexical order for String, numeric 33 | * order for Integer or Sorting employee by there ID etc. most of the java core 34 | * classes including String and Integer implements CompareTo() method and provide 35 | * natural sorting. 36 | */ 37 | override operator fun compareTo(other: PriorityFutureTask): Int { 38 | val p1: Priority = priorityRunnable.getPriority() 39 | val p2: Priority = other.priorityRunnable.getPriority() 40 | return p2.ordinal - p1.ordinal 41 | } 42 | 43 | } 44 | } -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx2048m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app"s APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | 23 | libraryVersion=1.0.0.0 24 | libraryName=Kine 25 | libraryDescription=A simple and powerful HTTP networking lib for kotlin/Android. 26 | publishedGroupId=com.kine 27 | artifact=Kine 28 | bintrayRepo=Kine 29 | bintrayName=kine 30 | siteUrl=https://github.com/AnkitAgrawal967/Kine 31 | gitUrl=https://github.com/AnkitAgrawal967/Kine.git 32 | developerId=AnkitAgrawal967 33 | developerName=Ankit Agrawal 34 | developerEmail=xyz@mail.com 35 | licenseName=The Apache Software License, Version 2.0 36 | licenseUrl=http://www.apache.org/licenses/LICENSE-2.0.txt 37 | allLicenses=["Apache-2.0"] -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | apply plugin: 'kotlin-kapt' 5 | 6 | android { 7 | compileSdkVersion 29 8 | buildToolsVersion "29.0.3" 9 | 10 | defaultConfig { 11 | applicationId "com.kine.test" 12 | minSdkVersion 16 13 | targetSdkVersion 22 14 | versionCode 1 15 | versionName "1.0" 16 | 17 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 18 | } 19 | 20 | buildTypes { 21 | release { 22 | minifyEnabled false 23 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 24 | } 25 | } 26 | } 27 | 28 | dependencies { 29 | implementation fileTree(dir: "libs", include: ["*.jar"]) 30 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 31 | implementation 'androidx.core:core-ktx:1.3.2' 32 | implementation 'androidx.appcompat:appcompat:1.2.0' 33 | implementation 'androidx.constraintlayout:constraintlayout:2.0.1' 34 | implementation project(':kine') 35 | implementation project(':kine-android') 36 | implementation project(':kine-okhttp') 37 | implementation project(':kine-moshi') 38 | implementation project(':kine-gson') 39 | implementation project(':kine-imageloader') 40 | implementation project(':kine-rxjava2') 41 | implementation project(':kine-coroutine') 42 | kapt("com.squareup.moshi:moshi-kotlin-codegen:1.9.3") 43 | implementation 'com.google.code.gson:gson:2.8.6' 44 | implementation("com.squareup.moshi:moshi:1.9.3") 45 | implementation 'com.squareup.picasso:picasso:2.71828' 46 | implementation "io.reactivex.rxjava2:rxandroid:2.1.1" 47 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.8" 48 | implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.8" 49 | 50 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/response/KineResponse.kt: -------------------------------------------------------------------------------- 1 | package com.kine.response 2 | 3 | import java.util.* 4 | 5 | /** 6 | * This class is used to store the response from the server. 7 | */ 8 | class KineResponse { 9 | /** data from this response. */ 10 | @JvmField 11 | val body: T? 12 | 13 | /** The HTTP status code. */ 14 | @JvmField 15 | val statusCode: Int 16 | 17 | /** KineResponse headers. */ 18 | @JvmField 19 | val headers: Map 20 | 21 | /** Network roundtrip time in milliseconds. */ 22 | @JvmField 23 | val networkTimeMs: Long 24 | 25 | /** source from which response is loaded from. */ 26 | @JvmField 27 | val loadedFrom: Int 28 | 29 | /** Parse time in milliseconds. */ 30 | @JvmField 31 | var parseTime: Long 32 | 33 | constructor( 34 | response: T, 35 | headers: Map, 36 | statusCode: Int, 37 | networkTimeMs: Long, 38 | loadedFrom: Int 39 | ) { 40 | this.body = response 41 | this.headers = headers 42 | this.statusCode = statusCode 43 | this.networkTimeMs = networkTimeMs 44 | this.loadedFrom = loadedFrom 45 | parseTime = 0 46 | } 47 | 48 | constructor(response: T, loadedFrom: Int) { 49 | this.body = response 50 | headers = HashMap() 51 | statusCode = 200 52 | networkTimeMs = 0 53 | this.loadedFrom = loadedFrom 54 | parseTime = 0 55 | } 56 | 57 | constructor(loadedFrom: Int) { 58 | body = null 59 | headers = HashMap() 60 | statusCode = 200 61 | networkTimeMs = 0 62 | this.loadedFrom = loadedFrom 63 | parseTime = 0 64 | } 65 | fun map(t:T):KineResponse{ 66 | return KineResponse(t,headers,statusCode,networkTimeMs,loadedFrom).apply { parseTime = this@KineResponse.parseTime } 67 | } 68 | object LoadedFrom { 69 | const val DISK = 1 70 | const val NETWORK = 2 71 | } 72 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/policies/DefaultRetryPolicy.kt: -------------------------------------------------------------------------------- 1 | package com.kine.policies 2 | 3 | /** 4 | * Default retry policy for requests. 5 | */ 6 | class DefaultRetryPolicy 7 | /** 8 | * Constructs a new retry policy using the default timeouts. 9 | */ @JvmOverloads constructor( 10 | /** The current timeout in milliseconds. */ 11 | private var mCurrentTimeoutMs: Int = DEFAULT_TIMEOUT_MS, 12 | /** The maximum number of attempts. */ 13 | private val mMaxNumRetries: Int = DEFAULT_MAX_RETRIES, 14 | /** The backoff multiplier for the policy. */ 15 | private val mBackoffMultiplier: Float = DEFAULT_BACKOFF_MULT 16 | ) : RetryPolicy { 17 | 18 | /** 19 | * Returns the current timeout. 20 | */ 21 | override fun getCurrentTimeout(): Int { 22 | return mCurrentTimeoutMs 23 | } 24 | 25 | /** 26 | * Returns the current retry count. 27 | */ 28 | override fun getRetryCount(): Int { 29 | return mMaxNumRetries 30 | } 31 | 32 | /** 33 | * Returns the total retry count (used for logging). 34 | * 35 | * @param timeOut 36 | */ 37 | override fun setCurrentTimeout(timeOut: Int) { 38 | mCurrentTimeoutMs = timeOut 39 | } 40 | 41 | /** 42 | * Returns the backoff multiplier for the policy. 43 | */ 44 | override fun getBackoffMultiplier(): Float { 45 | return mBackoffMultiplier 46 | } 47 | 48 | companion object { 49 | /** The default socket timeout in milliseconds */ 50 | const val DEFAULT_TIMEOUT_MS = 12500 51 | 52 | /** The default number of retries */ 53 | const val DEFAULT_MAX_RETRIES = 1 54 | 55 | /** The default backoff multiplier */ 56 | const val DEFAULT_BACKOFF_MULT = 1f 57 | } 58 | /** 59 | * Constructs a new retry policy. 60 | * @param mCurrentTimeoutMs The initial timeout for the policy. 61 | * @param mMaxNumRetries The maximum number of retries. 62 | * @param mBackoffMultiplier Backoff multiplier for the policy. 63 | */ 64 | } -------------------------------------------------------------------------------- /kine-android/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'kotlin-android' 3 | apply plugin: 'kotlin-android-extensions' 4 | 5 | ext { 6 | bintrayRepo = 'Kine' 7 | bintrayName = 'kine' 8 | 9 | publishedGroupId = 'com.kine' 10 | libraryName = 'Kine' 11 | artifact = 'kine-android' 12 | libraryDescription = 'A simple and powerful HTTP networking lib for kotlin/Android..' 13 | libraryVersion = '1.0.0.0' 14 | 15 | siteUrl = 'https://github.com/AnkitAgrawal967/Kine' 16 | gitUrl = 'https://github.com/AnkitAgrawal967/Kine.git' 17 | githubRepository= 'AnkitAgrawal967/Kine' 18 | 19 | developerId = 'AnkitAgrawal967' 20 | developerName = 'Ankit Agrawal' 21 | developerEmail = 'xyz@mail.com' 22 | 23 | licenseName = 'The Apache Software License, Version 2.0' 24 | licenseUrl = 'http://www.apache.org/licenses/LICENSE-2.0.txt' 25 | allLicenses = ["Apache-2.0"] 26 | } 27 | 28 | apply from: 'https://raw.githubusercontent.com/ktvipin27/RoomInspector/master/library/publish.gradle' 29 | 30 | android { 31 | compileSdkVersion 29 32 | buildToolsVersion "29.0.3" 33 | 34 | defaultConfig { 35 | minSdkVersion 16 36 | targetSdkVersion 29 37 | versionCode 1 38 | versionName "1.0" 39 | 40 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 41 | consumerProguardFiles "consumer-rules.pro" 42 | } 43 | 44 | buildTypes { 45 | release { 46 | minifyEnabled false 47 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 48 | } 49 | } 50 | tasks.withType(Javadoc).all { 51 | enabled = false 52 | } 53 | testOptions { 54 | unitTests.returnDefaultValues = true 55 | } 56 | } 57 | dependencies { 58 | implementation fileTree(dir: "libs", include: ["*.jar"]) 59 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 60 | implementation project(':kine') 61 | implementation "androidx.preference:preference-ktx:1.1.1" 62 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/request/MultiPartRequestBody.kt: -------------------------------------------------------------------------------- 1 | package com.kine.request 2 | 3 | import java.io.File 4 | import java.util.* 5 | 6 | class MultiPartRequestBody( 7 | var multiPartParams: HashMap = hashMapOf(), 8 | var multiPartFileParams: HashMap> = hashMapOf() 9 | ) : RequestBody() { 10 | 11 | fun addMultiPartFileParam(key: String, value: File, contentType: String? = null) { 12 | multiPartFileParams[key] = multiPartFileParams[key]?.apply {add( 13 | MultiPartFileBody( 14 | value, 15 | contentType 16 | ) 17 | )} 18 | ?:arrayListOf(MultiPartFileBody(value, contentType)) 19 | } 20 | 21 | fun addMultiPartParam(key: String, value: String, contentType: String? = null) { 22 | multiPartParams[key] = MultiPartStringBody(value, contentType) 23 | } 24 | fun addMultiPartFileParams(parts: HashMap, contentType: String? = null) { 25 | 26 | for ((key, file) in parts.entries) { 27 | val fileBodies: MutableList? = multiPartFileParams[key]?:ArrayList() 28 | fileBodies!!.add(MultiPartFileBody(file, contentType)) 29 | multiPartFileParams[key] = fileBodies 30 | } 31 | } 32 | fun addMultiPartFileListParams(parts: HashMap>, contentType: String? = null) { 33 | for ((key, fileList) in parts.entries) { 34 | val fileBodies: MutableList = multiPartFileParams[key] ?: ArrayList() 35 | for (file in fileList) { 36 | fileBodies.add(MultiPartFileBody(file, contentType)) 37 | } 38 | multiPartFileParams[key] = fileBodies 39 | } 40 | } 41 | fun addMultiPartParams(parts: HashMap, contentType: String? = null) { 42 | parts.apply { 43 | for ((key, stringBody) in this.entries) { 44 | multiPartParams[key] = MultiPartStringBody(stringBody, contentType) 45 | } 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /kine/src/main/java/com/kine/log/Logger.kt: -------------------------------------------------------------------------------- 1 | package com.kine.log 2 | 3 | import com.kine.extensions.getClassInstance 4 | 5 | 6 | /** 7 | * Helper class for logging. 8 | */ 9 | object Logger { 10 | private var level = LogLevel.NO_LOGS 11 | private var disabledLogs = false 12 | private var localLevel = LogLevel.NO_LEVEL 13 | private var log:Log= getDefaultLogger() 14 | 15 | private const val androidLoggerClass = "com.kine.android.log.Log" 16 | private fun getDefaultLogger(): Log { 17 | return androidLoggerClass.getClassInstance(JavaLog()) 18 | } 19 | fun setLevel(level: Int) { 20 | if (level != LogLevel.NO_LEVEL) { 21 | Logger.level = level 22 | } 23 | } 24 | 25 | fun setLocalLevel(level: Int) { 26 | if (level != LogLevel.NO_LEVEL) { 27 | localLevel = level 28 | } 29 | } 30 | 31 | fun e(tag: String?, message: String,exception: java.lang.Exception?=null) { 32 | if (LogLevel.isError(level, localLevel) && !disabledLogs) { 33 | log.e(tag, message,exception) 34 | } 35 | } 36 | 37 | fun v(tag: String?, message: String) { 38 | if (LogLevel.isVerbose(level, localLevel) && !disabledLogs) { 39 | log.v(tag, message) 40 | } 41 | } 42 | 43 | fun wtf(tag: String?, message: String) { 44 | if (!disabledLogs) { 45 | log.wtf(tag, message) 46 | } 47 | } 48 | 49 | fun d(tag: String?, message: String) { 50 | if (LogLevel.isDebug(level, localLevel) && !disabledLogs) { 51 | log.d(tag, message) 52 | } 53 | } 54 | 55 | fun i(tag: String?, message: String) { 56 | if (LogLevel.isInfo(level, localLevel) && !disabledLogs) { 57 | log.i(tag, message) 58 | } 59 | } 60 | 61 | fun w(tag: String?, message: String) { 62 | if (LogLevel.isWarning(level, localLevel) && !disabledLogs) { 63 | log.w(tag, message) 64 | } 65 | } 66 | 67 | fun printStackTrace(e: Exception) { 68 | if (!disabledLogs) { 69 | e.printStackTrace() 70 | } 71 | } 72 | 73 | fun setDisabledLogs(disabledLogs: Boolean) { 74 | Logger.disabledLogs = disabledLogs 75 | } 76 | } -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 23 | 24 |