如何在不使用Context的前提下在Presenter类中完成字符串提取?
推荐方案:将字符串解析逻辑下沉到View层
Presenter只负责业务逻辑判断,输出字符串构造规则和参数,由持有Context的View层负责最终字符串加载,完全规避Presenter持有Context的风险。
针对你的业务场景,Presenter可以直接返回标识类型和对应参数,示例逻辑如下:
// Presenter 层逻辑,不涉及任何Context相关操作 sealed class TestLineState { object Empty : TestLineState() data class MultiItem(val count: Int) : TestLineState() data class SingleItem(val name: String?) : TestLineState() } fun getTestLineState(sourceIds: List<*>, newMembers: NewMembers?): TestLineState { return when { sourceIds.isEmpty() -> TestLineState.Empty sourceIds.size > 1 -> TestLineState.MultiItem(sourceIds.size) else -> TestLineState.SingleItem(newMembers?.getNameForId(sourceIds[0])) } }
然后在View层(Activity/Fragment)接收状态后渲染:
// View层逻辑,自有Context无需额外传递 when(val state = presenter.getTestLineState(sourceIds, newMembers)) { is TestLineState.Empty -> testLine = "" is TestLineState.MultiItem -> testLine = getString(R.string.multi_test_format, state.count) is TestLineState.SingleItem -> testLine = state.name.orEmpty() }
对应的strings.xml定义:
<string name="multi_test_format">%d test</string>
备选方案:抽象字符串资源接口隔离Context依赖
如果确实需要在Presenter层直接拿到拼接完成的字符串,可以通过依赖注入的方式传入抽象的字符串资源实例,Presenter只依赖接口不直接持有Context:
- 首先定义通用字符串获取接口:
interface StringResourceProvider { fun getString(@StringRes resId: Int, vararg args: Any): String }
- 实现层用Application Context构造,不会产生内存泄漏:
class AndroidStringResourceProvider(private val appContext: Context) : StringResourceProvider { override fun getString(resId: Int, vararg args: Any): String { return appContext.getString(resId, *args) } }
- 将接口实例注入到Presenter中直接使用即可:
class TestPresenter(private val stringProvider: StringResourceProvider) { fun getTestLine(sourceIds: List<*>, newMembers: NewMembers?): String { return when { sourceIds.isEmpty() -> "" sourceIds.size > 1 -> stringProvider.getString(R.string.multi_test_format, sourceIds.size) else -> newMembers?.getNameForId(sourceIds[0]).orEmpty() } } }
注意:实现类必须传入Application Context,不能传入Activity/Fragment的Context,从根源避免内存泄漏问题。
内容的提问来源于stack exchange,提问作者user13305594
相关产品推荐
相关产品推荐

