【问题标题】:How to use Observers with socket callbacks?如何使用带有套接字回调的观察者?
【发布时间】:2019-03-31 08:28:02
【问题描述】:

我是一名对测试新技术感兴趣的 Android 开发人员。 知道,我想使用架构组件来改进我的项目。

我想列出来自服务器的文章并在 recyclerView 中显示它们。 需要注意的是,我已经使用WebSocket与服务器进行通信了。

我的套路如下:

首先,我从 viewModel 类中调用了 loadArticles 方法:

BlogViewModel = ViewModelProvders.of(this).get(BlogViewModel.class);
viewModel.loadArticles();

在 BlogViewModel 主体下方:

public class BlogViewModel extends ViewModel {

private BlogRepository repository;
private CompositeDisposable compositeDisposable = new CompositeDisposable();

public ObservableField<Boolean> isLoading = new ObservableField<>();
public MutableLiveData<List<Article>> articles = new MutableLiveData<>();


public BlogViewModel() {
    this.repository = new BlogRepository();
}

public void loadArticles() {
    isLoading.set(true);

    compositeDisposable.add(repository
            .getArticles()
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribeWith(new DisposableObserver<List<Article>>() {
                @Override
                public void onNext(List<Article> data) {
                    articles.setValue(data);
                }

                @Override
                public void onError(Throwable e) {
                    // FIXME: 3/31/2019
                }

                @Override
                public void onComplete() {
                    isLoading.set(false);
                }
            }));
}

@Override
protected void onCleared() {
    super.onCleared();

    if (!compositeDisposable.isDisposed()) {
        compositeDisposable.dispose();
    }
  }
}

另外,BlogRepository 类定义如下:

public class BlogRepository {

private BlogRemoteDataSource remoteDataSource = BlogRemoteDataSource.getInstance();

public Observable<List<Article>> getArticles() {
    if (Util.isConnect()) {
        return remoteDataSource.getArticles();
    } else {
        return null;
    }
  }
}

BlogRemoteDataSource 类定义如下:

public class BlogRemoteDataSource {

private Application app = (Application) Application.getInstance();
private List<Article> articles;

public static BlogRemoteDataSource getInstance() {
    return new BlogRemoteDataSource();
}

public Observable<List<Article>> getArticles() {
    JSONObject objData = new JSONObject();
    try {
        objData.put("itemID", "");
    } catch (JSONException e) {
        e.printStackTrace();
    }

    app.getSocket().observe(app.getOwner(), socket -> socket.event(Api.EVENT_GET_ARTICLE)
            .data(objData)
            .setCallbacks(new SocketCallback() {
                @Override
                public void onSuccess(JSONObject data) {
                    try {
                        articles = Article.parse(data.getJSONArray(Constant.PARAM_BODY));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(int code, String message) {
                }
            }).send());

    return Observable.just(articles);
    }
}

我的问题是当我返回 Observable.just(articles) 作为输出时。执行此行后,类中的onNext方法是BlogViewModel一旦被触发,但是当文章列表从服务器取值时,onNext方法没有被触发。

请指导我如何告诉 ViewModel,数据准备好了?

提前致谢。

【问题讨论】:

  • Thsnks Tamir Abutbul!

标签: java android observable rx-java2


【解决方案1】:

您好,您可以使用observeForever 而不是仅观察,因为observeForever() 不绑定到任何LifecycleOwner。所以像下面这样使用它:

首先删除您的 BlogRepository 类并将 BlogViewModel 更新为 下面:

public class BlogViewModel extends ViewModel {

private CompositeDisposable compositeDisposable = new CompositeDisposable();
private BlogRemoteDataSource remoteDataSource = BlogRemoteDataSource.getInstance();
public ObservableField<Boolean> isLoading = new ObservableField<>();

public BlogViewModel() {
    this.repository = new BlogRepository();
}

public void loadArticles() {
    isLoading.set(true);
    remoteDataSource.getArticles();
}

@Override
protected void onCleared() {
    super.onCleared();
    if (!compositeDisposable.isDisposed()) {
        compositeDisposable.dispose();
    }
  }
}

然后更新 BlogRemoteDataSource 如下:

public class BlogRemoteDataSource {

private Application app = (Application) Application.getInstance();
public MutableLiveData<List<Article>> articles = new MutableLiveData<>();

public static BlogRemoteDataSource getInstance() {
    return new BlogRemoteDataSource();
}

public void getArticles() {
    JSONObject objData = new JSONObject();
    try {
        objData.put("itemID", "");
    } catch (JSONException e) {
        e.printStackTrace();
    }

    app.getSocket().observeForever(app.getOwner(), socket -> socket.event(Api.EVENT_GET_ARTICLE)
            .data(objData)
            .setCallbacks(new SocketCallback() {
                @Override
                public void onSuccess(JSONObject data) {
                    try {
                        List<Article> newArticeList = Article.parse(data.getJSONArray(Constant.PARAM_BODY));
                        articles.postValue(newArticeList);
                        articles.notifyObserver();
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                @Override
                public void onError(int code, String message) {
                }
            }).send());
    }
}

希望现在有帮助!! :)

【讨论】:

  • 谢谢我的朋友,你的解决方案让我从 LifecycleOwner 中解散了,但它仍然不起作用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 2011-07-01
  • 2010-12-04
  • 1970-01-01
  • 2019-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多