Android的SQLiteDB未完成增加值 [英] Android SQLiteDB doesn't finish adding values

查看:186
本文介绍了Android的SQLiteDB未完成增加值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的SQLiteDatabase是给我一些麻烦。当用户关闭应用程序,在的onPause()的AsyncTask的开始保存数据。我不知道这是否是做的最好的方式,但我做的方式是,首先将数据库中删除所有现有的数据(这不是两个表之间的太多,也许20-30值),然后添加新的数据备份到数据库中。

该deleteAll()方法工作得很好,但是当它尝试添加的每个项目,它的第六届相继失败。

这是我的doInBackground()的AsyncTask的方法:

  @覆盖
    保护无效doInBackground(无效参数... args)
    {
        //打开数据库
        尝试
        {
            myDbHelper.openDatabase();
        }赶上(的SQLException SQLE)
        {
            扔SQLE;
        }        myDbHelper.deleteAll();        //加入所有材料和放大器;单位
        的for(int i = 0; I< ingredients.size();我++)
            myDbHelper.addIngredient(ingredients.get(I));
        的for(int i = 0; I< units.size();我++)
            myDbHelper.addUnit(units.get(I));        myDbHelper.close();
        返回null;
    }

接下来,这里是deleteAll(),addIngredient()和addUnit()我DatabaseHelper类的方法:

 公共无效deleteAll()
{
    INT deletedIngredientCount = myDataBase.delete(TABLE_INGREDIENTS,1,NULL);
    Log.d(QBCPro,deletedIngredientCount +的成分删除成功);    INT deletedUnitCount = myDataBase.delete(TABLE_UNITS,1,NULL);
    Log.d(QBCPro,deletedUnitCount +单位删除成功);
}公共无效addIngredient(成分成分)
{
    ContentValues​​值=新ContentValues​​();
    values​​.put(ING_KEY_NAME,ingredient.getName());
    values​​.put(ING_KEY_DENSITY,ingredient.getDensity());    //插入行
    INT行=(int)的myDataBase.insert(TABLE_INGREDIENTS,空,价值);
    如果(行== -1)
        Log.d(QBCPro,发生错误,排==+行);
    其他
        Log.d(QBCPro,插入成功+ values​​.get(ING_KEY_NAME)+进行+行);
}公共无效addUnit(单位unit)
{
    ContentValues​​值=新ContentValues​​();
    values​​.put(UNIT_KEY_NAME,unit.getName());
    values​​.put(UNIT_KEY_BASE_VALUE,unit.getBaseValue());
    values​​.put(UNIT_KEY_FINAL_VALUE,unit.getFinalValue());
    values​​.put(UNIT_KEY_IS_WEIGHT,unit.getIsWeight());    //插入行
    myDataBase.insert(TABLE_UNITS,空,价值);
}

最后,这里的日志。正如你所看到的,它突然结束,只调用addIngredient()的六倍。另外还有showStatusIcon警告,但我想不通的地方,可能会来自哪里,或者是什么导致了它。

  02-13 18:47:32.320:D / QBCPro :: :( 25264):SaveAllTask​​:保存到数据库...
02-13 18:47:32.405:W / IInputConnectionWrapper(25264)上的非活动InputConnection showStatusIcon
02-13 18:47:32.445:D / QBCPro(25264):DatabaseHelper deleteAll()调用。
02-13 18:47:32.480:D / QBCPro(25264):11成份成功删除
02-13 18:47:32.510:D / QBCPro(25264):12个单位成功删除
02-13 18:47:32.510:D / QBCPro(25264):离开DatabaseHelper deleteAll()方法。
02-13 18:47:32.540:D / QBCPro(25264):成功插入杏仁(地)为第1行
02-13 18:47:32.575:D / QBCPro(25264):成功地插入发酵粉到第2行
02-13 18:47:32.610:D / QBCPro(25264):成功地插入小苏打成3排
02-13 18:47:32.640:D / QBCPro(25264):成功地将黄油放入4排
02-13 18:47:32.685:D / QBCPro(25264):成功地将可可粉成5排
02-13 18:47:32.720:D / QBCPro(25264):成功插入面粉(全purp)到6排

我猜这会导致内存泄漏或东西,因为这是日志的末尾。它还使应用中断,因为当我把它回到前台,我得到了一堆IInputConnection警告和所有我的看法是不可见的。

任何有识之士将大大AP preciated!

更新:

据停止发生无故,但它再次启动。我并没有改变任何code数据库(超过日志报表等),但我已经改变了在主要活动了一点,但它不应该有对数据库的任何影响。这里是发生了什么:

用户退出应用程序,AsyncTask的SaveAllTask​​被调用。在code是上面一样,但我加了一些日志语句,你可以看到:

  13 02-14:41:29.561:D / QBCPro :: :( 12104):SaveAllTask​​ doInBackground叫...
