如何在Android 2.x中强制串行/顺序执行AsyncTasks

卡洛延·鲁塞夫(Kaloyan Roussev)

如果我没记错的话,有几种Android API(在甜甜圈之后和蜂窝之前),其中Google启用了AsyncTasks并行运行,旨在更快地执行。然后,许多开发人员在使用多个AsyncTasks到达同一数据库时犯了错误,并且由于默认情况下Android 3.0 AsyncTasks串行运行。

我现在在使用SQLite在Android 2.3.4设备上测试我的应用程序时遇到了这个问题

  • 首先,我从服务器获取类别,然后打开数据库,将其插入以关闭数据库。

  • 其次,我从服务器获取子类别,打开数据库,将其插入数据库,关闭数据库

  • 第三,我从服务器获取用户项目,打开数据库,插入项目,然后关闭数据库

我小心翼翼地确保一个接一个地启动,但是在每8-10次迭代中,某个位置在某个任务打开db的那一刻,某个地方的速度变慢并与另一个过程重叠,另一个任务紧随其后关闭,然后第一个任务关闭任务开始尝试写入已关闭的数据库。

我该怎么办?我想要干净,可靠的分离,顺序执行,并且我不想从以前的asynctask的onPostExecute开始asynctask,因为这三个命令不会总是连续运行

昨天我读了一篇文章,您无法在android 2.x上执行此操作

我是否应该在所有操作之前尝试打开数据库和DBHelper,然后再关闭数据库?

编辑:通常我在这里(在Begin事务处)收到错误:(错误表明数据库已关闭)

