mercredi 9 mars 2016

Passing an object through Activities (Android)

For my software engineering class, we have to incorporate an SQLite database into our application project.

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?

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

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

Aucun commentaire:

Enregistrer un commentaire