在android中使用AsyncTask和Activity的RxJava

Tom*_*net 1 java android android-asynctask rx-java

我有一个小时的使用RxJava的经验,我试图在我的项目中实现它,而不是使用接口和监听器.

我有一个异步任务,它在一个单独的模块中调用谷歌云端点方法,并List<Profile>在完成时收到.

onPostExecute()异步任务的方法中,我调用onNext以便任何订阅者都能接收到这些数据.

这是AsyncTask看起来像:

private BirthpayApi mApi;
private String mUserId;
private ReplaySubject<List<Profile>> notifier = ReplaySubject.create();

public GetFriends(String userId) {
    mUserId = userId;
}

public Observable<List<Profile>> asObservable() {
    return notifier;
}

@Override
protected List<Profile> doInBackground(Void... params) {
    if (mApi == null) {
        BirthpayApi.Builder builder = new BirthpayApi.Builder(AndroidHttp.newCompatibleTransport(),
                    new AndroidJsonFactory(), null)
                    // options for running against local devappserver
                    // - 10.0.2.2 is localhost's IP address in Android emulator
                    // - turn off compression when running against local devappserver
                    .setRootUrl("http://10.0.2.2:8080/_ah/api/")
                    .setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
                    @Override
                    public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
                            abstractGoogleClientRequest.setDisableGZipContent(true);
                        }
                    });
            mApi = builder.build();
    }

    try {
        return mApi.getFriends(mUserId).execute().getItems();
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    }
}

@Override
protected void onPostExecute(List<Profile> friends) {
    super.onPostExecute(friends);
    notifier.onNext(friends);
}
Run Code Online (Sandbox Code Playgroud)

在我的片段中,我想从调用该onNext()方法的异步任务中收集这些数据.因此implements Action1<List<Profile>>,我在宣布我的课程时使用了扩展片段.

onCall()来自Action1接口的方法中,我收集从Async任务发送的数据:

@Override
public void call(List<Profile> profiles) {
    if (profiles.size() > 0) {
        updateAdapter(profiles);
    } else
        setUpNoFriendsViews();
}
Run Code Online (Sandbox Code Playgroud)

我跟随树屋,但他们使用一个对象来建模他们的数据,这些数据变成了可观察的,而不是使用异步类,他们使用适配器作为观察者.我这样做是错的,无论哪种方式我都能让它发挥作用?

Jah*_*old 5

看起来你没有订阅你在任何地方创建的Observable,并且不清楚你在AsyncTask上调用execute的位置.此外,我不认为你想要一个ReplaySubject,但这取决于你想要实现的目标.

除此之外,我建议完全切换到Rx而不是混合使用Rx和AsyncTasks.在这种情况下,在您的模型类中创建一个类似于的方法:

public Observable<List<Profile>> getProfiles() {

    return Observable.defer(new Func0<Observable<List<Profile>>>() {
        @Override
        public Observable<List<Profile>> call() {

            if (mApi == null) {
                BirthpayApi.Builder builder = new BirthpayApi.Builder(AndroidHttp.newCompatibleTransport(),
                        new AndroidJsonFactory(), null)
                        // options for running against local devappserver
                        // - 10.0.2.2 is localhost's IP address in Android emulator
                        // - turn off compression when running against local devappserver
                        .setRootUrl("http://10.0.2.2:8080/_ah/api/")
                        .setGoogleClientRequestInitializer(new GoogleClientRequestInitializer() {
                            @Override
                            public void initialize(AbstractGoogleClientRequest<?> abstractGoogleClientRequest) throws IOException {
                                abstractGoogleClientRequest.setDisableGZipContent(true);
                            }
                        });
                mApi = builder.build();
            }

            try {
                List<Profile> profiles = mApi.getFriends(mUserId).execute().getItems();
                return Observable.just(profiles);
            } catch (IOException e) {
                return Observable.error(e);
            }
        }
    });
}
Run Code Online (Sandbox Code Playgroud)

然后在你的片段中:

modal.getProfiles()
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
        new Action1<List<Profile>>() {
                //...
        },
        new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                throwable.printStackTrace();
            }
        }
    );
Run Code Online (Sandbox Code Playgroud)