02-14 13:41:29.561:D / QBCPro :: :( 12104):SaveAllTask​​:ingredients.size()= 11
02-14 13:41:29.576:D / QBCPro :: :( 12104):SaveAllTask​​:units.size()= 12
02-14 13:41:29.616:D / QBCPro :: :( 12104):SaveAllTask​​:保存到数据库...
02-14 13:41:29.671:W / IInputConnectionWrapper(12104)上的非活动InputConnection showStatusIcon
02-14 13:41:29.701:D / QBCPro(12104):DatabaseHelper deleteAll()调用。
02-14 13:41:29.736:D / QBCPro(12104):11成份成功删除
02-14 13:41:29.761:D / QBCPro(12104):12个单位成功删除
02-14 13:41:29.761:D / QBCPro(12104):离开DatabaseHelper deleteAll()方法。
02-14 13:41:29.781:D / QBCPro(12104):成功插入杏仁(地)为第1行
02-14 13:41:29.811:D / QBCPro(12104):成功地插入发酵粉到第2行
02-14 13:41:29.836:D / QBCPro(12104):成功地插入小苏打成3排
02-14 13:41:29.861:D / QBCPro(12104):成功地将黄油放入4排
02-14 13:41:29.886:D / QBCPro(12104):成功地将可可粉成5排
02-14 13:41:29.921:D / QBCPro(12104):成功插入面粉(全purp)到6排
02-14 13:41:29.961:D / QBCPro(12104):成功插入粉(饼)到第7行
02-14 13:41:29.991:D / QBCPro(12104):成功地插入牛奶(2%)为8个行
02-14 13:41:30.021:D / QBCPro(12104):成功插入糖(BR,包装)成排9

然后它突然结束,像上面,不过奇怪的是在第9行,而不是6瞻应用回到前台电话AsyncTask的LoadAllTask​​,导致这样的:

  13 02-14:43:57.106:D / QBCPro :: :( 12532):LoadAllTask​​ doInBackground叫...
02-14 13:43:57.121:D / QBCPro :: :( 12532):LoadAllTask​​:ingredients.size()== 9
02-14 13:43:57.121:D / QBCPro :: :( 12532):LoadAllTask​​:units.size()== 0
02-14 13:43:57.121:D / QBCPro(12532):数据库已经关闭! (好事)
02-14 13:43:57.121:D / QBCPro :: :( 12532):LoadAllTask​​ doInBackground完成...

和我的应用程序中断。

我不认为这是必要的,但为了以防万一,这里是我的LoadAllTask​​ code:

  @覆盖
    保护无效doInBackground(无效... PARAMS)
    {
        Log.d(TAGLoadAllTask​​ doInBackground叫......);
        //打开数据库
        尝试
        {
            myDbHelper.openDatabase();
        }赶上(的SQLException SQLE)
        {
            扔SQLE;
        }        //获取所有成分和单位
        成分= myDbHelper.getAllIngredients();
        单位= myDbHelper.getAllUnits();        Log.d(TAGLoadAllTask​​:ingredients.size()==+ ingredients.size());
        Log.d(TAGLoadAllTask​​:units.size()==+ units.size());        myDbHelper.close();
        Log.d(TAGLoadAllTask​​ doInBackground完成...);
        返回null;
    }


解决方案

我通过创建它里面的AsyncTask的一个IntentService,并在调用的onPause它固定这一点。它现在工作无差错。下面是对的onPause code:

 意图saveIntent =新意图(这一点,SaveService.class);
    startService(saveIntent);

这是我的SaveService类:

 公共类SaveService扩展IntentService
{
    私人的ArrayList<性成分GT; ingredientsArray;
    私人的ArrayList<单元> unitsArray;
    私人DatabaseHelper dbHelper;    公共SaveService(字符串名称)
    {
        超(名);
    }    公共SaveService()
    {
        超级(SaveService);
    }    @覆盖
    保护无效onHandleIntent(意向意图)
    {
        //数据保存到数据库
        dbHelper =新DatabaseHelper(getApplicationContext());
        ingredientsArray = QuickBakeConverterPro.ingredients;
        unitsArray = QuickBakeConverterPro.units;        新SaveAllTask​​()执行();
    }    私有类SaveAllTask​​扩展的AsyncTask<太虚,太虚,太虚>
    {
        @覆盖
        保护无效doInBackground(无效参数... args)
        {
            //打开数据库
            尝试
            {
                dbHelper.openDatabase();
            }赶上(的SQLException SQLE)
            {
                扔SQLE;
            }            dbHelper.deleteAll();            //加入所有材料和放大器;单位
            的for(int i = 0; I< ingredientsArray.size();我++)
                dbHelper.addIngredient(ingredientsArray.get(I));
            的for(int i = 0; I< unitsArray.size();我++)
                dbHelper.addUnit(unitsArray.get(I));            dbHelper.close();            返回null;
        }
    } // SaveAllTask
} //类SaveService

