【问题标题】:Retrieving Data from SQLite Database through AsyncTask and Displaying it通过 AsyncTask 从 SQLite 数据库中检索数据并显示
【发布时间】:2016-09-21 21:50:10
【问题描述】:

所以我有一个过去几周一直在开发的程序,它使用 SQLite 数据库来存储用户添加的配方,该配方通过 AsyncTask 运行并存储。食谱可以添加和删除,但现在我必须使用 AsyncTask 来显示在某些类别中输入的食谱。因此,例如,如果用户添加了“面包”食谱,那么当用户单击“面包”按钮时,会在主屏幕上显示该食谱。这是我目前所拥有的:

MyDBHandler.java:

package com.example.healthylife;

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


public class MyDBHandler extends SQLiteOpenHelper {

private static final int DATABASE_VERSION = 1;
private static final String DATABASE_NAME = "recipeDB.db";
private static final String TABLE_RECIPE = "recipe";

private static final String COLUMN_ID = "_id";
private static final String COLUMN_RECIPENAME = "_recipename";
private static final String COLUMN_CATEGORY = "_category";
private static final String COLUMN_INGREDIENTS = "_ingredients";
private static final String COLUMN_INSTRUCTIONS = "_instructions";

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

@Override
public void onCreate(SQLiteDatabase db){
    String CREATE_RECIPE_TABLE = "CREATE TABLE " + TABLE_RECIPE + "(" +
            COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_RECIPENAME + " TEXT," +
            COLUMN_CATEGORY + " TEXT," + COLUMN_INGREDIENTS + " TEXT," +
            COLUMN_INSTRUCTIONS + " TEXT" + ")";
    db.execSQL(CREATE_RECIPE_TABLE);
}

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

public void addRecipe(Recipe recipe){
    ContentValues values = new ContentValues();
    values.put(COLUMN_RECIPENAME, recipe.getRecipeName());
    values.put(COLUMN_CATEGORY, recipe.getCategory());
    values.put(COLUMN_INGREDIENTS, recipe.getIngredients());
    values.put(COLUMN_INSTRUCTIONS, recipe.getInstructions());

    SQLiteDatabase db = this.getWritableDatabase();
    db.insert(TABLE_RECIPE, null, values);
    db.close();
}

public Recipe findRecipe(String recipename){
    String query = "Select * FROM " + TABLE_RECIPE + "WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();

    if (cursor.moveToFirst()){
        cursor.moveToFirst();
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        recipe.setRecipeName(cursor.getString(1));
        recipe.setCategory(cursor.getString(2));
        recipe.setIngredients(cursor.getString(3));
        recipe.setInstructions(cursor.getString(4));
        cursor.close();
    }else{
        recipe = null;
    }
    db.close();
    return recipe;
}

public boolean deleteRecipe(String recipename) {
    boolean result = false;

    String query = "Select * FROM " + TABLE_RECIPE + " WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";

    SQLiteDatabase db = this.getWritableDatabase();

    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();

    if (cursor.moveToFirst()) {
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        db.delete(TABLE_RECIPE, COLUMN_ID + " = ?",
                new String[] { String.valueOf(recipe.getID()) });
        cursor.close();
        result = true;
    }
    db.close();
    return result;
}

public Recipe getBread(String recipename) {
    SQLiteDatabase db = this.getWritableDatabase();

    String query = "Select * FROM " + TABLE_RECIPE + "WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";
    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();
    if (cursor != null) {
        cursor.moveToFirst();
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        recipe.setRecipeName(cursor.getString(1));
        recipe.setCategory(cursor.getString(2));
        recipe.setIngredients(cursor.getString(3));
        recipe.setInstructions(cursor.getString(4));
        cursor.close();
    }else{
        recipe = null;
    }
    db.close();
    return recipe;
}

public Recipe getFruit(String recipename) {
    SQLiteDatabase db = this.getReadableDatabase();

    String query = "Select * FROM " + TABLE_RECIPE + "WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";
    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();
    if (cursor != null) {
        cursor.moveToFirst();
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        recipe.setRecipeName(cursor.getString(1));
        recipe.setCategory(cursor.getString(2));
        recipe.setIngredients(cursor.getString(3));
        recipe.setInstructions(cursor.getString(4));
        cursor.close();
    }else{
        recipe = null;
    }
    db.close();
    return recipe;
}

public Recipe getVeg(String recipename) {
    SQLiteDatabase db = this.getReadableDatabase();

    String query = "Select * FROM " + TABLE_RECIPE + "WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";
    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();
    if (cursor != null) {
        cursor.moveToFirst();
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        recipe.setRecipeName(cursor.getString(1));
        recipe.setCategory(cursor.getString(2));
        recipe.setIngredients(cursor.getString(3));
        recipe.setInstructions(cursor.getString(4));
        cursor.close();
    }else{
        recipe = null;
    }
    db.close();
    return recipe;
}

public Recipe getSoup(String recipename) {
    SQLiteDatabase db = this.getReadableDatabase();

    String query = "Select * FROM " + TABLE_RECIPE + "WHERE " + COLUMN_RECIPENAME + " = \"" +
            recipename + "\"";
    Cursor cursor = db.rawQuery(query, null);

    Recipe recipe = new Recipe();
    if (cursor != null) {
        cursor.moveToFirst();
        recipe.setID(Integer.parseInt(cursor.getString(0)));
        recipe.setRecipeName(cursor.getString(1));
        recipe.setCategory(cursor.getString(2));
        recipe.setIngredients(cursor.getString(3));
        recipe.setInstructions(cursor.getString(4));
        cursor.close();
    }else{
        recipe = null;
    }
    db.close();
    return recipe;
}

[Recipe.java 有 getter/setter]

DatabaseActivity 类使用 AsyncTask 中的添加和删除功能:

package com.example.healthylife;



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


public class DatabaseActivity extends AppCompatActivity {


TextView idView;
EditText RecipeBox;
EditText CategoryBox;
EditText IngredientsBox;
EditText InstructionsBox;

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

