Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin-在Android中转换Singleton DatabaseController的最佳方法_Android_Kotlin - Fatal编程技术网

Kotlin-在Android中转换Singleton DatabaseController的最佳方法

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

我正在从“Kotlin in in Action”学习Kotlin,我正在慢慢地将Android应用程序代码转换成它。但是我在转换下面的类时发现了一些问题

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方法为例显示伴生对象,所以我不确定什么是真正有效的,什么是无效的。