代理模式是开发中很常用的设计模式,此模式主要有两个部分,一部分是代理部分,一部分是真实部分.

代理模式的官方解释是:为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
实现代理模式有两种方案:静态代理和动态代理。静态代理是指代理类在编译期就已经确定,即需要事先手动编写一个代理类。动态代理则是在运行时动态生成代理类。
这里带给大家一个动态代理一个很实用的开发技巧:动态设置Release包和Debug包的配置,以解决开发中频繁手动切换正式服和测试服服务器地址等功能,当然还可以通过这个扩展很多动态切换的功能.此处只是举一个例子.
接口代码:
interface HttpApi : Environment {
@Test("test.w3cvs.com")
@Product("release.w3cvs.com")
fun baseUrl():String
}
动态代理环境代码:
enum class Env {
Test,Product
}
interface Environment{
fun env():Env
}
object EnvironmentUtil {
lateinit var env: Env
fun init(envStr: String) {
env = Env.valueOf(envStr)
Log.w(this::class.java.simpleName, "init ---> envStr:$envStr env:${env.name}")
}
inline fun <reified T : Environment> get(): T {
val clazz = T::class.java
println("env clazz content $clazz")
require(clazz.isInterface) { "API declarations must be interfaces." }
return Proxy.newProxyInstance(
clazz.classLoader, arrayOf(clazz), object : InvocationHandler {
override fun invoke(proxy: Any, method: Method, args: Array<out Any>?): Any {
if (method.name == "env") return env
when (val annotation =
method.annotations.find { it.annotationClass.simpleName == env.name }) {
is Product -> return annotation.value
is Test -> return annotation.value
}
return ""
}
}
) as T
}
}
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class (val value: String)
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class Product(val value: String)
Application代码: 此处别忘记设置清单文件中的 android:name=".App"
class App : Application(){
private var context : Context? = null
override fun onCreate() {
super.onCreate()
context = this
EnvironmentUtil.init(BuildConfig.Env)
}
}
MainActivity代码:
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
Log.d("${this.componentName}", EnvironmentUtil.get<HttpApi>().baseUrl())
Log.d("${this.componentName}", EnvironmentUtil.env.name)
}
}
build.gradle(:app)
android {
compileSdk 31
defaultConfig {
applicationId "com.yaoyu.dynamicproxydemo"
minSdk 23
targetSdk 31
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
//在apk文件后边生成版本号信息
applicationVariants.all { variant ->
variant.outputs.all { output ->
def outputFile = output.outputFile
def fileName = ""
if (outputFile != null && outputFile.name.endsWith('.apk')) {
if (variant.buildType.name == 'release') {
fileName = "ProxyDemo_release_${defaultConfig.versionName}_${new Date().format("yyyyMMdd")}.apk"
} else if (variant.buildType.name == 'debug') {
fileName = "ProxyDemo_${defaultConfig.versionName}_${new Date().format("yyyyMMdd")}_debug.apk"
}
output.outputFileName = fileName
}
}
}
signingConfigs{
release{
File strFile = new File("你的签名路径:")
storeFile file(strFile)
storePassword "你的storePassword "
keyPassword "你的keyPassword "
keyAlias "你的keyAlias "
}
}
buildTypes {
release {
minifyEnabled false
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
buildConfigField "String", "Env", "\"$RELEASE_ENV\""
}
debug {
// signingConfig signingConfigs.debug
buildConfigField "String", "Env", "\"$DEBUG_ENV\""
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
注:红色代码是是关键代码,蓝色代码是需要替代成你自己的
2655

被折叠的 条评论
为什么被折叠?