My SQLiteDatabase is giving me some trouble. When the user closes the app, in onPause() an AsyncTask begins to save the data. I don't know if this is the best way to do it, but the way I have done it is, first the database deletes all of the existing data (it's not too much, maybe 20-30 values between two tables), then adds the fresh data back into the database.

The deleteAll() method works just fine, but when it tries to add each item, it fails after the 6th one.

This is my doInBackground() method of the AsyncTask:

@Override
    protected Void doInBackground(Void... args) 
    {           
        //open database
        try 
        {
            myDbHelper.openDatabase();
        }catch(SQLException sqle)
        {    
            throw sqle;  
        }

        myDbHelper.deleteAll();

        //add all ingredients & units
        for (int i = 0; i < ingredients.size(); i++)
            myDbHelper.addIngredient(ingredients.get(i));
        for (int i = 0; i < units.size(); i++)
            myDbHelper.addUnit(units.get(i));

        myDbHelper.close();


        return null;
    }

Next, here are the deleteAll(), addIngredient() and addUnit() methods of my DatabaseHelper class:

public void deleteAll() 
{
    int deletedIngredientCount = myDataBase.delete(TABLE_INGREDIENTS, "1", null);
    Log.d("QBCPro", deletedIngredientCount + " ingredients deleted successfully");

    int deletedUnitCount = myDataBase.delete(TABLE_UNITS, "1", null);
    Log.d("QBCPro", deletedUnitCount + " units deleted successfully");
}

public void addIngredient(Ingredient ingredient) 
{
    ContentValues values = new ContentValues();
    values.put(ING_KEY_NAME, ingredient.getName());
    values.put(ING_KEY_DENSITY, ingredient.getDensity());

    // Insert Row
    int row = (int) myDataBase.insert(TABLE_INGREDIENTS, null, values);
    if (row == -1)
        Log.d("QBCPro", "An error occurred, row == " + row);
    else
        Log.d("QBCPro", "Successfully inserted " + values.get(ING_KEY_NAME) + " into row " + row);
}

public void addUnit(Unit unit)
{
    ContentValues values = new ContentValues();
    values.put(UNIT_KEY_NAME, unit.getName());
    values.put(UNIT_KEY_BASE_VALUE, unit.getBaseValue());
    values.put(UNIT_KEY_FINAL_VALUE, unit.getFinalValue());
    values.put(UNIT_KEY_IS_WEIGHT, unit.getIsWeight());

    // Insert Row
    myDataBase.insert(TABLE_UNITS, null, values);
}

Finally, here's the log. As you can see, it finishes abruptly, only calling addIngredient() six times. There's also the showStatusIcon warning, but I can't figure out where that might be coming from, or what's causing it.

02-13 18:47:32.320: D/QBCPro:::(25264): SaveAllTask: Saving to database...
02-13 18:47:32.405: W/IInputConnectionWrapper(25264): showStatusIcon on inactive InputConnection
02-13 18:47:32.445: D/QBCPro(25264): DatabaseHelper deleteAll() called.
02-13 18:47:32.480: D/QBCPro(25264): 11 ingredients deleted successfully
02-13 18:47:32.510: D/QBCPro(25264): 12 units deleted successfully
02-13 18:47:32.510: D/QBCPro(25264): Leaving DatabaseHelper deleteAll() method.
02-13 18:47:32.540: D/QBCPro(25264): Successfully inserted almonds (ground) into row 1
02-13 18:47:32.575: D/QBCPro(25264): Successfully inserted baking powder into row 2
02-13 18:47:32.610: D/QBCPro(25264): Successfully inserted baking soda into row 3
02-13 18:47:32.640: D/QBCPro(25264): Successfully inserted butter into row 4
02-13 18:47:32.685: D/QBCPro(25264): Successfully inserted cocoa powder into row 5
02-13 18:47:32.720: D/QBCPro(25264): Successfully inserted flour (all-purp) into row 6

I'm guessing this causes a memory leak or something, because this is the end of the log. It also causes the app to break because when I bring it back to the foreground I get a bunch of IInputConnection warnings and all of my views are invisible.

Any insight would be greatly appreciated!

UPDATE:

It stopped happening for no reason, but it's starting again. I haven't changed any code in the database (other than log statements), but I have changed a bit in the main Activity, but it shouldn't have any bearing on the database. Here's what happens:

User exits app, AsyncTask SaveAllTask is called. The code is the same as above, but I added some log statements, as you can see:

