通过活动传递对象(Android)

时间:2016-03-10 06:55:20

标签: java android sqlite android-activity dependency-injection

对于我的软件工程类,我们必须将SQLite数据库合并到我们的应用程序项目中。

对于我们的应用程序,必须可以从多个活动访问此数据库类。我已将Database类转换为单例,然后调用

DBInterface database = Database.getInstance(this)

设置一个变量来引用数据库,以便在每个必要的类中访问它的方法,并且它可以工作。但是,我们应该在代码中使用依赖注入,我的教授特别告诉我们,应该可以从我们的数据库类切换到我们在前一次迭代中使用的存根数据库,只需更改一行代码即可。

显然这意味着将上述内容改为

DBInterface database = StubDB.getInstance(this)

但是,在执行此操作时,我仍然必须在使用数据库方法的每个活动中进行此更改。

所以我的问题是:有没有办法在我们的init活动中初始化我的数据库,然后在没有上面的赋值代码的情况下传递对每个必要活动的引用?

相关代码

Singleton数据库类

public class RecipeDatabase extends Activity implements DBInterface {
    private dbHelper Helper;
    private static RecipeDatabase sInstance;
    private static Context sContext;

    public static synchronized RecipeDatabase getInstance(Context context){
        if(sInstance == null){
            sInstance = new RecipeDatabase(context.getApplicationContext());
        }
        return sInstance;
    }

    private RecipeDatabase(Context context){
        Helper = new dbHelper(context);
        sContext = context;
    }

    @Override
    public void addRecipe(Recipe recipe)
    {
        String ingredients = recipe.ingredientString();
        String directions = recipe.directionString();


        SQLiteDatabase db = Helper.getWritableDatabase();
        ContentValues values = new ContentValues();

        values.put(Recipe.KEY_rID, recipe.getrID());
        values.put(Recipe.KEY_mealtype, recipe.getMealType());
        values.put(Recipe.KEY_mainingredient, recipe.getMainIngredient());
        values.put(Recipe.KEY_description, recipe.getDescription());
        values.put(Recipe.KEY_ingredients, ingredients);
        values.put(Recipe.KEY_directions, directions);
        values.put(Recipe.KEY_notes, recipe.getNotes());
        values.put(Recipe.KEY_rating, recipe.getRating());
        values.put(Recipe.KEY_cooktime, recipe.getCooktime());

        db.insert(Recipe.TABLE, null, values);

        db.close();
    }

    @Override
    public void editRecipe(Recipe recipe)
    {
        SQLiteDatabase db = Helper.getWritableDatabase();
        ContentValues values = new ContentValues();
        String ingredients = recipe.ingredientString();
        String directions = recipe.directionString();

        values.put(Recipe.KEY_rID, recipe.getrID());
        values.put(Recipe.KEY_mealtype, recipe.getMealType());
        values.put(Recipe.KEY_mainingredient, recipe.getMainIngredient());
        values.put(Recipe.KEY_description, recipe.getDescription());
        values.put(Recipe.KEY_ingredients, ingredients);
        values.put(Recipe.KEY_directions, directions);
        values.put(Recipe.KEY_notes, recipe.getNotes());
        values.put(Recipe.KEY_rating, recipe.getRating());
        values.put(Recipe.KEY_cooktime, recipe.getCooktime());

        db.update(Recipe.TABLE, values, Recipe.KEY_rID + " = ?", new String[]{String.valueOf(recipe.getrID())});
        db.close();
    }

    @Override
    public void deleteRecipe(Recipe recipe)
    {
        SQLiteDatabase db = Helper.getWritableDatabase();

        db.delete(Recipe.TABLE, Recipe.KEY_rID + " = ", new String[]{String.valueOf(recipe.getrID())});
        db.close();
    }

    public ArrayList<Recipe> getList()
    {
        ArrayList<Recipe> result = new ArrayList<>();

        SQLiteDatabase db = Helper.getReadableDatabase();

        String selectQuery = "SELECT " + Recipe.KEY_rID + ", " +
                Recipe.KEY_name + ", " +
                Recipe.KEY_mealtype + ", " +
                Recipe.KEY_mainingredient + ", " +
                Recipe.KEY_description + ", " +
                Recipe.KEY_ingredients + ", " +
                Recipe.KEY_directions + ", " +
                Recipe.KEY_notes + ", " +
                Recipe.KEY_rating + ", " +
                Recipe.KEY_cooktime + " FROM " + Recipe.TABLE;

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

        if(cursor.moveToFirst()) {
            do {
                ArrayList<String> ingredients = new ArrayList<>(); // Temp Storage
                ArrayList<String> directions = new ArrayList<>(); // Temp Storage

                String tempIngredient = cursor.getString(cursor.getColumnIndex(Recipe.KEY_ingredients));
                String[] temp = tempIngredient.split("- "); //Split up ingredients to individual strings

                for(int x=0; x < temp.length; x++) {
                    ingredients.add(temp[x]);
                }

                String tempDirection = cursor.getString(cursor.getColumnIndex(Recipe.KEY_ingredients));
                temp = tempDirection.split("- ");//split up directions into individual strings

                for(int x=0; x < temp.length; x++) {
                    directions.add(temp[x]);
                }
                //Get Values for Recipe Object
                int rID = cursor.getInt(cursor.getColumnIndex(Recipe.KEY_rID));
                String name = cursor.getString(cursor.getColumnIndex(Recipe.KEY_name));
                String mealType = cursor.getString(cursor.getColumnIndex(Recipe.KEY_mealtype));
                String mainIngredient = cursor.getString(cursor.getColumnIndex(Recipe.KEY_mainingredient));
                int rating = cursor.getInt(cursor.getColumnIndex(Recipe.KEY_rating));
                String description = cursor.getString(cursor.getColumnIndex(Recipe.KEY_description));
                int cooktime = cursor.getInt(cursor.getColumnIndex(Recipe.KEY_cooktime));
                String notes = cursor.getString(cursor.getColumnIndex(Recipe.KEY_notes));

                //Create new Recipe from Row
                Recipe tempRecipe = new Recipe(rID, name, description, mealType, mainIngredient,
                rating, cooktime, notes, ingredients, directions);

                //Add the recipe to the ArrayList
                result.add(tempRecipe);

            }while (cursor.moveToNext());
        }
        //Return the populated ArrayList for use
        return result;
    }
}

