我需要访问应用程序的上下文,但这样做会在第三行上显示“不要将Android上下文类放在静态字段中”。试图删除private val
但没有它我无法访问copyDatabase函数的上下文。
我需要上下文将assets文件夹中的数据库复制到应用程序的数据文件夹中。
class Database constructor(private val ctx: Context) : ManagedSQLiteOpenHelper(ctx, "dex.db", null, 1) {
companion object {
private var instance: Database? = null
@Synchronized
fun getInstance(ctx: Context): Database {
if (instance == null) {
instance = Database(ctx.applicationContext)
}
return instance!!
}
}
private fun copyDatabase() {
val input = ctx.assets.open("databases/dex.db")
FileOutputStream(ctx.getDatabasePath("dex.db").path).use { out ->
input.copyTo(out)
}
}
}
由于
答案 0 :(得分:1)
将public class Answer {
static class OlimpicSportEvent {
//private other field
//private other field
private final Sport sport;
private final Event event;
private final Phase phase;
OlimpicSportEvent(Sport sport, Event event, Phase phase) throws Exception{
this.sport = sport;
this.event = event;
this.phase = phase;
if(!this.validate()){
throw new Exception();
}
}
public Sport getSport() {
return sport;
}
public Event getEvent() {
return event;
}
public Phase getPhase() {
return phase;
}
private boolean validate(){
return this.sport.getEvents().contains(this.event);
}
}
public static void main(String[] args) {
try {
OlimpicSportEvent olSpEv = new OlimpicSportEvent(
Sport.ATHLETIC, Event.SPRINT_100_M, Phase.SEMIFINAL);
System.out.println("olSpEv created!");
// do whatever you want
} catch (Exception ex) {
System.out.println("olSpEv invalid!");
// handle ex
}
}
}
保留在Context
变量中会阻止垃圾收集器释放内存并导致内存泄漏。您应该将static
传递给构造函数并初始化其中的所有内容,而不应将其保留在变量中。
答案 1 :(得分:0)
通过使用companion object
,其生命周期等于加载的Database
类的生存期,您创建了在数据库实例中捕获的Context
与数据库实例之间的生命周期不匹配本身。
当您的应用程序被置于后台并恢复时,或者您只是旋转设备时,上下文(通常是Activity
实例)将被销毁而不会破坏整个应用程序,因此数据库实例将继续存在处置背景。这将可靠地导致应用程序失败。
尽管可能小心使用Application
上下文,而这很可能与生命周期相匹配,但保留上下文实例的一般做法是不明智的,因此警告
而是将数据库实例作为主活动类的属性,或者,提交使用依赖注入框架,将其作为一个单独的问题处理。
另外,您当前的代码使用了双重检查延迟初始化习惯用法的破坏变体。如果您需要延迟初始化,在Kotlin中,您应该始终将其保留给by lazy
属性委托,而不是自己滚动。