DynamicServer動態配置服務(真香!)

GithubLinkjava

測試員:服務地址臨時修改成‘xx’,幫打個包吧!android

遇到這種需求,你們通常怎麼解決呢?git

若是隻是一兩次,直接修改代碼就成。github

常常須要調整服務地址的話,最好仍是弄個工具。由於多個App中都常常須要切換正式和測試服務,因此寫了個工具,方便複用。api

有時測試須要不一樣角色帳號來驗證功能,因此也實現了內置多個帳號的功能,方便快速登陸。瀏覽器

可是建議測試帳號不要寫在代碼中,而是經過建立的樣例模板在瀏覽器中建立真實數據。markdown

枚舉服務地址

經過枚舉的方式把已知的服務地址集合到一塊兒。網絡

在構造函數中聲明任意多個服務類型(正式,測試,公測,預發佈等),並重寫toString方法。app

不能在枚舉中聲明String類型的其它變量,由於工具中默認全部String類型的變量都爲服務類型。ide

enum class DynamicServer(private val release: String, private val test: String) {
    APP_BASE("http://www.app.com", "http://192.168.141.34:8093"),
    USER_CENTER("http://www.user.com", "http://192.168.141.34:8094"),
    ;

    override fun toString(): String {
        return RemoteConfig.serverMap[name] ?: release
    }
}
複製代碼

讀取註解

新建一個註解類,並註解須要動態地址的服務,其它的使用BaseUrl註解。

@Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME)
annotation class DynamicBaseUrl(
    val value: DynamicServer,
    /**
     * append to value, auto check separator of '/'
     */
    val append: String = ""
)

@DynamicBaseUrl(DynamicServer.APP_BASE)
interface AppApi {
    @GET("login")
    fun login(): Observable<String>
}
複製代碼

新建一個工具類,並重寫getUserBaseUrl方法

class ApiUtil : ApiHolderUtil<ApiHolder>(ApiHolder::class) {
    companion object {
        val apiUtil = ApiUtil()
        val api = apiUtil.api
    }

    override fun getUserBaseUrl(cls: Class<*>): BaseUrlData {
        val baseUrl = cls.getAnnotation(DynamicBaseUrl::class.java)
        return if (baseUrl != null) BaseUrlData(baseUrl.value.release(), baseUrl.append)
        else {
            throw IllegalArgumentException(String.format("%s: MUST ANNOTATE WITH 'BaseUrl'", cls.name))
        }
    }
}
複製代碼

初始化

應用啓動時,調用 init() 初始化工具。須要更新時,調用updateServer()

enum class DynamicServer(private val release: String, private val test: String) {
    companion object {
        fun init(context: Context) {
            if (BuildConfig.DEBUG) {
                RemoteConfig.initDynamicServer(DynamicServer::class.java)
                updateServer(context.getUsingTestServer())
            }
        }

        fun updateServer(config: RemoteConfig, context: Context? = null) {
            config.updateServerMap(context)
            config.toServers().forEach {
                if (it.releaseValue != null) apiUtil.updateApi(it.releaseValue!!, it.value)
            }
        }
    }
}
複製代碼

手動切換服務

在登陸頁面中建立TestServerUtil實例並重寫onConfigSelected方法

val server = object : TestServerUtil(context, api) {
        override fun onConfigSelected(config: RemoteConfig) {
            DynamicServer.updateServer(config, context)
            tvServers.updateServerLabel(config)
        }
    }
    server.initShowOnClick(tvServers, true)
    tvServers.updateServerLabel(getUsingTestServer())
複製代碼

在設置頁面顯示當前使用的服務地址

tvServers.updateServerLabel(getUsingTestServer())
複製代碼

動態網頁地址

若是一些網頁地址是動態的,也能夠定義到枚舉中。

fun showUserPage() {
        val host = DynamicServer.USER_CENTER
        println("$host/userPage")
    }
複製代碼

遠程配置

推薦:一直免費用Leancloud的開發版服務,怪很差意思的,推薦你們試試看,真心不錯,除了有點小貴外!

之前作了個自家測試版App下載功能,文件流量超了花掉十多塊,其它基本沒花過錢!

若是須要遠程配置功能,須要在 Leancloud 上建立一個(免費)應用,不須要則忽略此項。

找到應用下路徑: 設置/應用Keys/Credentials,把AppID和MasterKey配置到應用中。

android {
    buildTypes {
        debug {
            resValue "string", "X_LC_ID", "AppID"
            resValue "string", "X_LC_KEY", "MasterKey"
        }
        release {
            resValue "string", "X_LC_ID", ""
            resValue "string", "X_LC_KEY", ""
        }
    }
}
複製代碼

若是多個應用都須要,能夠把配置信息寫到Gradle全局腳本中。

C:\Users\{用戶名}\.gradle\init.gradle

allprojects {
    ext {
        X_LC_ID = "AppID"
        X_LC_KEY = "MasterKey"
        
        INIT_X_LC_ID_KEY = {
            buildTypes {
                debug {
                    resValue "string", "X_LC_ID", findProperty('X_LC_ID') ?: ""
                    resValue "string", "X_LC_KEY", findProperty('X_LC_KEY') ?: ""
                }
                release {
                    resValue "string", "X_LC_ID", ""
                    resValue "string", "X_LC_KEY", ""
                }
            }
        }
    }
}
複製代碼

在app項目中以下調用

android {
    if (project.hasProperty('INIT_X_LC_ID_KEY')) android.with(INIT_X_LC_ID_KEY)
}
複製代碼

添加依賴 JitPack

dependencies {
    implementation 'com.github.DonaldDu:DynamicServer:x.x.x'//JitPack version
}
複製代碼

到此就基本實現動態服務地址功能了,詳細代碼請參考demo


Proguard

若是一個項目中沒有明確說明要加Proguard代碼,則表示項目已經處理或不須要處理。

我以爲全部(開源或私有)項目打包中都應該包含Proguard代碼,而不是寫在文檔中,讓用戶本身加。JAR都支持帶Proguard打包了。

個人其它開源項目

最後

開源不易,寫文章更不易,勞煩你們給本文點個贊,能夠的話,再給個star,感激涕零

相關文章
相關標籤/搜索