@Override
protected Void doInBackground(Void... arg0) {

    // dbTools.close();

    try {
        if (database == null) {
            database = dbTools.getWritableDatabase();
        }
    } catch (Exception e) {
        e.printStackTrace();

    }

    ContentValues values = new ContentValues();

    database.beginTransaction();

    try {

        // Iterating all UserItem objects from the LinkedHashSet and getting their info
        for (UserItem userItem : userItems) {


            // Inserting values for the database to insert in a new record
            values.put(C.DBColumns.ITEM_ID, userItem.getItemId());
            values.put(C.DBColumns.ITEM_NAME, userItem.getItemName());


            // database.insertWithOnConflict(C.DBTables.ITEMS, null, values, SQLiteDatabase.CONFLICT_REPLACE);
            database.insert(C.DBTables.ITEMS, null, values);

        } // End of For loop

        database.setTransactionSuccessful();

    } finally {

        database.endTransaction();

    }

    // Closing all cursors, databases and database helpers properly because not closing them can spring lots of trouble.
    if (database != null && database.isOpen()) {
        try {
            database.close();

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    return null;

} // End of doInBackground

这是我的DBTOOLS类别:

public class DBTools extends SQLiteOpenHelper {

    // Its a good practice for DBTools to be a singleton. Do not instantiate it with "new DBTools(context)" but with
    // DBTools.getInstance(context) instead
    private static DBTools sInstance;

    public static DBTools getInstance(Context context) {

        if (sInstance == null) {
            sInstance = new DBTools(context);
        }
        return sInstance;
    }

    public DBTools(Context context) {
        super(context, C.Preferences.LOCAL_SQLITE_DATABASE_NAME, null, 1);
    }

    public void onCreate(SQLiteDatabase database) {
        database.execSQL(SQLQueries.tableCategoriesCreate);
        database.execSQL(SQLQueries.tableSubcategoriesCreate);
        database.execSQL(SQLQueries.tableItemsCreate);
    }

    public void onOpen(SQLiteDatabase database) {
        database.execSQL(SQLQueries.tableCategoriesCreate);
        database.execSQL(SQLQueries.tableSubcategoriesCreate);
        database.execSQL(SQLQueries.tableItemsCreate);
    }

    public void onUpgrade(SQLiteDatabase database, int version_old, int current_version) {
        database.execSQL(SQLQueries.tableCategoriesDrop);
        database.execSQL(SQLQueries.tableSubcategoriesDrop);
        database.execSQL(SQLQueries.tableItemsDrop);
        onCreate(database);
    }

} // End of Class
Ben

由于您无法通过onPostExecute进行调用,因此我想您有两种选择,一种是将打开关闭调用移至活动或服务的开始和结束。

第二种方法是在DB和DBHelper中设置一个参考计数器,在其中跟踪打开被调用的次数,然后在调用关闭时减少该计数。这样,仅当计数为0时才可以执行关闭操作。采用这种方法时要记住的一件事是,您可能应该有一个方法,当您确定其他连接已完成时,该方法将强制数据库关闭。这不是必须的,但是可以确保故障发生时关闭数据库。

编辑:您必须使DBTools成为单例才能正常工作,但这不是等效的。这是一个简单的例子。

public class DBTools {
   private static DBTools instance;
   private static int openCount;

   public DBTools getInstance() {
     if (instance == null) {
       instance = new DBTools();
     }
     return instance;
   }

   private DBTools() {
     openCount = 0;
   }

   public void open() {
     openCount++;
     //Do open 
   }

   public close() {
     openCount--;
     if (openCount == 0) {
        //Do close
     }

   public void forceDBClose() {
      //Do close 
   }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在Play 2.x中强制执行JSON的严格序列化

来自分类Dev

如何在android中的viewpager2中删除对象?

来自分类Dev

如何在android中显示2位数字的NumberPicker?

来自分类Dev

如何在Android中解复用MP2TS?

来自分类Dev

如何在Intent Android中传递2个文件

来自分类Dev

如何在Android中动态创建2列布局?

来自分类Dev

如何在Android中的2个任务之间放置延迟?

来自分类Dev

如何在Android中同时运行2个线程

来自分类Dev

如何在 Android Camera2 中不断拍照?

来自分类Dev

如何在 Android 中配置 OAuth2 连接?

来自分类Dev

如何在Samba中强制执行SMB2协议?

来自分类Dev

如何在1个Android.mk中创建2个可执行文件

来自分类Dev

Java:如何在2x2 GridLayout中更改JLabel的顺序?

来自分类Dev

如何在AFNetworking 2中执行AFHTTPRequestOperation

来自分类Dev

如何在ggplot2中的方面之间强制使用常见的x轴标签/限制?

来自分类Dev

如何在android studio中的2行中设置2个单词

来自分类Dev

如何通过php在json中传递2数组以及如何在android中解析它

来自分类Dev

如何在SQL(Postgres)中强制执行过滤器评估顺序?

来自分类Dev

如何在go框架中为不同的测试强制执行测试顺序?

来自分类Dev

Angular 2 Material:如何在模态中强制对齐元素?

来自分类Dev

如何在Android设备上调试cocos2d-x 3本机代码

来自分类Dev

如何在Cocos2d-x中使用Android Studio

来自分类Dev

如何在eclipse ADT中将cocos2d-x android项目转换为c ++

来自分类Dev

如何在Android和iOS设备上为cocos2d-x 3.2添加振动?

来自分类Dev

如何在Cocos2d-x上使用Android Studio

来自分类Dev

如何在KVM上运行Android-x86以获得更好的2D图形性能?

来自分类Dev

如何在Android中的Retrofit 2的'Body'参数中传递字符串

来自分类Dev

如何在Android中水平等距的2行中显示6个项目

来自分类Dev

如何在Android中以等距的水平方式在2行中显示6个项目

Related 相关文章

  1. 1

    如何在Play 2.x中强制执行JSON的严格序列化

  2. 2

    如何在android中的viewpager2中删除对象?

  3. 3

    如何在android中显示2位数字的NumberPicker?

  4. 4

    如何在Android中解复用MP2TS?

  5. 5

    如何在Intent Android中传递2个文件

  6. 6

    如何在Android中动态创建2列布局?

  7. 7

    如何在Android中的2个任务之间放置延迟?

  8. 8

    如何在Android中同时运行2个线程

  9. 9

    如何在 Android Camera2 中不断拍照?

  10. 10

    如何在 Android 中配置 OAuth2 连接?

  11. 11

    如何在Samba中强制执行SMB2协议?

  12. 12

    如何在1个Android.mk中创建2个可执行文件

  13. 13

    Java:如何在2x2 GridLayout中更改JLabel的顺序?

  14. 14

    如何在AFNetworking 2中执行AFHTTPRequestOperation

  15. 15

    如何在ggplot2中的方面之间强制使用常见的x轴标签/限制?

  16. 16

    如何在android studio中的2行中设置2个单词

  17. 17

    如何通过php在json中传递2数组以及如何在android中解析它

  18. 18

    如何在SQL(Postgres)中强制执行过滤器评估顺序?

  19. 19

    如何在go框架中为不同的测试强制执行测试顺序?

  20. 20

    Angular 2 Material:如何在模态中强制对齐元素?

  21. 21

    如何在Android设备上调试cocos2d-x 3本机代码

  22. 22

    如何在Cocos2d-x中使用Android Studio

  23. 23

    如何在eclipse ADT中将cocos2d-x android项目转换为c ++

  24. 24

    如何在Android和iOS设备上为cocos2d-x 3.2添加振动?

  25. 25

    如何在Cocos2d-x上使用Android Studio

  26. 26

    如何在KVM上运行Android-x86以获得更好的2D图形性能?

  27. 27

    如何在Android中的Retrofit 2的'Body'参数中传递字符串

  28. 28

    如何在Android中水平等距的2行中显示6个项目

  29. 29

    如何在Android中以等距的水平方式在2行中显示6个项目

热门标签

归档