2015-10-28 44 views
6

我特別查看了addButtonClicked()方法和DBHandler本身。當我嘗試向數據庫中添加某些內容時,我無法弄清楚爲什麼程序基本陷入了無限循環。每次運行它並嘗試向數據庫添加內容時,它都會凍結並反覆提供此消息。Android數據庫不斷「啓動/等待阻塞GC分配」的應用程序

錯誤:

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; 
    } 


} 

回答

6

想通了的情況下,有人碰巧遇到此特定錯誤。在我的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(); 
     } 
2

只是爲了你的答案補充。相反的:

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"; 
     } 
}