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)
}
複製代碼
dependencies {
implementation 'com.github.DonaldDu:DynamicServer:x.x.x'//JitPack version
}
複製代碼
到此就基本實現動態服務地址功能了,詳細代碼請參考demo
若是一個項目中沒有明確說明要加Proguard代碼,則表示項目已經處理或不須要處理。
我以爲全部(開源或私有)項目打包中都應該包含Proguard代碼,而不是寫在文檔中,讓用戶本身加。JAR都支持帶Proguard打包了。
開源不易,寫文章更不易,勞煩你們給本文點個贊,能夠的話,再給個star,感激涕零