02-14 13:41:29.561: D/QBCPro:::(12104): SaveAllTask doInBackground called...
02-14 13:41:29.561: D/QBCPro:::(12104): SaveAllTask: ingredients.size() = 11
02-14 13:41:29.576: D/QBCPro:::(12104): SaveAllTask: units.size() = 12
02-14 13:41:29.616: D/QBCPro:::(12104): SaveAllTask: Saving to database...
02-14 13:41:29.671: W/IInputConnectionWrapper(12104): showStatusIcon on inactive InputConnection
02-14 13:41:29.701: D/QBCPro(12104): DatabaseHelper deleteAll() called.
02-14 13:41:29.736: D/QBCPro(12104): 11 ingredients deleted successfully
02-14 13:41:29.761: D/QBCPro(12104): 12 units deleted successfully
02-14 13:41:29.761: D/QBCPro(12104): Leaving DatabaseHelper deleteAll() method.
02-14 13:41:29.781: D/QBCPro(12104): Successfully inserted almonds (ground) into row 1
02-14 13:41:29.811: D/QBCPro(12104): Successfully inserted baking powder into row 2
02-14 13:41:29.836: D/QBCPro(12104): Successfully inserted baking soda into row 3
02-14 13:41:29.861: D/QBCPro(12104): Successfully inserted butter into row 4
02-14 13:41:29.886: D/QBCPro(12104): Successfully inserted cocoa powder into row 5
02-14 13:41:29.921: D/QBCPro(12104): Successfully inserted flour (all-purp) into row 6
02-14 13:41:29.961: D/QBCPro(12104): Successfully inserted flour (cake) into row 7
02-14 13:41:29.991: D/QBCPro(12104): Successfully inserted milk (2%) into row 8
02-14 13:41:30.021: D/QBCPro(12104): Successfully inserted sugar (br, packed) into row 9

Then it abruptly ends, like above, though strangely at row 9 rather than 6. Bringing the app back into the foreground calls AsyncTask LoadAllTask, leading to this:

02-14 13:43:57.106: D/QBCPro:::(12532): LoadAllTask doInBackground called...
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask: ingredients.size() == 9
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask: units.size() == 0
02-14 13:43:57.121: D/QBCPro(12532): Database CLOSED! (good thing)
02-14 13:43:57.121: D/QBCPro:::(12532): LoadAllTask doInBackground completed...

And my app breaks.

I don't think it's necessary, but just in case, here's my LoadAllTask code:

@Override
    protected Void doInBackground(Void... params) 
    {
        Log.d(TAG, "LoadAllTask doInBackground called...");
        //open database
        try 
        {
            myDbHelper.openDatabase();
        }catch(SQLException sqle)
        {    
            throw sqle;  
        }

        //get all ingredients and units
        ingredients = myDbHelper.getAllIngredients();
        units = myDbHelper.getAllUnits();

        Log.d(TAG, "LoadAllTask: ingredients.size() == " + ingredients.size());
        Log.d(TAG, "LoadAllTask: units.size() == " + units.size());

        myDbHelper.close();
        Log.d(TAG, "LoadAllTask doInBackground completed...");
        return null;
    }

解决方案

I fixed this by creating an IntentService with an AsyncTask inside of it, and calling it within onPause. It works error-free now. Here's the code in onPause:

    Intent saveIntent = new Intent(this, SaveService.class);
    startService(saveIntent); 

And here's my SaveService class:

public class SaveService extends IntentService
{
    private ArrayList<Ingredient> ingredientsArray;
    private ArrayList<Unit> unitsArray;
    private DatabaseHelper dbHelper;

    public SaveService(String name) 
    {
        super(name);
    }

    public SaveService() 
    {
        super("SaveService");
    }

    @Override
    protected void onHandleIntent(Intent intent) 
    {
        //save data to database
        dbHelper = new DatabaseHelper(getApplicationContext());
        ingredientsArray = QuickBakeConverterPro.ingredients;
        unitsArray = QuickBakeConverterPro.units;

        new SaveAllTask().execute();
    }

    private class SaveAllTask extends AsyncTask<Void, Void, Void>
    {
        @Override
        protected Void doInBackground(Void... args) 
        {
            //open database
            try 
            {
                dbHelper.openDatabase();
            }catch(SQLException sqle)
            {    
                throw sqle;  
            }

            dbHelper.deleteAll();

            //add all ingredients & units
            for (int i = 0; i < ingredientsArray.size(); i++)
                dbHelper.addIngredient(ingredientsArray.get(i));
            for (int i = 0; i < unitsArray.size(); i++)
                dbHelper.addUnit(unitsArray.get(i));

            dbHelper.close();

            return null;
        }
    }//SaveAllTask
}//class SaveService

这篇关于Android的SQLiteDB未完成增加值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