Android 如何使SQLite连接更高效

Android 如何使SQLite连接更高效,android,sqlite,android-sqlite,Android,Sqlite,Android Sqlite,在活动运行的整个过程中保持本地sqlite连接打开有什么好处吗 我通常创建一个新连接,然后在执行数据库操作的每个方法中关闭它。它看起来像这样: myMethod(Context context){ LocalDBHelper localDBHelper = new LocalDBHelper(context); //extended SQLiteOpenHelper SQLiteDatabase db = localDBHelper.getWritableDatabase();

在活动运行的整个过程中保持本地sqlite连接打开有什么好处吗

我通常创建一个新连接,然后在执行数据库操作的每个方法中关闭它。它看起来像这样:

myMethod(Context context){
    LocalDBHelper localDBHelper = new LocalDBHelper(context); //extended SQLiteOpenHelper 
    SQLiteDatabase db = localDBHelper.getWritableDatabase();
    ...
    localDBHelper.close();
}

因此,在典型的用户会话中,这种情况会发生大约10次。在
onResume()
中创建一个连接,在所有数据库访问方法中使用该连接,并最终在
onPause()
中关闭它是否有意义?

我个人发现调用初始应用程序加载所需的SQL连接更容易,存储到SQLite数据库中,或者设置一个刷新按钮,让用户决定何时刷新数据,或者为应用程序设置一个定期更新间隔计时器

通过这种方式,您可以在预先/用户定义的时间内加载数据,从而提高应用程序的一般使用期间的性能

虽然我认为这取决于DB交互的执行频率

这个问题可能会给你一些有用的答案:


就我个人而言,我发现调用初始应用程序加载所需的SQL连接、存储到SQLite数据库、设置刷新按钮供用户决定何时刷新数据或为应用程序设置定期更新间隔计时器更容易

通过这种方式,您可以在预先/用户定义的时间内加载数据,从而提高应用程序的一般使用期间的性能

虽然我认为这取决于DB交互的执行频率

这个问题可能会给你一些有用的答案:


由于您的应用程序每次都在同一台机器上运行,并且每次都访问相同的内存,因此打开它不会有任何问题。因为在相同的内存空间中,sqlite就像主应用程序的DLL一样加载


可能只会出现一个问题!当您想同时运行多个线程来访问数据库时(例如使用AsyncTask),它们之间的干扰会迫使一些线程停止!因此,最好每次都为新线程建立连接

由于您的应用程序每次都在同一台机器上运行,并且每次都访问相同的内存,因此打开它不会有任何问题。因为在相同的内存空间中,sqlite就像主应用程序的DLL一样加载

可能只会出现一个问题!当您想同时运行多个线程来访问数据库时(例如使用AsyncTask),它们之间的干扰会迫使一些线程停止!因此,最好每次都为新线程建立连接

在活动运行的整个过程中保持本地sqlite连接打开有什么好处吗

在整个过程中,您通常需要一个“连接”。特别是,您不希望跨多个线程同时使用多个“连接”。Android中SQLite的所有线程安全逻辑都基于对所有这些线程使用单个
SQLiteDatabase
(因此,使用单个
SQLiteOpenHelper
),因此可以进行适当的锁定

在活动运行的整个过程中保持本地sqlite连接打开有什么好处吗


在整个过程中,您通常需要一个“连接”。特别是,您不希望跨多个线程同时使用多个“连接”。Android中SQLite的所有线程安全逻辑都基于对所有这些线程使用单个
SQLiteDatabase
(因此,使用单个
SQLiteOpenHelper
),因此可以进行适当的锁定。

基于@commonware answer,我已经实现了一个单例模式,使用惰性实例化来拥有一个应用程序范围的
LocalDBHelper
实例。到目前为止,它工作得很好,并且避免了每次操作都需要实例化和关闭助手/数据库

public class MyApplication extends Application{
    private static MyApplication instance;
    public MyApplication(){
        instance = this;
    }
    public static Context getContext(){
        return instance;
    }
}

public class LocalDBHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "MyDB";
    private static final String LOG_TAG = "LocalDBHelper";

    private static LocalDBHelper instance = null;
    /*private constructor to avoid direct instantiation by other classes*/
    private LocalDBHelper(){
        super(MyApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
    }
    /*synchronized method to ensure only 1 instance of LocalDBHelper exists*/
    public static synchronized LocalDBHelper getInstance(){
        if(instance == null){
            instance = new LocalDBHelper();
        }
        return instance;
    }
    ...
    ...
}
用法:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.insert(...)
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();
与事务一起使用:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.insert(...)
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();
}


重要提示:无需调用
localDBHelper.getInstance().close()
anywhere

基于@commonware answer,我实现了一个单例模式,使用惰性实例化来拥有
localDBHelper
的单个应用程序范围实例。到目前为止,它工作得很好,并且避免了每次操作都需要实例化和关闭助手/数据库

public class MyApplication extends Application{
    private static MyApplication instance;
    public MyApplication(){
        instance = this;
    }
    public static Context getContext(){
        return instance;
    }
}

public class LocalDBHelper extends SQLiteOpenHelper{
    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "MyDB";
    private static final String LOG_TAG = "LocalDBHelper";

    private static LocalDBHelper instance = null;
    /*private constructor to avoid direct instantiation by other classes*/
    private LocalDBHelper(){
        super(MyApplication.getContext(), DATABASE_NAME, null, DATABASE_VERSION);
    }
    /*synchronized method to ensure only 1 instance of LocalDBHelper exists*/
    public static synchronized LocalDBHelper getInstance(){
        if(instance == null){
            instance = new LocalDBHelper();
        }
        return instance;
    }
    ...
    ...
}
用法:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.insert(...)
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();
与事务一起使用:

SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.insert(...)
SQLiteDatabase db = LocalDBHelper.getInstance().getWritableDatabase();
db.beginTransaction();
try{
....
...
db.setTransactionSuccessful();
}catch(Exception e){
    e.printStackTrace();
}
finally{
    db.endTransaction();
}


重要提示:无需调用
localDBHelper.getInstance().close()
anywhere

很抱歉,我意识到我的问题有误导性,因此我已将其更改为更清楚。如果应用程序中没有远程SQL访问,那么创建长期本地SQLite连接是否有意义?如果没有远程SQL访问,我认为这不会是一个问题,但是,如果应用程序在前一个活动中打开时尝试在数据库上运行任何函数,则可能会引发一两个错误。这里的一些答案可能对您有用:)我不认为跨活动会出现问题,因为我将在
onPause()
中关闭连接。啊,我明白了。。。老实说,我当时看不到任何问题,但也许其他用户可能有一些我不知道的见解:)抱歉,我意识到我的问题有误导性,所以我将其更改为更清楚。如果应用程序中没有远程SQL访问,那么创建长期本地SQLite连接是否有意义?如果没有远程SQL访问,我认为这不会是一个问题,但是,如果应用程序在前一个活动中打开时尝试在数据库上运行任何函数,则可能会引发一两个错误。这里的一些答案可能对您有用:)我不认为跨活动会出现问题