RxJava 重构的一个嵌套回调
需求:将百度地图的 js文件缓存到本地。百度地图js API需要引入一个js文件,为了提高地图加载速度,决定将js文件缓存到本地。
- http://api.map.baidu.com/api?v=2.0&ak=xNUVOanwO3w8XGGPT403G2Ks
- 访问url 得到一个函数,函数中包含一个script引入一个js文件,截取url下载文件。
一: 传统的方式
private void getNewFileAddress() {
httpUtils.send(HttpMethod.GET, address, new RequestCallBack<String>() {
@Override
public void onFailure(HttpException exception, String arg1) {
}
@Override
public void onSuccess(ResponseInfo<String> response) {
String result = response.result;
Matcher m = Pattern.compile("[a-zA-z]+://[^\\s\"]*").matcher(result); //匹配src
if(m.find()){
cacheMapFile(m.group());
Log.i(TAG, "截取到的ip地址为"+m.group());
}
}
});
}
private void cacheMapFile(String address) {
// 缓存的map文件
final File target = new File(Environment.getExternalStorageDirectory(),"baidu-map.js");
httpUtils.send(HttpMethod.GET, address, new RequestCallBack<String>() {
@Override
public void onFailure(HttpException arg0, String response) {
}
@Override
public void onSuccess(ResponseInfo<String> response) {
String result = response.result;
try {
//将js文件保存到本地
IOUtils.write(result, new FileOutputStream(target));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
使用RxJava
public class CacheMapService {
private String TAG = "debug";
public void cache(){
RestAdapter adapter = new RestAdapter.Builder()
.setConverter(new CustomConvert())
.setEndpoint("http://api.map.baidu.com")
.build();
GetUrl getUrl = adapter.create(GetUrl.class);
getUrl.getUrl()
.map(new Func1<String, String>() {
@Override
public String call(String address) {
Matcher m = Pattern.compile("[a-zA-z]+://[^\\s\"]*").matcher(address); //匹配src
if(m.find()){
return m.group();
}
return null;
}
})
.map(new Func1<String, Boolean>() {
@Override
public Boolean call(String url) {
RestAdapter adapter = new RestAdapter.Builder()
.setConverter(new CustomConvert())
.setEndpoint(url)
.build();
String path = String.format("%s/%s", Environment.getExternalStorageDirectory().getAbsolutePath(),"baidu-map.js");
String content = adapter.create(GetCacheFile.class).cacheFile();
FileOutputStream out = null;
try {
out = new FileOutputStream(new File(path));
IOUtils.write(content, out);
} catch (Exception e) {
e.printStackTrace();
}finally{
IOUtils.closeQuietly(out);
}
return true;
}
}).subscribe(new Action1<Boolean>() {
@Override
public void call(Boolean arg0) {
Log.i(TAG, "end...."+arg0);
}
});
}
public interface GetUrl{
@GET("/api?v=2.0&ak=xNUVOanwO3w8XGGPT403G2Ks")
Observable<String> getUrl();
}
public interface GetCacheFile{
@GET("/")
String cacheFile();
}
class CustomConvert implements Converter{
private InputStream in;
@Override
public Object fromBody(TypedInput typeInput, Type type)
throws ConversionException {
try {
in = typeInput.in();
} catch (IOException e) {
e.printStackTrace();
}
String response = null;
try {
response = fromString(in);
} catch (IOException e) {
e.printStackTrace();
};
return response;
}
private String fromString(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line;
while((line=reader.readLine()) != null){
sb.append(line);
}
return sb.toString();
}
@Override
public TypedOutput toBody(Object obj) {
return null;
}
}
}
对比完,使用RxJava代码可能更加繁琐,但是逻辑确很清晰。