广告
返回顶部
首页 > 资讯 > 精选 >Android框架之Volley源码的示例分析
  • 208
分享到

Android框架之Volley源码的示例分析

2023-06-15 09:06:11 208人浏览 独家记忆
摘要

这篇文章主要介绍Android框架之Volley源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Volley简单使用我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。好了,接下来上代码了

这篇文章主要介绍Android框架之Volley源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

Volley简单使用

我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。

Android框架之Volley源码的示例分析

好了,接下来上代码了.....

//获取volley的请求对象        RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());        StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, "Http://www.baidu.com", new Response.Listener<String>() {            @Override            public void onResponse(String s) {                Log.d("MainActivity", "----->" + s);            }        }, new Response.ErrorListener() {            @Override            public void onErrorResponse(VolleyError volleyError) {                Log.d("MainActivity", "---volleyError-->" + volleyError);            }        });        requestQueue.add(stringRequest);

从代码可以看出,首先newRequestQueue来获取到一个请求队列,然后在将StringRequest这个请求添加到请求队列中,就可以了,就是这么简单。当然请求不值StringRequest,还有JSONObjectRequest ,ImageRequest等等但是用法都是一样的,这里就不贴代码了。Volley的简单使用就这样可以进行请求了。是不是很简单

Volley执行原理

但是这个不是本篇的重点,重点是分析一下这些是怎么执行的。先上一张图

Android框架之Volley源码的示例分析

我们先看看newRequestQueue这个内部是怎么执行的,代码一开始连续执行了几个重载方法,最后走到newRequestQueue

public static RequestQueue newRequestQueue(Context context, httpstack stack, int maxDiskCacheBytes) {    File cacheDir = new File(context.getCacheDir(), "volley");    String userAgent = "volley/0";    try {        String packageName = context.getPackageName();        PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);        userAgent = packageName + "/" + info.versionCode;    } catch (NameNotFoundException var7) {        ;    }    //这里进行了一个版本的判断 2.3之前用的是HTTPClient,2.3之后使用的是HttpURLConnection    if (stack == null) {        if (VERSION.SDK_INT >= 9) {            stack = new HurlStack();        } else {            stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));        }    }    Network network = new BasicNetwork((HttpStack)stack);    RequestQueue queue;    if (maxDiskCacheBytes <= -1) {        queue = new RequestQueue(new DiskBasedCache(cacheDir), network);    } else {        queue = new RequestQueue(new DiskBasedCache(cacheDir, maxDiskCacheBytes), network);    }    queue.start();    return queue;}

在这里,我们看到了一个版本判断,是不是瞬间感觉有点熟悉,没错,我们前面说的,volley2.3之前用的是HTTPClient,2.3之后使用的是HttpURLConnection就是在这里进行判断的。接着看queue.start();

public void start() {        this.stop();        this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);        this.mCacheDispatcher.start();        for(int i = 0; i < this.mDispatchers.length; ++i) {            NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery);            this.mDispatchers[i] = networkDispatcher;            networkDispatcher.start();        }    }

mCacheDispatcher是缓存调度线程,NetworkDispatcher是网络调度线程,而这个this.mDispatchers.length系统默认的大小为4,也就是说,在这里总共启动了5个线程在后台运行。

好了,到这里,就可以了,看源码不要每一行都弄懂,不然,出不来了。到这里就拿到了这个RequestQueue对象。回过头来看前面使用的代码

//获取volley的请求对象RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());StringRequest stringRequest = new StringRequest(StringRequest.Method.GET, "http://www.baidu.com", new Response.Listener<String>() {    @Override    public void onResponse(String s) {        Log.d("MainActivity", "----->" + s);    }}, new Response.ErrorListener() {    @Override    public void onErrorResponse(VolleyError volleyError) {        Log.d("MainActivity", "---volleyError-->" + volleyError);    }});requestQueue.add(stringRequest);

我们拿到这个RequestQueue对象以后,然后就把这个请求通过add方法添加到队列中,我们看看这个add()方法是怎么执行的。

