0

In the official android documentation, on how to implement a ViewModel, there is this method:

private void loadUsers() {
        // Do an asynchronous operation to fetch users.
    }

In my case I don't need to fetch any data, I just want to save a bitmap which in another class than the ActivityClass.

I tried making a setter method, but I can't make an object of the ViewModel class! <(Look at my edit)>

  • This is my ViewModel class:

    public class MyViewModel extends ViewModel {
    
      private MutableLiveData<Bitmap> bitmapMutableLiveData;
    
      public LiveData<Bitmap> getBitmapMutableLiveData() {
        if (bitmapMutableLiveData == null) {
            bitmapMutableLiveData = new MutableLiveData<Bitmap>();
        }
        return bitmapMutableLiveData;
      }
    
      public void setBitmap(Bitmap bitmapImage) {
        bitmapMutableLiveData.postValue(bitmapImage);
      }
    }
    
  • And this is where I get and set the bitmap:

       void loadScaledImage(Uri photoUri){
    
        mUpdateGraphicViews.onClear();
    
        if(photoUri != null){
            bitmapImage = decodeSampledBitmapFromUri(photoUri);
    
            mImageView.setImageBitmap(bitmapImage);
            mFTR.recognizeTextFromImage(getScaledBitmap(bitmapImage));
        }
    }
    

So, how can I save a bitmap in the right way using a ViewModel? Thanks!


EDIT:

I made mistake by making the ViewModel class outside of the package, but I fixed that and I called the setter method like that.. in the loadScaledImage() method that I mentioned earlier.

myViewModel.setBitmap(bitmapImage);

But, now I faced a new problem in the onCreate() method!!!!

MyViewModel model = new ViewModelProvider(this).get(MyViewModel.class); //Cannot resolve constructor ViewModelProvider(com.ziad.sayit.PreviewActivity)
        model.getBitmapMutableLiveData().observe(this, bitmapMutableLiveData -> { //Lambda expressions are not supported at language level 7
            // update UI
        });

I have noticed that the ViewModelProvider() constructor takes two parameters in the super-class but this is now the case in the documentation, and the second one is weird, I have java 8 or is that not the case?


Update:

Using those two answers that I found, I was able to fix my last problem:

Cannot resolve ViewModelProvider construction in a fragment?

Java "lambda expressions not supported at this language level"

  • So, now, This is how I set and get the bitmap:

Made a ViewModel object as a global variable:

Bitmap savedImage;
MyViewModel model;

And this is in onCreate():

model = new ViewModelProvider(this).get(MyViewModel.class); 
        model.getBitmapMutableLiveData().observe(this, bitmapMutableLiveData -> { 

            savedImage = bitmapMutableLiveData;
        });

And then this is how I set the bitmap

if(savedImage != null) {
    helper.loadSavedBitmap(savedImage); //load the saved image
}else{
    helper.loadScaledImage(imageUri);   //there is a bunch of code before this but I delete it for the simplicity
    model.setBitmap(helper.bitmapImage); //set that new Image
}

But then I tested the app and nothing changed!


Update 2:

So, I discovered that the ViewModel doesn't work like normal code. the problem in the code above is that I used it ignoring the lifeCycle of the ViewModel and its Terms (because I didn't know any of that), but I have noticed that (And if I said anything wrong please correct me):

  1. The ViewModel doesn't run in the order of the code, however, it runs after everything in onCreate(). This is why you can't depend on it to save a value to a global variable like I did.
  2. If the ViewModel has no value stored on it, It doesn't work at all! So, no need to check if there is a value in it or not.
  3. It is called everytime onResume() or onStart() is called -I'm not really sure which one- regardless of the fact if onCreate() is being called or not..

So, I refactored the code, but still, there is something that I'm missing! All the code works fine even the ViewModel, but when I change the device language to check if it succeed to use the saved image.. an error occurs!!

I'm sharing my code with you:

PreviewActivity (where I use the ViewModel)

Helper class (prepare the image and set it to the screen)

MainActivity (Lanches the PreviewActivity)

LogCat Error

Ziad H.
  • 528
  • 1
  • 5
  • 20

1 Answers1

1

You simply can't make a ViewModel object in any another simple java class rather than Activity class because its sole purpose is to be aware of activity life cycle.

Although instead of directly storing bitmap from your simple java class i would recommend to get instance of your simple java class in activity class in which your viewModel is initialised, from there you can store your bitmap in viewModel.

Parth
  • 791
  • 7
  • 17
  • I updated somethings in the questions, could you check that out? Also, about the second part, do you mean get a reference of the `Bitmap` in the `SimpleJavaClass` and pass it to the `ViewModel` in the `Activity`? – Ziad H. Apr 09 '20 at 03:55
  • 1
    yes i mean to say is get a bitmap in you activity somehow and then store it in a `viewModel` and for your edit, your code seems fine. can you print the logcat? – Parth Apr 09 '20 at 04:07
  • I updated my question with all the new details that I did; and I got no errors but the `ModelView` didn't work!! – Ziad H. Apr 10 '20 at 03:13
  • Hello @ZiadH. It'll be better if you post your whole activity code here. it'll help us to see where the problem is occurring. – Parth Apr 10 '20 at 03:51
  • Hello @Parth, sorry for being late! I updated the question with all the necessary code and logcat and everything that I have done so far. – Ziad H. Apr 12 '20 at 00:47