Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用rxjava进行异步改造调用。我必须异步调用100多个调用_Java_Android_Rx Java_Retrofit2_Rx Java2 - Fatal编程技术网

如何使用rxjava进行异步改造调用。我必须异步调用100多个调用

如何使用rxjava进行异步改造调用。我必须异步调用100多个调用,java,android,rx-java,retrofit2,rx-java2,Java,Android,Rx Java,Retrofit2,Rx Java2,下面是我一直在编写的代码示例 项包含100个元素,因此使用同步调用获取数据会占用大量时间。有没有人能建议一种方法来提高这个操作的速度,从而减少所需的时间。 目前,执行此操作需要15-20秒。我是rxjava新手,因此如果可能,请提供此问题的详细解决方案。dataResponses包含100个项目中每个项目的RouteInstance对象 for(int i = 0 ; i<items.size();i++){ Map<String, String> map2 = ne

下面是我一直在编写的代码示例

项包含100个元素,因此使用同步调用获取数据会占用大量时间。有没有人能建议一种方法来提高这个操作的速度,从而减少所需的时间。 目前,执行此操作需要15-20秒。我是rxjava新手,因此如果可能,请提供此问题的详细解决方案。dataResponses包含100个项目中每个项目的RouteInstance对象

for(int i = 0 ; i<items.size();i++){

    Map<String, String> map2 = new HashMap<>();

    map2.put("units", "metric");
    map2.put("origin", currentLocation.getLatitude()+","+currentLocation.getLongitude());
    map2.put("destination", items.get(i).getPosition().get(0)+","+items.get(i).getPosition().get(1));
    map2.put("transportMode", "car");
    requests.add(RetrofitClient4_RouteDist.getClient().getRouteDist(map2));
}

Observable.zip(requests,  new Function<Object[], List<RouteDist>>() {
    @Override
    public List<RouteDist> apply(Object[] objects) throws Exception {
        Log.i("onSubscribe", "apply: " + objects.length);
        List<RouteDist> dataaResponses = new ArrayList<>();
        for (Object o : objects) {
            dataaResponses.add((RouteDist) o);
        }
        return dataaResponses;
    }
})
        .observeOn(AndroidSchedulers.mainThread())
        .subscribeOn(Schedulers.io())
        .subscribe(
                new Consumer<List<RouteDist>>() {
                    @Override
                    public void accept(List<RouteDist> dataaResponses) throws Exception {
                        Log.i("onSubscribe", "YOUR DATA IS HERE: "+dataaResponses.toString());
                        recyclerViewAdapter_profile = new RecyclerViewAdapter_Profile(items,dataaResponses);
                        recyclerView.setAdapter(recyclerViewAdapter_profile);
                    }
                },

                new Consumer<Throwable>() {
                    @Override
                    public void accept(Throwable e) throws Exception {
                        Log.e("onSubscribe", "Throwable: " + e);
                    }
                });
for(inti=0;iAPI

接口客户端{
可观察路由列表();
}
最后一节课{
}
最后一个类ClientImpl实现客户端{
@凌驾
公共可观察路由列表(){
返回可观察。从可调用(()->{
//通过这个日志,您可以看到,对可观察对象的每个订阅都是在线程池上执行的
//Log.e(“--------------”,Thread.currentThread().getName());
返回新的RouteDist();
});
}
}
通过subscribeOn应用线程

final class ClientProxy implements Client {
    private final Client api;
    private final Scheduler scheduler;

    ClientProxy(Client api, Scheduler scheduler) {
        this.api = api;
        this.scheduler = scheduler;
    }

    @Override
    public Observable<RouteDist> routeDist() {
        // apply #subscribeOn in order to move subscribeAcutal call on given Scheduler
        return api.routeDist().subscribeOn(scheduler);
    }
}
final类ClientProxy实现客户端{
私有最终客户端api;
专用最终调度器;
客户端代理(客户端api、调度程序){
this.api=api;
this.scheduler=调度程序;
}
@凌驾
公共可观察路由列表(){
//应用#subscribeOn,以便在给定计划程序上移动subscribeAcutal调用
返回api.routeDist().subscribeOn(调度程序);
}
}
雄激素试验

@Test
public void name() {
    // CachedThreadPool, in order to avoid creating 100-Threads or more. It is always a good idea to use own Schedulers (e.g. Testing)
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(0, 10,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<>());

    // wrap real client with Proxy, in order to move the subscribeActual call to the ThreadPool
    Client client = new ClientProxy(new ClientImpl(), Schedulers.from(threadPool));

    List<Observable<RouteDist>> observables = Arrays.asList(client.routeDist(), client.routeDist(), client.routeDist());

    TestObserver<List<RouteDist>> test = Observable.zip(observables, objects -> {
        return Arrays.stream(objects).map(t -> (RouteDist) t).collect(Collectors.toList());
    })
            .observeOn(AndroidSchedulers.mainThread())
            .test();

    test.awaitCount(1);

    // verify that onNext in subscribe is called in Android-EventLoop
    assertThat(test.lastThread()).isEqualTo(Looper.getMainLooper().getThread());
    // verify that 3 calls were made and merged into one List
    test.assertValueAt(0, routeDists -> {
        assertThat(routeDists).hasSize(3);
        return true;
    });
}
@测试
公共无效名称(){
//CachedThreadPool,以避免创建100个或更多线程。最好使用自己的调度程序(例如测试)
ThreadPoolExecutor threadPool=新的ThreadPoolExecutor(0,10,
60升,时间单位。秒,
新建SynchronousQueue());
//使用代理包装真实客户端,以便将subscribeActual调用移动到线程池
Client Client=new ClientProxy(new clientmpl(),Schedulers.from(threadPool));
List observables=Arrays.asList(client.routeDist(),client.routeDist(),client.routeDist());
TestObserver test=Observable.zip(可观察对象,对象->{
返回array.stream(objects).map(t->(RouteDist)t.collect(Collectors.toList());
})
.observeOn(AndroidSchedulers.mainThread())
.test();
测试计数(1);
//验证是否在Android EventLoop中调用了subscribe中的onNext
assertThat(test.lasthread()).isEqualTo(Looper.getMainLooper().getThread());
//验证是否进行了3次呼叫并合并到一个列表中
test.assertValueAt(0,路由列表->{
资产(routeDists)。hasSize(3);
返回true;
});
}
进一步阅读:

注: 不建议一次并发调用100次API。此外,使用Zip时,当您有足够大的线程池时,这将实际发生。当一个API调用超时时,此API调用可能会发出OneError。OneError将进一步传播到订阅服务器。您将不会得到任何结果,即使只有on API调用失败。建议使用一些onErrorResumeNext或其他错误处理操作符,以确保一个API调用不会取消整个结果。

API

接口客户端{
可观察路由列表();
}
最后一节课{
}
最后一个类ClientImpl实现客户端{
@凌驾
公共可观察路由列表(){
返回可观察。从可调用(()->{
//通过这个日志,您可以看到,对可观察对象的每个订阅都是在线程池上执行的
//Log.e(“--------------”,Thread.currentThread().getName());
返回新的RouteDist();
});
}
}
通过subscribeOn应用线程

final class ClientProxy implements Client {
    private final Client api;
    private final Scheduler scheduler;

    ClientProxy(Client api, Scheduler scheduler) {
        this.api = api;
        this.scheduler = scheduler;
    }

    @Override
    public Observable<RouteDist> routeDist() {
        // apply #subscribeOn in order to move subscribeAcutal call on given Scheduler
        return api.routeDist().subscribeOn(scheduler);
    }
}
final类ClientProxy实现客户端{
私有最终客户端api;
专用最终调度器;
客户端代理(客户端api、调度程序){
this.api=api;
this.scheduler=调度程序;
}
@凌驾
公共可观察路由列表(){
//应用#subscribeOn,以便在给定计划程序上移动subscribeAcutal调用
返回api.routeDist().subscribeOn(调度程序);
}
}
雄激素试验

@Test
public void name() {
    // CachedThreadPool, in order to avoid creating 100-Threads or more. It is always a good idea to use own Schedulers (e.g. Testing)
    ThreadPoolExecutor threadPool = new ThreadPoolExecutor(0, 10,
            60L, TimeUnit.SECONDS,
            new SynchronousQueue<>());

    // wrap real client with Proxy, in order to move the subscribeActual call to the ThreadPool
    Client client = new ClientProxy(new ClientImpl(), Schedulers.from(threadPool));

    List<Observable<RouteDist>> observables = Arrays.asList(client.routeDist(), client.routeDist(), client.routeDist());

    TestObserver<List<RouteDist>> test = Observable.zip(observables, objects -> {
        return Arrays.stream(objects).map(t -> (RouteDist) t).collect(Collectors.toList());
    })
            .observeOn(AndroidSchedulers.mainThread())
            .test();

    test.awaitCount(1);

    // verify that onNext in subscribe is called in Android-EventLoop
    assertThat(test.lastThread()).isEqualTo(Looper.getMainLooper().getThread());
    // verify that 3 calls were made and merged into one List
    test.assertValueAt(0, routeDists -> {
        assertThat(routeDists).hasSize(3);
        return true;
    });
}
@测试
公共无效名称(){
//CachedThreadPool,以避免创建100个或更多线程。最好使用自己的调度程序(例如测试)
ThreadPoolExecutor threadPool=新的ThreadPoolExecutor(0,10,
60升,时间单位。秒,
新建SynchronousQueue());
//使用代理包装真实客户端,以便将subscribeActual调用移动到线程池
Client Client=new ClientProxy(new clientmpl(),Schedulers.from(threadPool));
List observables=Arrays.asList(client.routeDist(),client.routeDist(),client.routeDist());
TestObserver test=Observable.zip(可观察对象,对象->{
返回array.stream(objects).map(t->(RouteDist)t.collect(Collectors.toList());
})
.observeOn(AndroidSchedulers.mainThread())
.test();
测试计数(1);
//验证是否在Android EventLoop中调用了subscribe中的onNext
assertThat(test.lasthread()).isEqualTo(Looper.getMainLooper().getThread());
//验证是否进行了3次呼叫并合并到一个列表中
test.assertValueAt(0,路由列表->{
资产(routeDists)。hasSize(3);
返回true;
});
}
进一步阅读:

注: 不建议一次并发调用100次API。此外,使用Zip时,当您有足够大的线程池时,这将实际发生。当一个API调用超时时,此API调用可能会发出OneError。OneError将进一步传播到订阅服务器。您将不会得到任何结果,即使only-on-API调用失败,建议下一步进行一些操作