使用RxJava和改造实施机房

时间:2018-07-26 22:01:11

标签: android retrofit2 rx-java2 android-room clean-architecture

我正在尝试将Room与RxJava和Retrofit一起使用,然后建议您使用组件拱门(这种机会是不可能的,项目在50%的范围内,只需要继续清洁拱门即可)。

所以问题是这个。我有一个返回 POJO 的Web服务。像这样:

{
 "success":"true",
 "message":"message",
 "data":{[
   "id":"id",
   "name":"name",
   "lname":"lname",
 ]} 
}

POJO更为复杂,但是对于这个例子来说还可以。我需要执行此操作,因为我的视图进行查询以从会议室中调用数据,但是如果数据库中没有数据,请调用我的Web服务,我的Web服务的响应将转换为实体并保存在数据库(会议室)中,然后返回我查看的数据列表。

我正在使用整洁的拱门。我对此表示感谢。再次不尝试使用

数据布局

  • 数据库
  • 网络
  • 存储库

  • 交互器
  • 回调

演示文稿

  • 演示者
  • 视图
  

POJO API响应

{
 "success":"true",
 "message":"message",
 "data":{[
   "id":"id",
   "name":"name",
   "address":"address",
   "phone":"phone",
 ]} 
}
  

我的数据库实体

@Entity(tableName = "clients")
    public class clients {

    String id;
    String name;
    String address;
    String phone;
    String status;


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }
}
  

我的房间房间

@Dao
public interface ClientsDao {

     @Insert(onConflict = OnConflictStrategy.REPLACE)
     void saveAll(List<Clients> clients);

     @Query("SELECT * FROM Clients")
     Flowable<List<Clients>> listClients();

}
  

RxJava帮助类

public class RxHelper {
private static final String TAG = RxHelper.class.getName();

@NonNull
public static <T>Observable<T> getObserbable(@NonNull final Call<T> reponse){

    return Observable.create(new ObservableOnSubscribe<T>() {
        @Override
        public void subscribe(final ObservableEmitter<T> emitter) throws Exception {

            reponse.enqueue(new Callback<T>() {
                @Override
                public void onResponse(Call<T> call, Response<T> response) {

                    if (!emitter.isDisposed()) {
                        emitter.onNext(response.body());
                    }
                }

                @Override
                public void onFailure(Call<T> call, Throwable t) {
                    if (!emitter.isDisposed()) {
                        emitter.onError(t);
                    }
                }
            });

        }
    });

}
}
  

我的客户RepoFactory

public Observable<ResponseClients> getApiClients(){
        String token = preferences.getValue(SDConstants.token);
        return RxHelper.getObserbable(apiNetwork.getClients(token));
}
  

我的客户回购

@Override
public Observable<ResponseClients> listClients() {
    return factory.listClients();
}

1 个答案:

答案 0 :(得分:3)

我不在房间里工作,但是熟悉rxjava时,您可以像这样设计存储库

您的房间界面

import tkinter as tk
import tkinter.ttk as ttk
from tkinter import *

root = Tk()

top=Toplevel(root)
text = Text(top)
vs = Scrollbar(top, orient="vertical")
hs = Scrollbar(top, orient="horizontal")
sizegrip = ttk.Sizegrip(root)

# hook up the scrollbars to the text widget
text.configure(yscrollcommand=vs.set, xscrollcommand=hs.set, wrap="none")
vs.configure(command=text.yview)
hs.configure(command=text.xview)

# grid everything on-screen
text.grid(row=0,column=0,sticky="news")
vs.grid(row=0,column=1,sticky="ns")
hs.grid(row=1,column=0,sticky="news")
sizegrip.grid(row=1,column=1,sticky="news")
root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

def fill():
    for n in range(30):
        text.insert("end", 'check scroll bar ' * 20, "", "\n")


Button(root, text='press', command=fill).grid(row=0, column=0)
root.mainloop()

使用时:
也许:如果数据库中没有用户并且查询不返回任何行,则也许会完成。

Flowable 每次用户数据更新时,Flowable对象都会自动发出,使您可以基于最新数据更新用户界面

:当数据库中没有用户并且查询不返回任何行时,Single将触发onError(EmptyResultSetException.class)

通过link

了解有关Room和RxJava的更多信息

实现“如果db call Web服务中没有数据”,则创建存储库方法

@Query(“SELECT * FROM Users WHERE id = :userId”)
Single<User> getUserById(String userId);

最终从交互器调用存储库方法,将其传递给交互器,然后再传递给演示文稿布局

更多详细信息:您可以将Api和DB注入到存储库中

update_Answer 用于反应式数据库 如果您想获取UI的最新更新,请执行以下操作:

您的房间界面:

public Single<User> getUserById(String userId){
 return  db.getUserById(userId)
              /// if there is no user in the database get data from api
             .onErrorResumeNext(api.getUserById(userId)
              .subscribeOn(Schedulers.io())
              //check your request
              .filter(statusPojo::getStatus)
               // save data to room
              .switchMap(data -> {
              //sava data to db
              return Observable.just(data)
              })
           );

}

存储库:

@Query(“SELECT * FROM Users WHERE id = :userId”)
Flowable<User> getUserById(String userId);

update_Answer2 用于响应式数据库,以及“如果数据库调用网络服务中没有数据” 根据此issue更好地使用返回 @Override public Flowable<User> getUser(int id) { getUserFromNet(id); //first emit cache data in db and after request complete emit last update from net return db.getUserById(id); } private Flowable<User> getUserFromNet(int id){ api.getUserById(userId) .subscribeOn(Schedulers.io()) .observeOn(Schedulers.io()) //check your request .filter(statusPojo::getStatus) // save data to room .subscribe(new DisposableObserver<User>() { @Override public void onNext(User user) { // save data to room } @Override public void onError(Throwable e) { Timber.e(e); } @Override public void onComplete() { } }); }

并检查列表大小,而不是Flowable <List<T>>白色Flowable<T>,因为如果数据库swichIfEmpity中没有任何用户,请勿呼叫Flowable<T>并且不发出{{ 1}}

onNext()