    idView = (TextView) findViewById(R.id.Recipe_ID);
    RecipeBox = (EditText) findViewById(R.id.edit_RecipeName);
    CategoryBox = (EditText) findViewById(R.id.input_category);
    IngredientsBox = (EditText) findViewById(R.id.edit_Ingredients);
    InstructionsBox = (EditText) findViewById(R.id.edit_Instructions);
}

public void newRecipe (View view){

    AsyncTaskSave op = new AsyncTaskSave();
    op.execute();

}

public void lookupRecipe (View view){
    MyDBHandler dbHandler = new MyDBHandler(this, null, null, 1);

    Recipe recipe = dbHandler.findRecipe(RecipeBox.getText().toString());

    if (recipe != null){
        idView.setText(String.valueOf(recipe.getID()));

        CategoryBox.setText(String.valueOf(recipe.getCategory()));
        IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
        InstructionsBox.setText(String.valueOf(recipe.getInstructions()));
    }else {
        idView.setText("No Match Found");
    }
}

public void removeRecipe (View view){

    AsyncTaskDelete task = new AsyncTaskDelete();
    task.execute();
}

private class AsyncTaskSave extends AsyncTask <Object, Object, String> {

    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (DatabaseActivity.this, null, null, 1);
        Recipe recipe = new Recipe();
        dbHandler.addRecipe(recipe);

        return null;
    }
    @Override
    protected void onPostExecute(String result) {
        Recipe recipe = new Recipe();
        RecipeBox.setText(String.valueOf(recipe.getRecipeName()));
        CategoryBox.setText(String.valueOf(recipe.getCategory()));
        IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
        InstructionsBox.setText(String.valueOf(recipe.getInstructions()));

        result = "Added Successfully";
        idView.setText(result);
    }
}

private class AsyncTaskDelete extends AsyncTask<Object, String, String>{
    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (DatabaseActivity.this, null, null, 1);
        dbHandler.deleteRecipe(null);

        return null;
    }

    @Override
    protected void onPostExecute(String result){

        if (result == null){
            idView.setText("Record Deleted");
            RecipeBox.setText("");
            CategoryBox.setText("");
            IngredientsBox.setText("");
            InstructionsBox.setText("");
        }else
            idView.setText("No Match Found");
    }
}

}

SyncActivity.java 类应该显示由 DatabaseActivity 类添加的配方,并在按下我的主屏幕按钮时在屏幕上调用它们:

package com.example.healthylife;

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

public class SyncActivity extends AppCompatActivity{

TextView idView;
TextView RecipeBox;
TextView CategoryBox;
TextView IngredientsBox;
TextView InstructionsBox;

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

    idView = (TextView) findViewById(R.id.Recipe_ID);
    RecipeBox = (TextView) findViewById(R.id.edit_RecipeName);
    CategoryBox = (TextView) findViewById(R.id.input_category);
    IngredientsBox = (TextView) findViewById(R.id.edit_Ingredients);
    InstructionsBox = (TextView) findViewById(R.id.edit_Instructions);
}

