Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.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中,如何在可观察对象中处理map()中的异常_Java_Android_Rx Java_Rx Android - Fatal编程技术网

在RxJava中,如何在可观察对象中处理map()中的异常

在RxJava中,如何在可观察对象中处理map()中的异常,java,android,rx-java,rx-android,Java,Android,Rx Java,Rx Android,我想这样做: Observable.just(bitmap) .map(new Func1<Bitmap, File>() { @Override public File call(Bitmap photoBitmap) { //File creation throws IOException, //I just

我想这样做:

Observable.just(bitmap)
            .map(new Func1<Bitmap, File>() {
                @Override
                public File call(Bitmap photoBitmap) {

                    //File creation throws IOException, 
                    //I just want it to hit the onError() inside subscribe()

                    File photoFile = new File(App.getAppContext().getCacheDir(), "userprofilepic_temp.jpg");
                    if(photoFile.isFile()) {//delete the file first if it exists otherwise the new file won't be created
                        photoFile.delete();
                    }
                    photoFile.createNewFile(); //saves the file in the cache dir

                    FileOutputStream fos = new FileOutputStream(photoFile);
                    photoBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);//jpeg format
                    fos.close();

                    return photoFile;

                }
            })
            .subscribe(//continue implementation...);
Observable.just(位图)
.map(新函数1(){
@凌驾
公共文件调用(位图照片位图){
//文件创建引发IOException,
//我只想让它在subscribe()中点击onError()
File photoFile=新文件(App.getAppContext().getCacheDir(),“userprofilepic_temp.jpg”);
如果(photoFile.isFile()){//首先删除文件(如果存在),否则将不会创建新文件
photoFile.delete();
}
photoFile.createNewFile();//将文件保存在缓存目录中
FileOutputStream fos=新的FileOutputStream(照片文件);
photoBitmap.compress(Bitmap.CompressFormat.JPEG,90,fos);//JPEG格式
fos.close();
返回照片文件;
}
})
.subscribe(//继续实施…);

基本上在
call()
方法中,它可以抛出异常。如何让观察者在
onError()
中处理它。或者这不是正确的思考方式吗?

对于1.0.15,有一个
fromCallable
工厂方法,让您为每个订阅者运行一个
Callable
实例,您也可以在其中抛出选中的异常:

Observable.fromCallable(() -> {      
    File photoFile = new File(App.getAppContext().getCacheDir(),
        "userprofilepic_temp.jpg");
    if (photoFile.isFile()) {
       //delete the file if it exists otherwise the new file won't be created
        photoFile.delete();
    }
    photoFile.createNewFile(); //saves the file in the cache dir

    FileOutputStream fos = new FileOutputStream(photoFile);
    photoBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);//jpeg format
    fos.close();

    return photoFile;
})
.subscribe(...)
编辑:


rx将始终捕获错误,即使这是RuntimeException。 所以您可以在catch块中抛出某种运行时异常。这就是它实际上应该如何工作

 Observable.just(bitmap)
                .map(b -> {
                    try {
                        // do some work which throws IOException
                        throw new IOException("something went wrong");
                    } catch (IOException e) {
                        throw new RXIOException(e);
                        // Or you can use 
                        throw Exceptions.propagate(e);
                        // This helper method will wrap your exception with runtime one
                    }
                }).subscribe(o -> {
                    // do something here
                }, exception -> exception.printStackTrace());

public static class RXIOException extends RuntimeException {
        public RXIOException(IOException throwable) {
            super(throwable);
        }
}

刚刚创建了helper类以将此样板文件提取到另一个位置:

public class RxRethrow {
    public static <T, R> Func1<T, R> rethrow(Func1R<T, R> catchedFunc) {
        return t -> {
            try {
                return catchedFunc.call(t);
            } catch (Exception e) {
                throw Exceptions.propagate(e);
            }
        };
    }

    public interface Func1R<T, R> extends Function {
        R call(T t) throws Exception;
    }
}

我不知道这个问题第一次被问到和回答时的情况如何,但RxJava目前包含了一个用于此确切目的的helper方法:
异常。传播(可丢弃的t)

直接抛出RuntimeException和错误或将任何其他异常类型包装到RuntimeException中的方便方法


我想这在这种情况下是可行的,但是如果我想将依赖于第一个映射的输出的两个映射链接在一起呢。使用
Func1()
我可以获得返回类型和参数。您必须使用flatMap,尝试catch并返回just()或error()。工作起来像champ!!当我尝试这样做时,它要求我用一个try catch来包围异常,您必须抛出RuntimeException。JVM不会要求您用try-catch来包围它。这就是我的想法,让
call()
抛出一个IOException,但它说重写的方法不会抛出IOExceptionName。IOException不是运行时异常。再读一遍我的答案。啊,对不起。完全有道理。你能看一下上面@akarnokd的答案吗?它使用了
Observable.error
。您会推荐您的方法吗?请注意,在RXJava2中,像
map
这样的操作符允许从lambda抛出已检查的异常。这实际上是RxJava 1中的一个设计缺陷,因为抛出的确切错误无法在映射lambda的“onError”中传播,而不会包装为
RuntimeException
@Sree哇,我实际上没有发现这一点,我被自定义异常类蒙蔽了双眼。现在,我仔细看,我可以看到,实际上有另一个答案在这里使用相同的方法。
public class RxRethrow {
    public static <T, R> Func1<T, R> rethrow(Func1R<T, R> catchedFunc) {
        return t -> {
            try {
                return catchedFunc.call(t);
            } catch (Exception e) {
                throw Exceptions.propagate(e);
            }
        };
    }

    public interface Func1R<T, R> extends Function {
        R call(T t) throws Exception;
    }
}
.map(RxRethrow.rethrow(products -> mapper.writer(schema).writeValueAsString(products)))