public <T> Request<T> add(Request<T> request) {        request.setRequestQueue(this);        Set var2 = this.mCurrentRequests;        synchronized(this.mCurrentRequests) {            this.mCurrentRequests.add(request);        }        request.setSequence(this.getSequenceNumber());        request.addMarker("add-to-queue");        if (!request.shouldCache()) { //如果不能缓存            this.mNetworkQueue.add(request);            return request;        } else {            Map var7 = this.mWaitingRequests;            synchronized(this.mWaitingRequests) {                String cacheKey = request.getCacheKey();                if (this.mWaitingRequests.containsKey(cacheKey)) { //判断之前是否执行过,但是还没有返回结果                    Queue<Request<?>> stagedRequests = (Queue)this.mWaitingRequests.get(cacheKey);                    if (stagedRequests == null) {                        stagedRequests = new LinkedList();                    }                    ((Queue)stagedRequests).add(request);                    this.mWaitingRequests.put(cacheKey, stagedRequests);                    if (VolleyLog.DEBUG) {                        VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", new Object[]{cacheKey});                    }                } else {                //没有的话就将请求加入缓存队列mCacheQueue,同时加入mWaitingRequests中用来做下次同样请求来时的重复判断依据                    this.mWaitingRequests.put(cacheKey, (Object)null);                    this.mCacheQueue.add(request);                }                return request;            }        }    }

从代码中可以看出,首先判断是否可以缓存,当然,默认是可以缓存的。如果不能缓存的话,则通过this.mNetworkQueue.add(request);将请求添加到网络请求队列中。如果可以缓存,则还会判断一次这个请求是否请求,如果执行过就就通过this.mWaitingRequests.put(cacheKey, stagedRequests);添加到mWaitingRequests队列,不在重复请求。否则就加入到缓存队列。

大体的流程是这样。现在我们看看缓存的,和网络的是怎么执行的。我们找到start()方法

public void start() {        this.stop();        this.mCacheDispatcher = new CacheDispatcher(this.mCacheQueue, this.mNetworkQueue, this.mCache, this.mDelivery);        this.mCacheDispatcher.start();        for(int i = 0; i < this.mDispatchers.length; ++i) {            NetworkDispatcher networkDispatcher = new NetworkDispatcher(this.mNetworkQueue, this.mNetwork, this.mCache, this.mDelivery);            this.mDispatchers[i] = networkDispatcher;            networkDispatcher.start();        }    }

先看CacheDispatcher,找到run()方法

public void run() {        if (DEBUG) {            VolleyLog.v("start new dispatcher", new Object[0]);        }        Process.setThreadPriority(10);        this.mCache.initialize();        while(true) {            while(true) {                while(true) {                    while(true) {                        try {                            while(true) {                                final Request<?> request = (Request)this.mCacheQueue.take(); //从缓存队列中获取到一个请求                                request.addMarker("cache-queue-take");                                if (request.isCanceled()) { //判断请求是否取消,如果取消了,那就将该请求finish掉                                    request.finish("cache-discard-canceled");                                } else {                                    Entry entry = this.mCache.get(request.getCacheKey());                                    if (entry == null) {//如果从缓存中取出来的内容为空,则将请求加入到网络线程中再次请求                                        request.addMarker("cache-miss");                                        this.mNetworkQueue.put(request);                                    } else if (entry.isExpired()) { //如果请求过期了,则将请求加入到网络线程中再次请求                                        request.addMarker("cache-hit-expired");                                        request.setCacheEntry(entry);                                        this.mNetworkQueue.put(request);                                    } else { //将数据回调到主线程                                        request.addMarker("cache-hit");                                        Response<?> response = request.parseNetworkResponse(new NetworkResponse(entry.data, entry.responseHeaders));                                        request.addMarker("cache-hit-parsed");                                        if (entry.refreshNeeded()) {                                            request.addMarker("cache-hit-refresh-needed");                                            request.setCacheEntry(entry);                                            response.intermediate = true;                                            this.mDelivery.postResponse(request, response, new Runnable() {                                                public void run() {                                                    try {                                                        CacheDispatcher.this.mNetworkQueue.put(request);                                                    } catch (InterruptedException var2) {                                                        ;                                                    }                                                }                                            });                                        } else {                                            this.mDelivery.postResponse(request, response);                                        }                                    }                                }                            }                        } catch (InterruptedException var4) {                            if (this.MQuit) {                                return;                            }                        }                    }                }            }        }    }

这里嵌套了几个循环,有点凌乱啊,但是慢慢分析的话,就会发现,其实很清晰。我在注释上面写了,这里就不重复了

我们在看看NetworkDispatcher,看看网络线程是怎么执行的。一样找到run()方法

public void run() {        Process.setThreadPriority(10);        while(true) {            long startTimeMs;            Request request;            while(true) {                startTimeMs = SystemClock.elapsedRealtime();                try {                    request = (Request)this.mQueue.take(); //获取到一个请求                    break;                } catch (InterruptedException var6) {                    if (this.mQuit) {                        return;                    }                }            }            try {                request.addMarker("network-queue-take");                if (request.isCanceled()) { //如果请求取消了,则将请求finish掉                    request.finish("network-discard-cancelled");                } else {//进行网络请求                    this.addTrafficStatsTag(request);                    NetworkResponse networkResponse = this.mNetwork.perfORMRequest(request);                    request.addMarker("network-http-complete");                    if (networkResponse.notModified && request.hasHadResponseDelivered()) {                        request.finish("not-modified");                    } else {                        Response<?> response = request.parseNetworkResponse(networkResponse);                        request.addMarker("network-parse-complete");                        if (request.shouldCache() && response.cacheEntry != null) {                            this.mCache.put(request.getCacheKey(), response.cacheEntry);                            request.addMarker("network-cache-written");                        }                        request.markDelivered();                        this.mDelivery.postResponse(request, response);                    }                }            } catch (VolleyError var7) {                var7.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);                this.parseAndDeliverNetworkError(request, var7);            } catch (Exception var8) {                VolleyLog.e(var8, "Unhandled exception %s", new Object[]{var8.toString()});                VolleyError volleyError = new VolleyError(var8);                volleyError.setNetworkTimeMs(SystemClock.elapsedRealtime() - startTimeMs);                this.mDelivery.postError(request, volleyError);            }        }    }

代码比较多,我们直接找到NetworkResponse networkResponse = this.mNetwork.performRequest(request);这句代码,这句代码就是请求网络的代码,最核心的。performRequest是一个接口,我们看看这个performRequest()方法。Network在最开始说版本判断的时候里面有一句代码Network network = new BasicNetwork((HttpStack)stack);  从这句代码,我们可以知道BasicNetwork才是最终实现网络请求的类,我们找到performRequest方法

public NetworkResponse performRequest(Request<?> request) throws VolleyError {        long requestStart = SystemClock.elapsedRealtime();        while(true) {            HttpResponse httpResponse = null;            byte[] responseContents = null;            Map responseHeaders = Collections.emptyMap();            try {                Map<String, String> headers = new HashMap();                this.addCacheHeaders(headers, request.getCacheEntry());                httpResponse = this.mHttpStack.performRequest(request, headers);                StatusLine statusLine = httpResponse.getStatusLine();                int statusCode = statusLine.getStatusCode();                responseHeaders = convertHeaders(httpResponse.getAllHeaders());                if (statusCode == 304) {                    Entry entry = request.getCacheEntry();                    if (entry == null) {                        return new NetworkResponse(304, (byte[])null, responseHeaders, true, SystemClock.elapsedRealtime() - requestStart);                    }                    entry.responseHeaders.putAll(responseHeaders);                    return new NetworkResponse(304, entry.data, entry.responseHeaders, true, SystemClock.elapsedRealtime() - requestStart);                }                if (statusCode == 301 || statusCode == 302) {                    String newUrl = (String)responseHeaders.get("Location");                    request.setRedirectUrl(newUrl);                }                byte[] responseContents;                if (httpResponse.getEntity() != null) {                    responseContents = this.entityToBytes(httpResponse.getEntity());                } else {                    responseContents = new byte[0];                }                long requestLifetime = SystemClock.elapsedRealtime() - requestStart;                this.logSlowRequests(requestLifetime, request, responseContents, statusLine);                if (statusCode >= 200 && statusCode <= 299) {                    return new NetworkResponse(statusCode, responseContents, responseHeaders, false, SystemClock.elapsedRealtime() - requestStart);                }                throw new IOException();            } catch (SocketTimeoutException var12) {                attemptRetryOnException("socket", request, new TimeoutError());            } catch (ConnectTimeoutException var13) {                attemptRetryOnException("connection", request, new TimeoutError());            } catch (MalformedURLException var14) {                throw new RuntimeException("Bad URL " + request.getUrl(), var14);            } catch (IOException var15) {                int statusCode = false;                NetworkResponse networkResponse = null;                if (httpResponse == null) {                    throw new NoConnectionError(var15);                }                int statusCode = httpResponse.getStatusLine().getStatusCode();                if (statusCode != 301 && statusCode != 302) {                    VolleyLog.e("Unexpected response code %d for %s", new Object[]{statusCode, request.getUrl()});                } else {                    VolleyLog.e("Request at %s has been redirected to %s", new Object[]{request.getOriginUrl(), request.getUrl()});                }                if (responseContents == null) {                    throw new NetworkError(networkResponse);                }                networkResponse = new NetworkResponse(statusCode, (byte[])responseContents, responseHeaders, false, SystemClock.elapsedRealtime() - requestStart);                if (statusCode != 401 && statusCode != 403) {                    if (statusCode != 301 && statusCode != 302) {                        throw new ServerError(networkResponse);                    }                    attemptRetryOnException("redirect", request, new AuthFailureError(networkResponse));                } else {                    attemptRetryOnException("auth", request, new AuthFailureError(networkResponse));                }            }        }    }

代码比较多,但是大多数代码是判断状态返回码的,不需要理会。

我们直接看httpResponse = this.mHttpStack.performRequest(request, headers);这一句代码,HttpStack这个有没有很熟悉。没有??没关系我在复制一次代码

if (stack == null) {    if (VERSION.SDK_INT >= 9) {        stack = new HurlStack();    } else {        stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));    }}

以上是“Android框架之Volley源码的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网精选频道!

--结束END--

本文标题: Android框架之Volley源码的示例分析

本文链接: https://www.lsjlt.com/news/279500.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android框架之Volley源码的示例分析
    这篇文章主要介绍Android框架之Volley源码的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Volley简单使用我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。好了,接下来上代码了...
    99+
    2023-06-15
  • 解析Android框架之Volley源码
    目录Volley简单使用Volley执行原理Volley简单使用 我这里是以依赖架包的形式 ,大家也可以以gradle的形式进行依赖。 好了,接下来上代码了..... //获取...
    99+
    2022-11-12
  • Android框架之OkHttp3源码的示例分析
    这篇文章将为大家详细讲解有关Android框架之OkHttp3源码的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。OkHttp流程图OkHttp基本使用gradle依赖implementation...
    99+
    2023-06-15
  • Android Volley框架使用源码分享
    过去在Android上网络通信都是使用的Xutils 因为用它可以顺道处理了图片和网络这两个方面,后来发觉Xutils里面使用的是HttpClient  而Googl...
    99+
    2022-06-06
    volley框架 volley 源码分享 源码 Android
  • 解析Android框架之OkHttp3源码
    目录OkHttp流程图OkHttp基本使用OkHttp源码分析OkHttp流程图 OkHttp基本使用 gradle依赖 implementation 'com.squareup...
    99+
    2022-11-12
  • PHP之CI框架的示例分析
    这篇文章将为大家详细讲解有关PHP之CI框架的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。一、前言CodeIgniter 是一个简单快速的PHP MVC框架。EllisLab 的工作人员发布了 ...
    99+
    2023-06-20
  • PHP开源AJAX框架的示例分析
    这篇文章主要介绍PHP开源AJAX框架的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在php中,有许许多多的框架,如thinkphp,Laravel等,今天我们就由小编来介绍14种开源的AJAX框架,有需要...
    99+
    2023-06-20
  • vue源码架构的示例分析
    这篇文章将为大家详细讲解有关vue源码架构的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。下载去github上下载Vue https://github.com/v...
    99+
    2022-10-19
  • 从源码分析Android的Volley库的工作流程
    Volley现在已经被官方放到AOSP里面,已经逐步成为Android官方推荐的网络框架。 类抽象 对Http协议的抽象 Requeset 顾名思义,对请求的封装,实现了Com...
    99+
    2022-06-06
    工作流 volley 源码 Android
  • Java源码解析之ConcurrentHashMap的示例分析
    小编给大家分享一下Java源码解析之ConcurrentHashMap的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!早期 ConcurrentHashMap,其实现是基于:分离锁,也就是将内部进行分段(Segme...
    99+
    2023-06-15
  • python源码剖析之PyObject的示例分析
    这篇文章主要介绍python源码剖析之PyObject的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!一、Python中的对象Python中一切皆是对象。————Guido van Rossum(1989)这...
    99+
    2023-06-15
  • Vue源码分析之虚拟DOM的示例分析
    小编给大家分享一下Vue源码分析之虚拟DOM的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!为什么需要虚拟dom?虚拟DOM就是为了解决浏览器性能问题而被...
    99+
    2023-06-15
  • Java基础之MapReduce框架的示例分析
    小编给大家分享一下Java基础之MapReduce框架的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、MapTask工作机制MapTask就是Map阶...
    99+
    2023-06-15
  • Android动画(四)动画框架源码分析
    本篇难度较大,慎入 也许可以先去看总结在来一起分析 从我们写的开始进入: fun click(view: View) { va...
    99+
    2022-06-06
    源码 框架 Android
  • Flask框架的示例分析
    这篇文章主要介绍Flask框架的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!对于python中的框架来说,虽然有一些大型的框架可以供我们挑选,但有时候我们处理数据用不到那么难的框架,这样反而会增加处理数据的...
    99+
    2023-06-14
  • SSM框架的示例分析
    这篇文章主要为大家展示了“SSM框架的示例分析”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“SSM框架的示例分析”这篇文章吧。SSM图示流程:Spring核心:Java反射Mybatis:动态代...
    99+
    2023-06-15
  • SpringMVC框架的示例分析
    小编给大家分享一下SpringMVC框架的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!简介SpringMVC采用模型(Model)-视图(View)-控...
    99+
    2023-06-02
  • webpack源码之loader机制的示例分析
    这篇文章主要介绍webpack源码之loader机制的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!loader概念loader是用来加载处理各种形式的资源,本质上是一个函数...
    99+
    2022-10-19
  • Java集合框架概览之ArrayList源码分析
    今天小编给大家分享一下Java集合框架概览之ArrayList源码分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。一、从一...
    99+
    2023-07-05
  • Java源码解析之接口Collection的示例分析
    小编给大家分享一下Java源码解析之接口Collection的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、图示二、方法定义我们先想一想,公司如果要我...
    99+
    2023-06-15
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作