public void getBread (View view) {

    AsyncTaskBread os = new AsyncTaskBread();
    os.execute();
}

public void getFruit (View view){
    AsyncTaskFruit ob = new AsyncTaskFruit();
    ob.execute();
}

public void getVeg (View view){
    AsyncTaskVeg ow = new AsyncTaskVeg();
    ow.execute();
}

public void getSoup (View view){
    AsyncTaskSoup ox = new AsyncTaskSoup();
    ox.execute();
}

private class AsyncTaskBread extends AsyncTask <Object, Object, String>{

    MyDBHandler dbHandler;

    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1);
        dbHandler.getBread("Bread");
        return "Bread";
    }

    @Override
    protected void onPostExecute(String result){
        Recipe recipe = dbHandler.getBread(CategoryBox.getText().toString());

        if(recipe != null){
            idView.setText(String.valueOf(recipe.getID()));
            RecipeBox.setText(String.valueOf(recipe.getRecipeName()));
            IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
            InstructionsBox.setText(String.valueOf(recipe.getInstructions()));
        }else {
            result = "No Match Found";
            idView.setText(result);
        }
    }
}

private class AsyncTaskFruit extends AsyncTask <Object, Object, String>{

    MyDBHandler dbHandler;

    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1);
        dbHandler.getFruit("Fruit");
        return "Fruit";

    }

    @Override
    protected void onPostExecute(String result){
        Recipe recipe = dbHandler.getFruit(CategoryBox.getText().toString());

        if(recipe != null){
            idView.setText(String.valueOf(recipe.getID()));
            RecipeBox.setText(String.valueOf(recipe.getRecipeName()));
            IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
            InstructionsBox.setText(String.valueOf(recipe.getInstructions()));
        }else {
            result = "No Match Found";
            idView.setText(result);
        }
    }
}

private class AsyncTaskVeg extends AsyncTask <Object, Object, String>{

    MyDBHandler dbHandler;

    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1);
        dbHandler.getVeg("Vegetables");
        return "Vegetables";

    }

    @Override
    protected void onPostExecute(String result){
        Recipe recipe = dbHandler.getVeg(CategoryBox.getText().toString());

        if(recipe != null){
            idView.setText(String.valueOf(recipe.getID()));
            RecipeBox.setText(String.valueOf(recipe.getRecipeName()));
            IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
            InstructionsBox.setText(String.valueOf(recipe.getInstructions()));
        }else {
            result = "No Match Found";
            idView.setText(result);
        }
    }
}

private class AsyncTaskSoup extends AsyncTask <Object, Object, String>{

    MyDBHandler dbHandler;

    @Override
    protected String doInBackground(Object...objects){
        MyDBHandler dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1);
        dbHandler.getSoup("Soup");
        return "Soup";

    }

    @Override
    protected void onPostExecute(String result){
        Recipe recipe = dbHandler.getSoup(CategoryBox.getText().toString());

        if(recipe != null){
            idView.setText(String.valueOf(recipe.getID()));
            RecipeBox.setText(String.valueOf(recipe.getRecipeName()));
            IngredientsBox.setText(String.valueOf(recipe.getIngredients()));
            InstructionsBox.setText(String.valueOf(recipe.getInstructions()));
        }else {
            result = "No Match Found";
            idView.setText(result);
        }
    }
}
}

现在这里是主屏幕:

Home Screen in app

将食谱添加到食谱书后,单击每个按钮时,它们应在某些字段中显示详细信息,但我的字段为空:

Recipe call when buttons are clicked

现在 SyncActivity 类应该从数据库中检索通过 DatabaseActivity 类输入的值,但事实并非如此。我需要更改 myDBHandler 中的代码吗?还是在 SyncActivity 中?

【问题讨论】:

    标签: java android sqlite android-asynctask


    【解决方案1】:

    问题在于,例如 AsyncTaskBread 类中的私有对象 dbHandler 从未初始化。您在 doInBackground 中初始化 dbHandler,但该对象仅存在于该函数中。尝试将行 MyDBHandler dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1); 更改为 dbHandler = new MyDBHandler (SyncActivity.this, null, null, 1); 我还建议您将 sql 查询从 onPostExecute 移动到 doInBackground,因为 onPostExecute 在 UI(主)线程上运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 2020-09-18
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2012-08-31
      相关资源
      最近更新 更多