Как использовать ViewModel для правильного сохранения растрового изображения?

В официальной документации Android о том, как реализовать ViewModel, < strong> есть такой способ:

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

В моем случае мне не нужно получать какие-либо данные, я просто хочу сохранить bitmap, который находится в другом классе, чем ActivityClass.

Я пробовал создать метод установки, но не могу создать объект класса ViewModel! ‹(Посмотрите мою правку)>

  • Это мой класс ViewModel:

    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);
      }
    }
    
  • Вот где я беру и устанавливаю растровое изображение:

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

Итак, как правильно сохранить bitmap, используя ViewModel? Спасибо!


ИЗМЕНИТЬ:

Я сделал ошибку, создав класс ViewModel вне пакета, но я исправил это и вызвал метод установки, подобный этому ... в методе loadScaledImage(), о котором я упоминал ранее.

myViewModel.setBitmap(bitmapImage);

Но теперь я столкнулся с новой проблемой в onCreate() методе !!!!

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

Я заметил, что конструктор ViewModelProvider() принимает два параметра в super-class, но теперь это так в документации, а второй странный, у меня java 8 или это не так?


Обновление:

Используя эти два ответа, которые я нашел, я смог исправить свою последнюю проблему:

Не удается разрешить конструкцию ViewModelProvider во фрагменте?

лямбда-выражения Java не поддерживаются на этом уровне языка

  • Итак, вот как я устанавливаю и получаю растровое изображение:

Сделал объект ViewModel как глобальную переменную:

Bitmap savedImage;
MyViewModel model;

А это в onCreate():

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

            savedImage = bitmapMutableLiveData;
        });

И вот как я установил 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
}

Но потом я протестировал приложение, и ничего не изменилось!


Обновление 2:

Итак, я обнаружил, что ViewModel не работает как обычный код. проблема в приведенном выше коде заключается в том, что я использовал его, игнорируя жизненный цикл ViewModel и его условия (потому что я не знал ни одного из этого), но я заметил это (и если я сказал что-то не так, пожалуйста, поправьте меня):

  1. ViewModel не выполняется в порядке кода, однако он выполняется после всего, что указано в onCreate(). Вот почему вы не можете рассчитывать на то, что он сохранит значение в глобальной переменной, как это сделал я.
  2. Если ViewModel не имеет сохраненного значения, он вообще не работает! Так что не нужно проверять, есть в нем значение или нет.
  3. Он вызывается каждый раз, когда вызывается onResume() или onStart() - я не совсем уверен, какой из них - независимо от того, вызывается onCreate() или нет ..

Итак, я изменил код, но все же кое-что мне не хватает! Весь код работает нормально, даже ViewModel, но когда я меняю язык устройства на проверьте, удалось ли использовать сохраненное изображение .. возникает ошибка !!

Я делюсь с вами своим кодом:

PreviewActivity (где я использую ViewModel)

Вспомогательный класс (подготовьте изображение и установите его на экран)

MainActivity (запускает PreviewActivity)

Ошибка LogCat




Ответы (1)


Вы просто не можете создать объект ViewModel в любом другом простом классе java, а не в классе Activity, потому что его единственная цель - знать жизненный цикл активности.

Хотя вместо непосредственного хранения растрового изображения из вашего простого класса java я бы рекомендовал получить экземпляр вашего простого класса java в классе активности, в котором ваш viewModel инициализирован, оттуда вы можете сохранить свое растровое изображение в viewModel.

person Parth    schedule 09.04.2020
comment
Я кое-что обновил в вопросах, не могли бы вы это проверить? Кроме того, что касается второй части, вы имеете в виду получить ссылку на Bitmap в SimpleJavaClass и передать ее ViewModel в Activity? - person Ziad H.; 09.04.2020
comment
да, я хочу сказать, что нужно каким-то образом получить растровое изображение в своей деятельности, а затем сохранить его в viewModel, и для вашего редактирования ваш код кажется прекрасным. вы можете распечатать логарифм? - person Parth; 09.04.2020
comment
Я обновил свой вопрос со всеми новыми подробностями, которые я сделал; и у меня нет ошибок, но ModelView не работает !! - person Ziad H.; 10.04.2020
comment
Привет @ZiadH. Будет лучше, если вы разместите здесь весь код своей активности. это поможет нам увидеть, где возникает проблема. - person Parth; 10.04.2020
comment
Привет @Parth, извини за опоздание! Я обновил вопрос, добавив весь необходимый код, logcat и все, что я сделал до сих пор. - person Ziad H.; 12.04.2020