Android-приложение с базой данных постоянно " запуск / ожидание блокировки gc alloc"
Я специально просмотрел метод 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("");
}
}
Сеттеры/Геттеры:
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 ответов
выяснил это в случае, если кто-то случайно столкнется с этой конкретной ошибкой. В моем 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();
}
просто добавить на ваш ответ. Вместо:
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";
}
}