Android使用线程执行SQLite查询

时间:2015-09-01 20:37:20

标签: java android multithreading sqlite

我正在尝试为应用程序创建一个餐馆及其项目的数据库,作为熟悉Android的初学者项目。我有一个上一个活动的列表,其中用户点击餐馆的名称并显示项目。我创建了一个helperDB类来处理insert语句和数据库设置,虽然当我从一个新线程调用我的insert方法时,它们似乎没有执行。我提供了以下代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_bar);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    Intent intent = getIntent();
    String barName = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
    final TextView tv = (TextView) findViewById(R.id.name);
    tv.setText(barName);

    restaurants = new ArrayList<String>();
    mydb = new DBHelper(this);

   new Thread(new Runnable() {
        @Override
        public void run() {
            mydb.insertDrink("cake", "McD's", 8);
            mydb.insertDrink("muffin", "The Woods", 8);
            restaurants = mydb.getDrinks("The Woods");
            System.out.println(restaurants);
        }
    }).start();


    ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, restaurants);

    obj = (ListView)findViewById(R.id.listview);
    obj.setAdapter(arrayAdapter);
}

insert语句和getDrinks方法的代码如下:

public boolean insertDrink(String drink, String name, int price){
    SQLiteDatabase db = this.getWritableDatabase();
    ContentValues contentValues = new ContentValues();

    contentValues.put("drink", drink);
    contentValues.put("name", name);
    contentValues.put("price", price);
    db.insert("Bars", null, contentValues);
    return true;
}
public ArrayList<String> getDrinks(String name){
    ArrayList<String> arrayList = new ArrayList<>();

    SQLiteDatabase db = this.getReadableDatabase();
    Cursor res = db.rawQuery("select * from Bars", null);
    res.moveToFirst();

    while(res.isAfterLast() == false){
        arrayList.add(res.getString(res.getColumnIndex(BAR_COLUMN_DRINK)));
        res.moveToNext();
    }
    return arrayList;
}

我知道我不应该从UI线程以外的任何线程访问任何android工具包,虽然我不认为我这样做。如果这不是填充SQLite android数据库的常规方法,我当然也愿意知道在哪里这样做。

2 个答案:

答案 0 :(得分:2)

  

虽然当我从一个新线程中调用我的insert方法时,它们   似乎没有执行。

你怎么能这样说?您是否在数据库中看到数据条目?或者仅查看restaurant ArrayList

我怀疑你没有得到你的餐厅ArrayList,因为你的线程以异步方式运行。

执行Thread之后的下一个语句,无需等待填充restaurnat arrayList。

<强>解决方案:

使用AsyncTask调用doInBackground()中的数据库内容并在onPostExecute()中获取结果,并使用相同的方法将结果设置为适配器。

答案 1 :(得分:2)

我建议你使用AsyncTask。

也许是这样的:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_display_bar);

    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    Intent intent = getIntent();
    String barName = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
    final TextView tv = (TextView) findViewById(R.id.name);
    tv.setText(barName);

    new AsyncTask<Void, Void, ArrayList<String>> {
         protected Long doInBackground() {
           DBHelper mydb = new DBHelper(ThisActivityClassName.this);
           mydb.insertDrink("cake", "McD's", 8);
           mydb.insertDrink("muffin", "The Woods", 8);
           return mydb.getDrinks("The Woods");
         }

         protected void onPostExecute(ArrayList<String> restaurants) {
           ArrayAdapter arrayAdapter=new ArrayAdapter(this,android.R.layout.simple_list_item_1, restaurants);

           obj = (ListView)findViewById(R.id.listview);
           obj.setAdapter(arrayAdapter);
         }
     }.execute();
}