1

I am adding an item to my database using Room.

I get the details of the item from the user in AddFriendActivity, which calls addItem() of AddFriendViewModel which in turn calls subclass AddAsyncTask.

The item gets inserted and I get the id in the doInBackground() or OnPostExecute() of the AsyncTask. Now I need to pass or get this id in my AddFriendActivity.

My Activity:

public class AddFriendActivity extends AppCompatActivity {

    private AddFriendViewModel addFriendViewModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        .
        .
        .
        addFriendViewModel = ViewModelProviders.of(this).get(AddFriendViewModel.class);

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                addFriend();
            }
        });

    }

    private void addFriend() {
        .
        .
        .
        addFriendViewModel.addFriend(new FriendEntity(...));
        finish();
    }
}

My ViewModel class with subclass AddAsyncTask:

public class AddFriendViewModel extends AndroidViewModel {

    private AppDatabase appDatabase;

    public AddFriendViewModel(Application application) {
        super(application);
        appDatabase = AppDatabase.getDatabase(this.getApplication());
    }

    void addFriend(final FriendEntity friendEntity) {
        AddAsyncTask myTask = new AddAsyncTask(appDatabase);
        myTask.execute(friendEntity);
    }

    private static class AddAsyncTask extends AsyncTask<FriendEntity, Void, Long> {

        private AppDatabase db;

        AddAsyncTask(AppDatabase appDatabase) {
            db = appDatabase;
        }

        @Override
        protected Long doInBackground(final FriendEntity... params) {
            return db.friendDao().insert(params[0]);
        }

        @Override
        protected void onPostExecute(Long insertedId) {

        }
    }
}
user9207265
  • 13
  • 1
  • 4

1 Answers1

2

Add an interface

  public interface IdCallback{
     void onFriendInserted(Long id);
    }

Implement it in AddFriendActivity

class AddFriendActivity extends AppCompatActivity implements IdCallback{
private AddFriendViewModel addFriendViewModel;

@Override
protected void onCreate(Bundle savedInstanceState) {
    .
    .
    .
    addFriendViewModel = ViewModelProviders.of(this).get(AddFriendViewModel.class);

    FloatingActionButton fab = findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            addFriend();
        }
    });

}

private void addFriend() {
    .
    .
    .
    addFriendViewModel.addFriend(new FriendEntity(...),this);//<-- pass this
    finish();
}

 public void onFriendInserted(Long id){
  // do something with id
 } 
...

}

Pass interface to our ViewModel via constructor and call this on getting back Id

 public class AddFriendViewModel extends AndroidViewModel {

    private AppDatabase appDatabase;
    private IdCallback callback;

    public AddFriendViewModel(Application application) {
        super(application);
        appDatabase = AppDatabase.getDatabase(this.getApplication());
    }

    void addFriend(final FriendEntity friendEntity,IdCallback callback) {
        AddAsyncTask myTask = new AddAsyncTask(appDatabase);
        this.callback = callback; //< assign
        myTask.execute(friendEntity);
    }

    private static class AddAsyncTask extends AsyncTask<FriendEntity, Void, Long> {

        private AppDatabase db;

        AddAsyncTask(AppDatabase appDatabase) {
            db = appDatabase;
        }

        @Override
        protected Long doInBackground(final FriendEntity... params) {
            return db.friendDao().insert(params[0]);
        }

        @Override
        protected void onPostExecute(Long insertedId) {
            callback.onFriendInserted(insertedId);
        }
    }
}
Rajan Kali
  • 12,627
  • 3
  • 25
  • 37
  • 5
    I think this might cause memory leaks as you are holding a reference to the activity. "Caution: A ViewModel must never reference a view, Lifecycle, or any class that may hold a reference to the activity context." https://developer.android.com/topic/libraries/architecture/viewmodel – Mathias Jeppsson Aug 09 '18 at 00:35
  • 1
    @MathiasJeppsson we can pass weak reference to a avoid that – Rajan Kali Aug 09 '18 at 04:37