Как использовать ViewModel для правильного сохранения растрового изображения? - PullRequest
0 голосов
/ 09 апреля 2020

В официальной android документации , о том, как реализовать ViewModel, , есть этот метод:

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 объект как глобальная вариация ble:

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 Error

1 Ответ

1 голос
/ 09 апреля 2020

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

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

...