`
yanfaguanli
  • 浏览: 662594 次
文章分类
社区版块
存档分类
最新评论

Android中关于Volley的使用(三)认识Volley的架构

 
阅读更多
前面我们讲了怎么应用Volley从网络获取图片跟JSON数据,具体的应用如下:
1)通过Volley类获得一个RequestQueue对象:
mQueue = Volley.newRequestQueue(this);  

2)创建一个Request对象,并将请求添加上面创建的mQueue中,如下:
    ImageRequest imgRequest = new ImageRequest(imgUrl,  
            new Response.Listener<Bitmap>() {  
                @Override  
                public void onResponse(Bitmap arg0) {  
                    // TODO Auto-generated method stub  
                    imageView.setImageBitmap(arg0);  
                }  
            },   
            300,   
            200,   
            Config.ARGB_8888,   
            new ErrorListener() {  
                @Override  
                public void onErrorResponse(VolleyError arg0) {  
                      
                }  
            });  
    mQueue.add(imgRequest);

一开始会不会觉得有点怔,为什么只需要将请求添加到队列中,不需要去发送请求吗?当然是要的,只是这一切都被封装在Volley后面而已。
我们先来看一下隐藏在Volley后面的这个架构是怎么样的吧,如下图:
首先,我们要先了解一下Volley的架构,简单地来说,就是三层:
1)队列:将请求添加到Queue中
2)缓存:在Cache中查找有没有缓存这个请求要的数据,
2.1)有,请求如果过期了,到第 3)步,如果没有过期,直接返回一个Response。
2.2)没有,到第 3)步
3)网络:通过传进来的url 来发送请求,到网络中获取数据,然后返回一个Response,并判断是否要存到Cache中。
结合上图,我们来简单地先说一下Volley的流程是怎么样的。
第一步:通过Volley.newRequestQueue方法创建一个RequestQueue队列,而且同时会创建如下三个对象:
a)一个HttpStack对象,Volley会根据SDK的版本来判断是基于HttpUrlConnection还是基于HttpClient来创建对象,一个HttpStack对象,只用一件事,就是去真正的执行这个请求,去网络上拿回数据,其定义如下:
public interface HttpStack {
    /**
     * Performs an HTTP request with the given parameters.
     *
     * <p>A GET request is sent if request.getPostBody() == null. A POST request is sent otherwise,
     * and the Content-Type header is set to request.getPostBodyContentType().</p>
     *
     * @param request the request to perform
     * @param additionalHeaders additional headers to be sent together with
     *         {@link Request#getHeaders()}
     * @return the HTTP response
     */
    public HttpResponse performRequest(Request<?> request, Map<String, String> additionalHeaders)
        throws IOException, AuthFailureError;
}


b)一个Network对象,在Volley的实现是BasicNetwork类,在构建这个对象的时候,一个HttpStack对象去传给它作为参数,而它将会调用这个HttpStack去获取事情。它是对HttpUrlConnection和HttpClient的一个包装,让外面的对象不用去关心到底是通过哪个接口来获取数据。

public interface Network {
    /**
     * Performs the specified request.
     * @param request Request to process
     * @return A {@link NetworkResponse} with data and caching metadata; will never be null
     * @throws VolleyError on errors
     */
    public NetworkResponse performRequest(Request<?> request) throws VolleyError;
}

看一下它的实现类BasicNetwork中是如何实现的这个接口中的方法的,看下面代码中的最后一行:
public NetworkResponse performRequest(Request<?> request) throws VolleyError {
        long requestStart = SystemClock.elapsedRealtime();
        while (true) {
            HttpResponse httpResponse = null;
            byte[] responseContents = null;
            Map<String, String> responseHeaders = new HashMap<String, String>();
            try {
                // Gather headers.
                Map<String, String> headers = new HashMap<String, String>();
                addCacheHeaders(headers, request.getCacheEntry());
                httpResponse = mHttpStack.performRequest(request, headers);

c)一个Cache对象,这是一个缓存对象,Volley中默认的实现类是DiskBasedCache类。
第二步:创建好RequestQueue之后,就会调用其start方法。而在其start方法呢,就会去创建两个线程,就是图上面的CacheDispatcher和NetworkDispatcher了,如下:
    public void start() {
        stop();  // Make sure any currently running dispatchers are stopped.
        // Create the cache dispatcher and start it.
        mCacheDispatcher = new CacheDispatcher(mCacheQueue, mNetworkQueue, mCache, mDelivery);
        mCacheDispatcher.start();


        // Create network dispatchers (and corresponding threads) up to the pool size.
        for (int i = 0; i < mDispatchers.length; i++) {
            NetworkDispatcher networkDispatcher = new NetworkDispatcher(mNetworkQueue, mNetwork,
                    mCache, mDelivery);
            mDispatchers[i] = networkDispatcher;
            networkDispatcher.start();
        }
    }

当然,也需要让这两个线程跑起来,我们也可以在这里看到,在Volley类中创建的Network接口对象,Cache接口对象,还有一个包装了Handler类的对象mDelivery都会在这里作为参数传给CacheDispatcher和NetworkDispatcher,当然,最重要的,也会将RequestQueue这个装请求的队列给传进去,而这两个线程一旦开始之后,就会一直处理或者等待请求。
第三步:如果Cache中没有记录的话,还是需要通过NetworkDispatcher去实现的,所以接下来就是Network在后面做事情了,看下面的代码:
    public void run() {
        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
        Request<?> request;
        while (true) {
                ...
                // Perform the network request.
                NetworkResponse networkResponse = mNetwork.performRequest(request);
                request.addMarker("network-http-complete");

其实也就是调用Network去发送请求,而Network又会调用HttpStack去发送请求。
第四步:通过Handler将Response给传回主线程中定义的Listener,
 mDelivery.postResponse(request, response);       


而mDelivery其实是一个ExecutorDelivery对象,它封装了Handler,通过它,会调用到请求的deliverResponse方法,如下:

            // Deliver a normal response or error, depending.
            if (mResponse.isSuccess()) {
                mRequest.deliverResponse(mResponse.result);
            } else {
                mRequest.deliverError(mResponse.error);
            }

而每个具体的请求都需要去实现自己的逻辑,比如在ImageRequest中,
    private final Response.Listener<Bitmap> mListener;
    
    @Override
    protected void deliverResponse(Bitmap response) {
        mListener.onResponse(response);
    }
    

我们可以看到,它其实也就是调用Listener中的onResponse方法,而Listener的这个方法,则是我们在创建Request对象的时候,需要去实现的一个方法,所以一切都跑回到
主线程中方法去了。
嗯,隐藏在Volley后面大概的流程就是这样。结束。
分享到:
评论

相关推荐

    android MVP简单使用

    android中MVP架构的简单使用,工程中包括了android-support-design的简单使用,gson的使用,data-binding的使用,以及对volley做了一个简单的封装。并且其中还包括了后台java代码

    Android代码-Android-Http-Example

    集成了android-async-http, volley, okhttp3等网络请求框架.可直接切换底层库. 1 简介 架构分层 总共分为三层: 网络请求调用层. app统一调用该层接口和这层提供的回调,该层可以切换不同的网络请求库. 网络请求库...

    http-lib-based-on-volley:基于volley的http连接库,封装了各种异步同步请求方法

    http-lib-based-on-volley基于Google Volley的Http库android http lib based on volley使用说明:一、优化了volley的组织结构,重新定义的包架构更加清晰明了,方便阅读,扩展包组织结构图如下所示:base包中包括了...

    volley+async

    android两种流行的网络(http)请求架构.

    各种框架学习

    该代码包含了Android中常用的框架学习,可在Android Studio中直接运行出来

    Android代码-SweetMusicPlayer

    拥有播放本地、在线音乐以及mv等功能,采用 MVP RxJava Retrofit 架构的项目, 使用Java和Kotlin混合开发。 更多请看博客。 Features 本地音乐按照歌曲,专辑,艺术家显示对应信息 在线搜索音乐并播放 智能匹配本地...

    Android项目源码煎蛋网非官方客户端项目源码.zip

    MVC架构的使用 对超长图片加载的解决方案 WebView与JS通信,及加载本地缓存图片的实现 RecyclerView自动加载、加载完成回调,以及item进入动画 多楼层回复自定义控件的实现 严格模式(StrictMode)的设置及用法 ...

    Android项目源码开源的 Material Design 豆瓣客户端.zip

    使用 Support Library 中的 AppCompat、Design、CardView、RecyclerView 进行 Material Design 实现,在必要时引入/自己写作第三方库以实现部分界面元素和效果。 使用框架的 Shared Element Transition 实现在 ...

    Android中网络框架简单封装的实例方法

    访问网络,最基本的接口有:HttpUrlConnection,HttpClient,而在后续的发展中,出现了Volley,OkHttp,Retrofit等网络封装库。由于各种原因,在实际的项目开发中,我们可能会需要在项目的版本迭代中,切换网络框架。...

    JianDan-高仿煎蛋客户端.zip

    项目虽小,五脏俱全,学习这个项目,你将学到Android Studio开发Android的基本配置对MD风格的Theme兼容对Volley网络请求库的封装和自定义Application、Activity和Fragment基类的基本设计MVC架构的使用对超长图片加载...

    安卓java读取网页源码-Android-Resourse:安卓资源

    安卓java读取网页源码 -Android经久不衰最受欢迎的开源库整理,你一定用过10个以上,架构师必备 文末附开源框架综合使用开源APP项目 第三方库 一 、网络请求 1、Android Async HTTP Android异步HTTP库 ...

    LDXY:“灵动校园”项目 (基于android客户端的学生社交平台)

    关于SmartImageView开源控件的使用smartImageVIew,支持从URL和通讯录中获取图像,可以替代Android标准的ImageView特征根据URL地址装载图像;支持装载通讯录中的图像;支持异步装载;支持缓存;开源项目

    warm-package:Android的保暖包

    这是一个使用Kotlin 语言撰写的Android 专案,此App 的功能是在画面上显示现在的电池温度,你可以使用Seekbar 调整想要让手机发烫到几度,按了Float Action Button 后App 就会开始做事情让手机发烫,发烫期间你可以...

    Android项目源码煎蛋网非官方客户端项目

    注意:本项目基于android studio开发,eclipse可能...MVC架构的使用 对超长图片加载的解决方案 WebView与JS通信,及加载本地缓存图片的实现 RecyclerView自动加载、加载完成回调,以及item进入动画 多楼层回复自定

    popularMoviesApp:显示流行的电影

    热门电影应用 应用程序显示流行或收视率最高的电影的网格排列,并允许用户点击电影海报并切换到“详细信息屏幕”以观看预告片或阅读评论。 允许用户在本地将电影标记为收藏,以... 在应用中使用了Picasso和AysncTask。

    Android 项目实战-影讯

    本课程包含14个小节课程,内容包括:影讯项目演示,影讯项目架构,使用聚合API后台,封装Volley网络框架,根据JSON格式创建JavaBean,实现底部导航 ,实现侧滑菜单,实现MovieDao,实现可索引ListView,集成百度地图...

    基于安卓的网上订餐系统,优秀毕业设计系统,新手必看!

    系统采用C/S(服务端/客户端)架构,Android网络通讯框架采用Volley,服务器开发采用JavaEE进行开发,通过HTTP协议进行网络数据的请求发送。 用户功能模块: ◆注册:用户注册账号,需提供用户名,密码,电子邮箱等。 ...

    详解Android 教你打造高效的图片加载框架

    优秀的图片加载框架不要太多,什么UIL , Volley ,Picasso,Imageloader等等。但是作为一名合格的程序猿,必须懂其中的实现原理,于是乎,今天我就带大家一起来设计一个加载网络、本地的图片框架。有人可能会说,自己...

    HackInCity:我们在2015 HackNTU的作品

    HackInCity ... ##Login/Logout/sign up部分用到Volley、SQLite和SharedPreferences,撰写架构良好值得模仿 ##Tab切换Fragment部分有些赶所以写的乱,用的是Android 5.0的ToolBar #上传照片可运作

    百度地图开发java源码-Programming-Journey:SomeApplicationhavebeendevelopedby1anc

    口袋是一个工具与资讯聚合类应用,在的基础上加入很多以往项目中的代码,算是对我的Android学习之旅的阶段性总结。口袋一方面可以作为工具发短信打电话、管理各类型文件、查询天气、简单计算、翻译单词、摩斯电码、...

Global site tag (gtag.js) - Google Analytics