Passing an object through Activities (Android)

beelzabuddy

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

Dagger2 is the perfect thing for you. 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.

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

As you can see, just adding @Singleton will make it a 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).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

Android Parcelable object not passing properly between activities

From Dev

Android Parcelable object not passing properly between activities

From Dev

Android - Passing Object between activities error

From Dev

Passing bundles through activities

From Dev

Error passing custom object between activities through intent

From Dev

Passing and keeping data through activities

From Dev

Passing custom object between Android activities in C#

From Dev

Android how to access the same object through different activities

From Dev

Passing parse object between activities

From Dev

Passing parse object between activities

From Dev

Passing extras between activities in android

From Dev

Passing objects between activities in Android

From Dev

Android passing data between activities

From Dev

Passing an object between to activities getting null object

From Dev

Passing an object through a constructor?

From Dev

Passing an object through a constructor?

From Dev

Passing object through segue

From Dev

Best practice: passing objects between Android activities

From Dev

Android - Passing an Array of Classes Between Activities

From Dev

Passing PHP sessions between Android activities

From Dev

passing data between 2 activities android

From Dev

passing data between activities in android - error

From Dev

Passing Data Between Activities in Android App

From Dev

Passing data between Activities Android | java

From Dev

Passing a class instance between two activities Android

From Dev

Object Sharing Between Activities in Android

From Dev

Android, EditText preservation through new activities

From Dev

React - passing object through props

From Dev

Passing a model object through ViewBag

Related Related

HotTag

Archive