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):
- The
ViewModel
doesn't run in the order of the code, however, it runs after everything inonCreate()
. This is why you can't depend on it to save a value to a global variable like I did. - 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. - It is called everytime
onResume()
oronStart()
is called -I'm not really sure which one- regardless of the fact ifonCreate()
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)