简体   繁体   English

通过活动传递对象(Android)

[英]Passing an object through Activities (Android)

For my software engineering class, we have to incorporate an SQLite database into our application project. 对于我的软件工程课程,我们必须将SQLite数据库合并到我们的应用程序项目中。

For our application this database class has to be accessible from multiple activities. 对于我们的应用程序,必须从多个活动中访问该数据库类。 I have turned the Database class into a singleton and then call 我已经将数据库类变成单例,然后调用

DBInterface database = Database.getInstance(this)

to set a variable to reference the database in order to access its methods in each necessary class and it works. 设置一个变量来引用数据库,以便在每个必需的类中访问其方法,并且该数据库有效。 However, we are supposed to utilize dependency injections into our code and my professor has specifically told us that it should be possible to switch from our database class to a stub database we used in a previous iteration by only changing one line of code. 但是,我们应该在代码中利用依赖注入,而我的教授特别告诉我们,只需更改一行代码,就可以从我们的数据库类切换到我们在先前迭代中使用的存根数据库。

Obviously this means changing the above to 显然,这意味着将以上内容更改为

DBInterface database = StubDB.getInstance(this)

However in doing this I still have to make this change in each of the activities that uses the database methods. 但是,这样做时,我仍然必须在使用数据库方法的每个活动中进行此更改。

So my question is this: is there a way to initialize my database in our init activity and then pass a reference to each necessary activity without the assignment code above? 所以我的问题是这样的:有没有一种方法可以在我们的init活动中初始化我的数据库,然后将引用传递给每个必要的活动,而无需上面的分配代码?

Relevant Code 相关代码

Singleton Database Class 单例数据库类

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

Init Class 初始化类

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

One of the Activity Classes that needs the DB methods 需要DB方法的活动类之一

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

Database Helper Class 数据库助手类

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

Dagger2 is the perfect thing for you. Dagger2对您来说是完美的选择。 It's really easy to use, just follow the instructions they provide in the docs and you'll love it once you figure it out. 它真的很容易使用,只需按照文档中提供的说明进行操作,一旦发现它就会很喜欢。

Basically you're going to use 基本上你会用

@Inject
DBInterface database;

In every activity, fragment, service, or anywhere you wanna use the database. 在每个活动,片段,服务或您想使用数据库的任何地方。 Then you will create a DatabaseModule which will have a method that provides the database for injection. 然后,您将创建一个DatabaseModule,它将具有提供注入数据库的方法。

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

As you can see, just adding @Singleton will make it a singleton. 如您所见,仅添加@Singleton即可使其成为单例。 And now changing the database you use is truly a one line change. 现在更改您使用的数据库确实是一行更改。

Dagger2 is the greatest thing you will encounter for dependency injection for sure, just setup it correctly, write if you have any trouble (but you shouldn't, with their thorough instructions). 对于依赖注入,Dagger2是您肯定会遇到的最伟大的事情,只要正确设置它,如果有任何麻烦就写(但是,不应该使用它们的详尽说明)。

You can use the SQLiteOpenHelper . 您可以使用SQLiteOpenHelper It will make sure all your activities access the same database. 这将确保您的所有活动都访问同一数据库。 Even if you have different database helper objects in each Activity, they all access the same database. 即使每个活动中都有不同的数据库帮助器对象,它们也都访问相同的数据库。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM