Kotlin中如何不传递Context跨类获取MainActivity的Context
问题修正
你当前代码里val context: Context = MainActivity::class的写法是错误的:MainActivity::class是Kotlin的类引用对象,属于KClass类型,根本不是Context实例,既无法通过编译,也会存在强持有Activity导致内存泄漏、空指针的风险。
访问SharedPreferences不需要依赖MainActivity的专属Context,使用应用级Context即可满足需求,以下是两种可直接落地的方案:
方案1:构造函数传参(最贴合你的使用场景)
你本身就是在MainActivity中调用方法构建列表,直接在创建类实例时把Context作为参数传入即可,类内部优先转存applicationContext,避免内存泄漏:
open class ListItems( open val title: String, // 保留你原有其他参数 ) class GameName( override val title: String, context: Context, // 保留你原有其他参数 ) : ListItems(title, active) { // 转存应用级Context,生命周期和App一致,不会泄漏 private val sp = context.applicationContext.getSharedPreferences("CompletedGames", Context.MODE_PRIVATE) init { // 直接读取SP数据即可,比如读取当前游戏的完成状态 val isCompleted = sp.getBoolean(title, false) // 实现你的其他业务逻辑 } }
在MainActivity中构建列表时直接传入当前Context即可:
// MainActivity内调用 val gameList = listOf( GameName("游戏1", this), GameName("游戏2", this) )
方案2:全局Application提供Context(适合多场景复用)
如果项目中有多处需要访问Context、操作SP,可以自定义Application类全局持有应用级Context,不用每次传参:
- 自定义Application类
class App : Application() { companion object { lateinit var appContext: Context private set } override fun onCreate() { super.onCreate() appContext = applicationContext } } - 在
AndroidManifest.xml中注册自定义Application<application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:theme="@style/Theme.YourAppName"> <!-- 原有Activity、Service等组件声明不变 --> </application> - 任意类中直接使用全局Context访问SP
class GameName( override val title: String, // 保留你原有其他参数 ) : ListItems(title, active) { private val sp = App.appContext.getSharedPreferences("CompletedGames", Context.MODE_PRIVATE) init { // 直接操作SP即可 } }
注意事项
- 不要通过静态变量、单例强持有MainActivity实例,当Activity因屏幕旋转、退到后台被销毁时,持有的旧实例会造成内存泄漏,甚至在访问时触发空指针崩溃
- 操作SharedPreferences、读取全局资源这类通用场景,用应用级Context完全可以满足需求,不需要绑定特定Activity的Context
内容的提问来源于stack exchange,提问作者Rory Nesbitt
相关产品推荐
相关产品推荐

