Last active
October 20, 2016 06:33
-
-
Save SmartDengg/dafddcc5e990a62a96a0f077860d4340 to your computer and use it in GitHub Desktop.
NetWorkingPractice
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| **Android生态圈发展步伐之快,网络框架更是层出不穷,本次主讲人将带你回顾网络框架的变迁史,并对比时下流行网络框架,阐述他的经验,以及这些演变背后的原因。** | |
| Android开发生态圈的节奏非常之快。每周都会有新的工具诞生,类库的更新,博客的发表以及技术探讨。 | |
| 如果你外出度假,当你回来的时候可能已经发布了新版本的 | |
| 网络框架不同于其他,因为它在一定程度上与业务耦合度极高,甚至从代码的角度来说会遍布于工程的各个角落,很难集中管理,一旦替换甚至还要经过漫长的调试过程。 | |
| 不同与图像加载,日志打印等框架那样,在短时间内就能够进行重构,而且一直沿用多个迭代版本也是正常的。 | |
| 这一次我会跟大家一起回顾Android开发中那些常见的网络加载类,还有库。 | |
| 阐述我的观点,分享我的经验,希望大家能够喜欢。 | |
Author
Author
ALL RXJAVA WITH RETROFIT
优雅线程切换,统一的错误处理,回调天堂,统统给你。
比如说现在有一个需求,通过webservice获取城市列表 -> 根据返回的结果,通过城市ID获取电影列表 -> 根绝返回的结果,通过电影ID获取电影详情 -> 进行展示。
首先定义java接口
interface Service {
//获取城市列表集合
@GET("movie/citys") Observable<List<CityListResponse>> getCityList();
//根据城市ID获取电影列表集合
@GET("movie/movies.today") Observable<List<MovieListResponse>> getMovies(
@Query("cityid") String cityId);
//根据电影ID获取电影详情
@GET("movie/query") Observable<MovieDetailResponse> getMovieDetail(
@Query("movieid") String movieId);
}
处理网络操作的逻辑如下:
private void retrieveMovies() {
final Service service = ServiceGenerator.createService(Service.class);
//1. 获取城市列表(网络操作)
service.getCityList()
.concatMap(new Func1<List<CityListResponse>, Observable<CityListResponse>>() {
@Override
public Observable<CityListResponse> call(List<CityListResponse> cityListResponses) {
//2.依次取出"城市列表"集合中的元素
return Observable.from(cityListResponses);
}
})
.concatMap(new Func1<CityListResponse, Observable<List<MovieListResponse>>>() {
@Override
public Observable<List<MovieListResponse>> call(CityListResponse cityListResponse) {
//3.根据每一个城市的id,获取该城市的电影列表(网络操作)
return service.getMovies(cityListResponse.cityId);
}
})
.concatMap(new Func1<List<MovieListResponse>, Observable<MovieListResponse>>() {
@Override
public Observable<MovieListResponse> call(List<MovieListResponse> movieListResponses) {
//4.依次取出"电影列表"集合中的元素
return Observable.from(movieListResponses);
}
})
.concatMap(new Func1<MovieListResponse, Observable<MovieDetailResponse>>() {
@Override
public Observable<MovieDetailResponse> call(MovieListResponse movieListResponse) {
//5.根据每一个电影的ID,获取该电影详情(网络操作)
return service.getMovieDetail(movieListResponse.movieId);
}
})
.subscribeOn(Schedulers.newThread())// 6.线程切换,上游的所有操作执行在工作线程
.observeOn(AndroidSchedulers.mainThread())//7.线程切换,下游的所有将操作执行在UI线程
.subscribe(new Subscriber<MovieDetailResponse>() {
@Override public void onCompleted() {
// finishCompletion
}
@Override public void onError(Throwable e) {
//error handler
}
@Override public void onNext(MovieDetailResponse movieDetailResponse) {
//8.根据电影ID所获取到的电影详情,该函数会被调用多次。
textView.append(movieDetailResponse.movieName);
}
});
}
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment

接下来的这一段,我想跟大家分享一下,我在日常开发中,尤其是处理网络操作的时候,遇到的那些棘手问题,并且经常让我感到困惑的事情。
这一段应该插在httpurlconnection和httpclient的对比之后。文字有限,不再赘述,大部分都会来自于口述。
那么现在假设,我们已经有了封装性极好的http客户端,我们不关心它的内部实现,也就是说它可以由
HttpUrlconnection实现,也可以由httpclient实现,只不过这些细节,我们不再关注。假设它的健壮性非常好,合理的线程池调度,超时时间,甚至网络缓存等。OK,我们有了一个配置如此强大的客户端后,那就开始使用吧,但是需要注意的是,我们还没有处理响应的回调接口,没关系,我们还有一个老朋友AsyncTask,他可以帮助我们来处理这些异步任务,而且我们自己封装的HTTP客户端在绝大多数工程中都是跟AsyncTask搭配使用的。不过AsyncTask并不属于本次演讲的内容,因此不做过多赘述,你只需要记住,它是一个在future-task的基础上,封装了Handler消息机制,通过线程池调度处理异步任务的类。
比如,我要加载一些URL,以字符串的形式展示这些地址的返回结果。
假设
EffectiveHttpClient就是我在上面提到的,自定义的高效HTTP客户端,再所一遍,我们不考虑它的内部细节实现。那么回到这个例子中,看一看,哪些地方使我们不能接受的,或者说,这样会带来什么隐患。
我们先从代码的角度来考虑问题:
onDestroy()。而AsyncTask运行,由于非静态内部类会持有外部类的引用,这就造成了ACT/Fragment的泄漏,如果继续在onPostExecute()中更新UI,可能引起NPE,或者其他崩溃隐患,而且我们很难真正取消一个正在运行的线程。