Android应用程序带有数据库,不断出现“启动/等待阻塞gc分配”的问题。

9
我仔细研究了addButtonClicked()方法和DBHandler本身,但无法弄清楚为什么当我尝试向数据库添加内容时程序基本上会陷入无限循环。每次运行并尝试向数据库添加内容时,它都会冻结并一遍又一遍地显示此消息。 错误:
10-27 20:34:50.303 2849-2849/? I/art: Not late-enabling -Xcheck:jni (already on)
10-27 20:34:50.303 2849-2849/? I/art: Late-enabling JIT
10-27 20:34:50.312 2849-2849/? I/art: JIT created with code_cache_capacity=2MB compile_threshold=1000
10-27 20:34:50.408 2849-2849/com.example.test.assignment W/System: ClassLoader referenced unknown path: /data/app/com.example.test.assignment-2/lib/x86
10-27 20:34:50.966 2849-2860/com.example.test.assignment W/art: Suspending all threads took: 6.223ms
10-27 20:34:51.033 2849-2860/com.example.test.assignment I/art: Background partial concurrent mark sweep GC freed 423(15KB) AllocSpace objects, 418(7MB) LOS objects, 38% free, 6MB/10MB, paused 6.686ms total 54.772ms
10-27 20:34:51.577 2849-2860/com.example.test.assignment W/art: Suspending all threads took: 6.097ms
10-27 20:34:51.816 2849-2860/com.example.test.assignment I/art: WaitForGcToComplete blocked for 11.994ms for cause Background
10-27 20:34:52.017 2849-2860/com.example.test.assignment W/art: Suspending all threads took: 9.393ms
10-27 20:34:52.023 2849-2860/com.example.test.assignment I/art: Background sticky concurrent mark sweep GC freed 845(30KB) AllocSpace objects, 843(41MB) LOS objects, 76% free, 1233KB/5MB, paused 10.623ms total 31.789ms
10-27 20:34:52.132 2849-2860/com.example.test.assignment I/art: Background partial concurrent mark sweep GC freed 752(27KB) AllocSpace objects, 747(37MB) LOS objects, 15% free, 21MB/25MB, paused 20.980ms total 40.058ms
10-27 20:34:53.000 2849-2849/com.example.test.assignment I/art: Waiting for a blocking GC Alloc
10-27 20:34:53.001 2849-2849/com.example.test.assignment I/art: Starting a blocking GC Alloc
10-27 20:34:53.123 2849-2849/com.example.test.assignment I/art: Waiting for a blocking GC Alloc
10-27 20:34:53.126 2849-2849/com.example.test.assignment I/art: Starting a blocking GC Alloc
10-27 20:34:53.195 2849-2849/com.example.test.assignment I/art: Waiting for a blocking GC Alloc
10-27 20:34:53.205 2849-2849/com.example.test.assignment I/art: WaitForGcToComplete blocked for 10.178ms for cause Alloc

它一遍又一遍地运行,并且printSelectedDatabase()从未运行,因为它不显示在文本视图中。

主活动:

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    EditText dataInput;
    TextView showText;
    DBHandler dbHandler;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dataInput = (EditText) findViewById(R.id.dataInput);
        showText = (TextView) findViewById(R.id.showText);
        dbHandler = new DBHandler(this, null, null, 1);
        printSelectedDatabase();
    }

    public void addButtonClicked(View view){
        Animals animal = new Animals(dataInput.getText().toString());
        dbHandler.addAnimal(animal);
        printSelectedDatabase();
    }

    public void deleteButtonClicked(View view){
        String string = dataInput.getText().toString();
        dbHandler.deleteAnimal(string);
        printSelectedDatabase();
    }

    public void printSelectedDatabase(){
        String string = dbHandler.printDatabase();
        showText.setText(string);
        dataInput.setText("");
    }
}

Setter/Getters:

public class Animals {

    private int _id;
    private String _animalName;

    public Animals(){

    }

    public Animals(String animalName) {
        this._animalName = animalName;
    }

    public void set_id(int _id) {
        this._id = _id;
    }

    public void set_animalname(String _animalName) {
        this._animalName = _animalName;
    }

    public int get_id() {
        return _id;
    }

    public String get_animalName() {
        return _animalName;
    }
}

DBHandler:

import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.Cursor;
import android.content.Context;
import android.content.ContentValues;

public class DBHandler extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;
    private static final String DATABASE_NAME = "animals.db";
    public static final String TABLE_ANIMALS = "animals";
    public static final String COLUMN_ID = "_id";
    public static final String COLUMN_ANIMALS = "animalName";

    public DBHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, DATABASE_NAME, factory, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String query = "CREATE TABLE " + TABLE_ANIMALS + "(" +
                COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " +
                COLUMN_ANIMALS + " TEXT " +
                ");";
        db.execSQL(query);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_ANIMALS);
        onCreate(db);
    }

    //Add Animal
    public void addAnimal(Animals animal){
        ContentValues values = new ContentValues();
        values.put(COLUMN_ANIMALS, animal.get_animalName());
        SQLiteDatabase db = getWritableDatabase();
        db.insert(TABLE_ANIMALS, null, values);
        db.close();
    }
    //Delete Animal
    public  void deleteAnimal(String animalName){
        SQLiteDatabase db = getWritableDatabase();
        db.execSQL("DELETE FROM " + TABLE_ANIMALS + " WHERE " + COLUMN_ANIMALS + "=\"" + animalName + "\";");
    }

    //Print Animals
    public String printDatabase(){
        String string = "";
        SQLiteDatabase db = getWritableDatabase();
        String query = "SELECT * FROM " + TABLE_ANIMALS + " WHERE 1";
        Cursor cursor = db.rawQuery(query, null);
        cursor.moveToFirst();
        while(!cursor.isAfterLast()){
            if(cursor.getString(cursor.getColumnIndex("animalName"))!=null){
                string += cursor.getString(cursor.getColumnIndex("animalName"));
                string += "\n";
            }
        }
        db.close();
        return string;
    }


}
2个回答

9
如果有人遇到这个特定的错误,我希望你能够解决它。在我的DBHandler中,我在while语句中缺少了一个换行符。
 while(!cursor.isAfterLast()){
                if(cursor.getString(cursor.getColumnIndex("animalName"))!=null){
                    string += cursor.getString(cursor.getColumnIndex("animalName"));
                    string += "\n";
                }
            }

应该是:

while(!cursor.isAfterLast()){
            if(cursor.getString(cursor.getColumnIndex("animalName"))!=null){
                string += cursor.getString(cursor.getColumnIndex("animalName"));
                string += "\n";
            }
            cursor.moveToNext();
        }

6
只是补充一下你的回答。可以这样写:
while(!cursor.isAfterLast()){
   // do stuff with cursor
    cursor.moveToNext();
}

使用以下代码可以使您的代码更加简洁:

while (cursor.moveToNext()) {
    // do stuff with cursor
}

当你进行查询时,游标对象位于第一条记录之前。调用cursor.moveToNext()将移动到下一个位置,并返回true(如果实际上有要移动的记录)和false(否则)。

此外,避免在循环内部调用cursor.getColumnIndex("columnName")。最好将列索引缓存到int变量中,并在循环内引用该变量。

int animalNameColumn = cursor.getColumnIndex("animalName");
while (cursor.moveToNext()) {
       if(cursor.getString(animalNameColumn)!=null){
            string += cursor.getString(animalNameColumn);
            string += "\n";
        }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接