Kotlin-在Android中转换Singleton DatabaseController的最佳方法
我正在从“Kotlin in in Action”学习Kotlin,我正在慢慢地将Android应用程序代码转换成它。但是我在转换下面的类时发现了一些问题Kotlin-在Android中转换Singleton DatabaseController的最佳方法,android,kotlin,Android,Kotlin,我正在从“Kotlin in in Action”学习Kotlin,我正在慢慢地将Android应用程序代码转换成它。但是我在转换下面的类时发现了一些问题 public class DatabaseController { private static DatabaseController sDatabaseController; private SQLiteDatabase mDatabase; private DatabaseController(Context contex
public class DatabaseController {
private static DatabaseController sDatabaseController;
private SQLiteDatabase mDatabase;
private DatabaseController(Context context) {
mDatabase = new SQLiteOpenHelperImpl(context.getApplicationContext())
.getWritableDatabase();
}
public static DatabaseController getDatabaseController(Context context) {
if (sDatabaseController == null) {
sDatabaseController = new DatabaseController(context);
}
return sDatabaseController;
}
public void addElement(Element element) {
if (element != null) {
ContentValues values = getContentValues(element);
mDatabase.beginTransaction();
try {
// insert element
mDatabase.setTransactionSuccessful();
} finally {
mDatabase.endTransaction();
}
}
}
我提出了两种不同的Kotlin实现,但它们都不能完全说服我。哪一个可以被认为是更好的解决方案?还是存在第三个更好的
第一个使用对象的实现
object DatabaseControllerObject {
private var mDatabase : SQLiteDatabase? = null
fun initDatabase(context: Context) {
mDatabase = mDatabase?: SQLiteOpenHelperImpl(context.applicationContext).writableDatabase
}
fun addElement(context: Context, element: Element) {
initDatabase(context)
// insert alarm
mDatabase?.let {
// CODE
}
}
第二个实现是将所有内容都放在一个文件中,我在每个需要数据库的活动的onCreate()中调用initDatabase(..)
private var mDatabase: SQLiteDatabase? = null
fun initDatabase(context: Context) {
mDatabase = mDatabase ?: SQLiteOpenHelperImpl(context.applicationContext).writableDatabase
}
fun addElement(element: Element) {
val values = getContentValues(element)
mDatabase?.let {
it.beginTransaction()
try {
// insert
it.setTransactionSuccessful()
} finally {
it.endTransaction()
}
}
}
我想你想要的是一个伴星:
class DatabaseController
{
private constructor(context: Context)
{
// ...
}
companion object
{
private var instance: DatabaseController? = null
fun getInstance(context: Context): DatabaseController
{
if(instance == null)
{
instance = DatabaseController(context)
}
return instance!!
}
}
}
那么你可以这样称呼它:
val databaseController = DatabaseController.getInstance(context)
为什么你不能使用一个带有适当可见性修饰符的类?@CaseyB抱歉,从这个意义上讲?对不起,我误解了你的意图。您希望使数据库控制器具有一个返回自身实例的静态方法,对吗?@CaseyB yes,以便隐藏SQLiteDatabase。主要的问题是,对于Kotlin,我没有找到它的任何官方翻译。我添加了一个答案,可以满足您的要求。它几乎是Java的一个直接端口。您还可以在类声明中定义构造函数:class DatabaseController(val-context:context){…}并定义一个init{…}块。我对这个解决方案唯一的疑问是:伴随对象的工作方式类似于Java中的静态字段,对吗?所以,它不会每次都实例化“instance”,对吗?它会在第一次调用getInstance时实例化instance。之后它将返回现有实例。非常感谢!!“Kotlin in Action”欺骗了我,因为它以singleton为例显示对象,而以factory方法为例显示伴生对象,所以我不确定什么是真正有效的,什么是无效的。