如何无需实例化类即可在Kotlin类间传值:MainActivity向ServiceBuilder传字符串
解决方案
核心思路:调整ServiceBuilder单例的初始化时机,支持运行时传入baseUrl参数,全程内存传递无额外IO开销,符合你的要求。
第一步:修改ServiceBuilder实现
你现在用的Kotlin object 是饿汉单例,类加载时就会初始化所有属性,原来的const val URL是编译期常量,天然不支持接收运行时从Activity传递的动态值,需要调整为懒加载逻辑:
object ServiceBuilder { // 移除原有的硬编码常量URL,改为私有可变参数 private var baseUrl: String? = null // 与baseUrl无关的通用配置保留原有初始化逻辑 private val logger = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY) val headerInterceptor = object: Interceptor { override fun intercept(chain: Interceptor.Chain): Response { var request = chain.request() request = request.newBuilder() .addHeader("x-device-type", Build.DEVICE) .addHeader("Accept-Language", Locale.getDefault().language) .build() return chain.proceed(request) } } private val okHttp = OkHttpClient.Builder() .callTimeout(5, TimeUnit.SECONDS) .addInterceptor(headerInterceptor) .addInterceptor(logger) // Retrofit改为懒加载,只有第一次调用buildService时才会初始化 private val retrofit: Retrofit by lazy { checkNotNull(baseUrl) { "请先调用ServiceBuilder.init()传入baseUrl" } Retrofit.Builder() .baseUrl(baseUrl!!) .addConverterFactory(GsonConverterFactory.create()) .client(okHttp.build()) .build() } // 对外暴露初始化方法,接收从外部传入的URL fun init(url: String) { // 防止重复初始化,如需支持动态切换BaseUrl可去掉这个判断,新增reset方法清空原有实例 if (baseUrl == null) { baseUrl = url } } fun <T> buildService(serviceType: Class<T>): T { return retrofit.create(serviceType) } }
第二步:在MainActivity中传递参数
只需要在第一次调用buildService之前,调用初始化方法传入你的字符串即可,不需要持有Activity实例,也没有额外开销:
class MainActivity : AppCompatActivity() { // 你需要传递的目标字符串 private val targetUrl = "https://你要传递的链接地址.com" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // 先初始化ServiceBuilder传入参数 ServiceBuilder.init(targetUrl) // 后续正常调用buildService即可 // val apiService = ServiceBuilder.buildService(你的Api接口::class.java) } }
方案说明
- 全程内存传值,无SP、数据库等IO操作,性能无损耗
- 不需要持有Activity实例,不会造成内存泄漏
- 依赖Kotlin懒加载特性,Retrofit全局只会初始化一次,无重复创建开销
- 内置初始化校验,避免未传参就调用的崩溃问题
- 如果后续有动态切换BaseUrl的需求,只需新增reset方法清空原有
baseUrl和retrofit实例即可支持重新初始化
内容的提问来源于stack exchange,提问作者Vando
相关产品推荐
相关产品推荐

