有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在socket回调中使用观察器?

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

我想列出服务器上的文章,并在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);
    }
}

我的问题是当我返回可观察的。只是(文章)作为输出。执行这一行后,类中的onNext方法会被触发一次BlogViewModel,但当从服务器获取文章列表和值时,不会触发onNext方法

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

提前谢谢


共 (1) 个答案

  1. # 1 楼答案

    您好,您可以使用observeForever而不是observeonly,因为observeForever()不与任何LifecycleOwner绑定。因此,请按如下方式使用:

    First remove your BlogRepository class and update BlogViewModel as below:

    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());
        }
    }
    

    希望现在有帮助!!:)