【问题标题】:Android Using a Thread to Execute SQLite QueriesAndroid 使用线程执行 SQLite 查询
【发布时间】:2015-11-27 05:05:18
【问题描述】:

我正在尝试为一个应用程序创建一个餐厅及其项目的数据库,作为熟悉 android 的入门项目。我有一个来自先前活动的列表,其中用户单击餐厅名称并显示项目。我创建了一个 helperDB 类来处理插入语句和数据库设置,尽管当我从一个新线程中调用我的插入方法时,它们似乎没有执行。我提供了以下代码:

@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 数据库的常规方式,我当然也愿意学习在哪里执行此操作。

【问题讨论】:

  • 您的they do not seem to execute 声明是否基于它们未显示在您的列表中?
  • 那可能是因为ArrayAdapter是在restaurants变量初始化之前创建的,你应该看看AsyncTask

标签: java android multithreading sqlite


【解决方案1】:

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

你怎么能这么说?您是否在数据库中看到数据条目?还是只查找restaurant ArrayList

我怀疑你没有得到你的餐厅数组列表,因为你的线程异步运行。

你在线程执行后的下一条语句没有等待填充restaurnat arrayList。

解决方案:

使用AsyncTaskdoInBackground() 中调用您的数据库内容并在onPostExecute() 中获取结果,并以相同的方法设置带有结果的适配器。

【讨论】:

  • 好的,当我将 ArrayAdapter 移动到 onPostExecute() 方法中时,“this”上下文不再有效,因为我不再处于 on create 范围内。我应该把它改成什么?
  • 我使用了DisplayBar.this 作为上下文并且它起作用了!
【解决方案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();
}

【讨论】:

    猜你喜欢
    • 2011-08-28
    • 2010-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-23
    • 2017-09-01
    • 2021-09-23
    • 1970-01-01
    相关资源
    最近更新 更多