andorid - как получить доступ к контексту или общим свойствам в классе модели MVVM - PullRequest
1 голос
/ 23 апреля 2019

Мне нужен доступ к sharedPrefences в моем классе модели, так как мы не должны получать доступ к контексту и представлениям из класса модели. Как я могу получить значение из модели?Я не хочу анализировать каждую из моих переменных в viewmodel, а затем в моем классе модели.

класс модели:

class CategoryModel(private val netManager: NetManager) {
    var dateChanges: String = "null";
    var isLoading= ObservableField<Boolean>(false)

    fun getCats(): MutableLiveData<MutableList<Cat>> {
        isLoading.set(true)
        var list = MutableLiveData<MutableList<Cat>>();
        if (netManager.isConnected!!) {
            list = getCatsOnline();
        }
        return list
    }

    private fun getCatsOnline(): MutableLiveData<MutableList<Cat>> {
        var list = MutableLiveData<MutableList<Cat>>();
        val getCats = ApiConnection.client.create(Category::class.java)

        Log.v("this","uid "+MyApp().uid)
        getCats.getCats(MyApp().uid, dateChanges)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(
                { success ->
                    isLoading.set(false)
                    list+= success.cats
                },{
                    error->
                        isLoading.set(false)
                        Log.v("this","ErrorGetCats "+ error.localizedMessage);
                }
            )

        return list;
    }

    operator fun <T> MutableLiveData<MutableList<T>>.plusAssign(values: List<T>) {
        val value = this.value ?: arrayListOf()
        value.addAll(values)
        this.value = value
    }
}

Как я могу это сделать?

Ответы [ 3 ]

2 голосов
/ 23 апреля 2019

Сначала вам нужно изменить класс Model:

class CategoryModel(.. NetManager, private val sharedPrefences: SharedPrefences)

, теперь вы можете получить applicationContext, используя AndroidViewModel вместо ViewModel, не пугайтесь получения статической ссылкиto applicationContext не обязательно плохая идея :

public class MyViewModel extends AndroidViewModel {

    private val preferences: SharedPreferences = 
        PreferenceManager.getDefaultSharedPreferences(getApplication())
    private val netManager: NetManager
    private val model = CategoryModel(netManager, preferences)

    ...
}           

Теперь более элегантный способ - использовать Factory для вставки зависимостей в ViewModelthis:

public static class Factory extends ViewModelProvider.NewInstanceFactory {

    @NonNull
    private final SharedPreferences mPreferences;
    ...

    public Factory(@NonNull SharedPreferences preferences, ...) {
        mPreferences = preferences;
    }

    @Override
    public <T extends ViewModel> T create(Class<T> modelClass) {
        //noinspection unchecked
        return (T) new MyViewModel(mPreferences, ..);
    }
}

PS: В идеале я хотел бы создать модель с использованием ServiceLocator или DependencyInjector и внедрить ее непосредственно в ViewModel, используя упомянутый Factory.

0 голосов
/ 23 апреля 2019

Я бы обернул sharedPreferences как репозиторий, чтобы ваша модель получила зависимость от этого интерфейса репозитория, а реализация репозитория получила ApplicationContext в конструкторе it-s

0 голосов
/ 23 апреля 2019

Мне нужен доступ к sharedPrefences в моем классе модели, так как мы не должны Доступ к контексту и представлениям из класса модели. Как получить значение из модель?

Оберните его и передайте как зависимость конструктору вашего ViewModel.

Оборачивая, это только рекомендация, если вы хотите переключиться с SharedPreferences на что-то другое для хранения данных (например, другую библиотеку)

...