Android: хранение большого объема информации по области в шаблоне MVP

Я пробую проект с Rx, dagger, realm, модификацией в шаблоне MVP. Я не эксперт в этих библиотеках и мало знаю об этих библиотеках.

В проекте Scope Application я объявляю конфигурацию области, а затем получаю ее экземпляр для ввода моему докладчику.

В первом действии с именем LoginActivityو, поскольку оно находит свое имя, это действие используется для входа в приложение. У меня есть два текста редактирования для вставки username и pasword, и у меня есть кнопка для входа в систему. Когда кнопка нажата в ViewLogin, я сделал наблюдаемые клики:

public Observable<Object> observeLoginBtn() {
    return RxView.clicks(mBinding.buttonLogin);
} 

и в LoginPresenter я реализовал это наблюдаемое для задачи входа в систему с помощью RX. Если имя пользователя и пароль указаны правильно, служба вернет клиенту информацию о пользователе в виде json.

{
"User": {
    "Address": "     ",
    "BirthDate": "1395/09/28",
    "Email": " ",
    "EnableExpireDate": null,
    "FirstName": "kia",
    "JobLocations": {
        "AllowDomains": "9,13",
        "Altitude": "12",
    },
    "UserImage": [..]...
}

Это часть json. На самом деле с помощью gson я вернул клиенту необходимую информацию. Теперь я хочу сохранить эту информацию на устройстве по области. Я выполнил задачу входа в систему с помощью rx, и когда сервер возвращает информацию о пользователе, я получил эту информацию в onNext:

        .switchMap(new Function<Response<String>, ObservableSource<UserInfo>>() {
            @Override
            public ObservableSource<UserInfo> apply(Response<String> stringResponse) throws Exception {
                String orginCookie = stringResponse.raw().header("Set-Cookie")
                        + "domain=" +
                        stringResponse.raw().header("Access-Control-Allow-Origin");
                String cookie = SerializeUtil.serializeCookie(orginCookie);
                return model.getLoginUser(info[0], cookie);
            }
        })
        .observeOn(AndroidSchedulers.mainThread())
   .subscribeWith(new DisposableObserver<UserInfo> (){
       @Override
       public void onNext(UserInfo userInfo) {

Поскольку теперь onNext выполняется на Ui thread. Теперь в этом разделе я хочу хранить эту информацию по областям: Прежде всего, мне нужно создать RealmObject в соответствии с ответом пользователя:

public class UserInfo{
@SerializedName("User")
    private User user;
    public static UserInfo objectFromData(String str) {
        return new Gson().fromJson(str, UserInfo.class);
    }
    public User getUser() {
        return user;
    }
    public void setUser(User User) {
        this.user = User;
    }
}

Вложенный пользовательский класс:

public class User extends RealmObject implements RealmModel {
    public User objectFromData(String str) {

        return new Gson().fromJson(str, User.class);
    }
    @SerializedName("Tel")
    private String Tel;
    @SerializedName("UserName")
    private String UserName;
    @SerializedName("UserImage")
    private RealmList<Integer> UserImage;
   @SerializedName("JobLocations")
   private JobLocations jobLocations;
    .... //getter and setter
}

Вложенный класс JobLocations:

public class JobLocations extends RealmObject implements RealmModel {
    public static JobLocations objectFromData(String str) {
        return new Gson().fromJson(str, JobLocations.class);
    }
    @SerializedName("AllowDomains")
    private String AllowDomains;
    @SerializedName("Altitude")
    private String Altitude;
    @SerializedName("City")
    private String City;
    .... // getter and setter
}

Я создал репозиторий для вставки моей модели в БД:

public class DatabaseRealm implements IDatabaseRealm{
...
@Override
public <T extends RealmObject> T add(T model) {
    realm.beginTransaction();
    realm.copyToRealm(model);
    realm.commitTransaction();
    return model;
}

Здесь происходит запись. Это то, что я сделал наблюдаемым для вставки моей модели в БД:

public class TaskRepositoryImpl implements Repository<User> {
...
@Override
public Observable<User> add(final User model) {
    return Observable.create(new ObservableOnSubscribe<User>() {
        @Override
        public void subscribe(ObservableEmitter<User> emitter) throws Exception {
            try {
                databaseRealm.add(model);
                emitter.onNext(model);
                emitter.onComplete();
            }catch (Exception e) {
                emitter.onError(e);
            }
        }
    });
}

В методе loginPresenter в методе subscribeWith я получил свою информацию о пользователе json, которую я использую в области следующим образом:

.subscribeWith(new DisposableObserver<UserInfo> (){
               @Override
               public void onNext(UserInfo userInfo) {
                    taskRepository.add(userInfo.getUser())
                            .subscribeOn(Schedulers.trampoline())
                            .observeOn(AndroidSchedulers.mainThread())
                            .subscribe(new DisposableObserver<User>() {
                                @Override
                                public void onNext(User user) {

                                }

                                @Override
                                public void onError(Throwable e) {

                                }

                                @Override
                                public void onComplete() {

                                }
                            });

Теперь у меня есть два основных вопроса: 1- Является ли подходящим местом для хранения данных. Я имею в виду onNext в subscribeWith?

2- В ответе сервера есть изображение пользователя, и оно имеет большой размер. Я думаю, что хранение в области накапливается в потоке пользовательского интерфейса, это может привести к ошибке ANR. Как может хранить эту информацию в фоновом потоке в моем шаблоне?

Извините, что мой текст получился длинным Я постарался объяснить его идеально и понятно.


person Cyrus the Great    schedule 01.04.2018    source источник
comment
Пожалуйста, не объясняйте все вкратце о своей проблеме с этим кодом проблемы.   -  person Zulqurnain Jutt    schedule 01.04.2018
comment
Я хочу, чтобы ребята поняли, что я сделал!!! Для лучшей помощи. извините   -  person Cyrus the Great    schedule 01.04.2018
comment
первый вопрос: да или может быть, полностью зависит от того, почему вы хотите его сохранить и для чего, второй вопрос: вы можете преобразовать изображение в байты растрового изображения, а затем сохранить его с помощью rxjava , но я рекомендую вам сохранить путь к изображению и хранить изображение локально на SD-карте или где-то еще   -  person Zulqurnain Jutt    schedule 01.04.2018
comment
Хорошо, чувак, но во втором вопросе изображение, полученное с сервера, представляет собой массив байтов. Я отправляю данные сразу после получения в область для хранения. для преобразования byteArray в файл и сохранения файла пути в БД я должен сделать это в классе DatabaseRealm и добавить метод. Но преобразование должно выполняться в фоновом потоке. Как я могу выполнить метод добавления в классе DatabaseRealm на фоне? это был мой главный вопрос   -  person Cyrus the Great    schedule 01.04.2018
comment
Я не вижу никакого создания файла или кода, генерирующего байты, в приведенном выше фрагменте, опубликуйте это, и я посмотрю, чего не хватает   -  person Zulqurnain Jutt    schedule 01.04.2018
comment
Я еще не создал ни одного файла. потому что мой вопрос заключался в выполнении транзакций в фоновом потоке. Согласно официальной веб-странице области, мы можем выполнить Asynchronous transaction методом executeTransactionAsync. Теперь, когда я использовал Rx, как я могу это сделать?   -  person Cyrus the Great    schedule 01.04.2018


Ответы (1)


1.) Я удивлен, что private String UserName; не @PrimaryKey

2.)

@Override
public <T extends RealmObject> T add(T model) {
    realm.beginTransaction();
    realm.copyToRealm(model);
    realm.commitTransaction();
    return model;
}

Может быть

@Override
public <T extends RealmModel> Single<T> add(T model) {
    return Single.create((emitter) ->
        if(model.isManaged()) {
            return model;
        } 
        realm.executeTransactionAsync((r) -> {
             r.insertOrUpdate(model); // if has primary key 
        }, () -> {
            emitter.onSuccess(model);
        }, (throwable) -> {
            emitter.onError(throwable);
        } 
    );
}

Или что-то очень похожее. Затем вы можете flatMap Single для обработки маршрута успеха.

person EpicPandaForce    schedule 01.04.2018
comment
чувак, это мои изменения: codepad.org/PlexnZWH в качестве твоего предложения. Но как я могу обрабатывать emitter.onSuccess или emitter.onError(error); из rx в моем презентере: codepad.org/5wYL2Pht - person Cyrus the Great; 02.04.2018
comment
Я добавил своего докладчика следующим образом: codepad.org/RmeIkzio это правда? - person Cyrus the Great; 02.04.2018
comment
Эм-м-м. Я просто пойду, надеюсь, у вас нет доступа к нелегальному потоку Realm, и попробуйте. - person EpicPandaForce; 02.04.2018
comment
Спасибо приятель. Я так запутался. В этом посте я описываю, как создать экземпляр из области: dagger" title="доступ к области из неправильного потока в rx и dagger">stackoverflow.com/questions/49609966/ . - person Cyrus the Great; 02.04.2018