初始班级

public class init extends ListActivity {

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

        //The code to change to switch from stub to database
        DBInterface repository = RecipeDatabase.getInstance(this);
        //DBInterface repository = new StubDB(this);

        ArrayList<Recipe> recipes = repository.getList();
        ArrayList<String> recipeDisplay = new ArrayList<>();
        for(int i=0; i<recipes.size(); i++) {
            recipeDisplay.add(recipes.get(i).getName());
        }

        ArrayAdapter<String> myArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, recipeDisplay);
        ListView lv = this.getListView();
        lv.setAdapter(myArrayAdapter);
    }

    @Override
    protected void onListItemClick(ListView l, View v, int pos, long id){
        super.onListItemClick(l, v, pos, id);

        Intent myIntent = new Intent(this, Details.class);
        myIntent.putExtra("recipePosition", pos);
        startActivity(myIntent);
    }

    public void shoppingListButton(View view){
        startActivity(new Intent(this, ShoppingList.class));
    }

    public void addRecipeButton(View view){
        Intent myIntent = new Intent(this, Edit.class);
        myIntent.putExtra("editType", 1); // 1 corresponds to add recipe
        startActivity(myIntent);
    }
}

需要数据库方法的一个活动类

public class Details extends ListActivity {
    int recipePosition = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_details);
        //want to avoid this call 
        DBInterface repository = RecipeDatabase.getInstance(this);
        recipePosition = getIntent().getIntExtra("recipePosition", 0);
        Recipe clickedRecipe = repository.getList().get(recipePosition);
        ArrayList<String> recipeDetails = new ArrayList<>();
        recipeDetails.add(clickedRecipe.getName());
        recipeDetails.add(clickedRecipe.getDescription());
        recipeDetails.add("Ingredients:");
        for(int i=0; i<clickedRecipe.getIngredients().size(); i++){
            recipeDetails.add(clickedRecipe.getIngredients().get(i));
        }
        recipeDetails.add("Instructions:");
        for(int i=0; i<clickedRecipe.getDirections().size(); i++){
            recipeDetails.add(clickedRecipe.getDirections().get(i));
        }
        ArrayAdapter<String> myArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, recipeDetails);
        ListView lv = this.getListView();
        lv.setAdapter(myArrayAdapter);
    }
    public void editButton(View view){
        Intent myIntent = new Intent(this, Edit.class);
        myIntent.putExtra("recipePosition", recipePosition);
        myIntent.putExtra("editType", 2); // 2 corresponds to modify recipe
        startActivity(myIntent);
    }
}

数据库助手类

public class dbHelper extends SQLiteOpenHelper {

    private static final int DATABASE_VERSION = 1;

    private static final String DATABASE_NAME = "ROSE.db";

    public dbHelper(Context context){
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db){
        //Creates the Recipe Table which stores recipes
        String CREATE_TABLE_RECIPES = "CREATE TABLE " + Recipe.TABLE  +
                "(" + Recipe.KEY_rID + " INTEGER PRIMARY KEY, " +
                Recipe.KEY_name + " TEXT, " +
                Recipe.KEY_mealtype + " TEXT, " +
                Recipe.KEY_mainingredient + " TEXT, " +
                Recipe.KEY_description + " TEXT, " +
                Recipe.KEY_ingredients + " TEXT, " +
                Recipe.KEY_directions + " TEXT, " +
                Recipe.KEY_notes + " TEXT, " +
                Recipe.KEY_rating + " INTEGER, " +
                Recipe.KEY_cooktime + " INTEGER )";
        db.execSQL(CREATE_TABLE_RECIPES);
    }

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

2 个答案:

答案 0 :(得分:2)

Dagger2对你来说是完美的选择。它非常易于使用,只需按照它们在文档中提供的说明进行操作,一旦找到它就会爱上它。

基本上你要使用

@Inject
DBInterface database;

在每个活动,片段,服务或任何您想要使用数据库的地方。 然后,您将创建一个DatabaseModule,它将具有一个为注入提供数据库的方法。

@Singleton
@Provides static DBInterface provideDatabase() {
      return new WhateverDatabaseImplementsDBInterface();
}

正如您所看到的,只需添加 @Singleton 即可使其成为单身人士。而现在更改您使用的数据库确实是一线改变。

Dagger2是您在依赖注入时遇到的最好的事情,只需正确设置,如果您有任何问题请写入(但是您不应该通过他们的详细说明)。

答案 1 :(得分:0)

您可以使用SQLiteOpenHelper。它将确保您的所有活动都访问同一个数据库。即使每个Activity中有不同的数据库帮助程序对象,它们也都访问同一个数据库。