195_Volley源码解析

来源:互联网 发布:可视化编程软件哪个好 编辑:程序博客网 时间:2024/06/06 07:17

Volley源码解析

我们来看看Volley的源码

 

先看看Volley_lib文件夹下面都有些什么东西

外面一个包volley,很多java文件

volley里面还有一个包toolbox,里面也有很多java文件

 

我们从哪里开始看呢

这样吧,我们怎么用的,就按着使用的流程来看

 

我们就以StringRequest为例子

 

这些Request的流程都差不多的

我们以StringRequest为例子

 

首先是创建了StringRequest

StringRequest stringRequest = new StringRequest(url,new Response.Listener(){},new Response.ErrorListener(){});

 

那么我们就找到这个构造方法

    public StringRequest(String url, Listener<String> listener, ErrorListener errorListener) {

        this(Method.GET, url, listener, errorListener);

    }

我们看到,他是调用了自己的另外一个构造方法,然后传了一个get方法

也就是说我们平时默认是get

那么我们找到另一个构造方法

    public StringRequest(int method, String url, Listener<String> listener,

            ErrorListener errorListener) {

        super(method, url, errorListener);

        mListener = listener;

    }

我们看到

首先是调用了父类的构造方法,

method,url,errorListener都传给了父类

然后listener给了自己

给了mListener成员变量

 

我们先进父类Request里面看一看

    public Request(int method, String url, Response.ErrorListener listener) {

        mMethod = method;

        mUrl = url;

        mErrorListener = listener;

        setRetryPolicy(new DefaultRetryPolicy());

 

        mDefaultTrafficStatsTag = TextUtils.isEmpty(url) ? 0: Uri.parse(url).getHost().hashCode();

    }

我们看到

method,url,errorListener都给了自己的成员变量

然后调用了setRetryPolicy,重试的方案,new了一个默认的重试方案

 

接着是创建RequestQueue

Volley调用newRequestQueue

RequestQueue requestQueue=Volley.newRequestQueue(getContext());

进这个方法看看

    public static RequestQueue newRequestQueue(Context context) {

        return newRequestQueue(context, null);

    }

 

再进一层

    public static RequestQueue newRequestQueue(Context context, HttpStack stack) {

        File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);

 

        String userAgent = "volley/0";

        try {

            String packageName = context.getPackageName();

            PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);

            userAgent = packageName + "/" + info.versionCode;

        } catch (NameNotFoundException e) {

        }

 

        if (stack == null) {

            if (Build.VERSION.SDK_INT >= 9) {

                stack = new HurlStack();

            } else {

                // Prior to Gingerbread, HttpUrlConnection was unreliable.

                // See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html

                stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));

            }

        }

 

        Network network = new BasicNetwork(stack);

 

        RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir), network);

        queue.start();

 

        return queue;

    }

 

这里的代码就有点复杂了

我们慢慢看

我们主要看红色部分

如果stack不为空

那么进入

然后判断的是SDK版本

如果SDK>=9

那么stack=new HurlStack();

这里的HurlStack其实就是HttpUrlConnection

否则

stack=new HttpClientStack(AndroidHttpClient.newInstance(userAgent));

这里的HttpClientStack其实就是HttpClient

 

然后是new了一个BasicNetwork

这里的BasicNetwork可以看做是一个HttpURLConnection或者HttpClient

然后创建了RequestQueue返回出去

 

最后是RequestQueue调用add方法发送请求

 

我们进入add方法看看

 

    public Request add(Request request) {

        // Tag the request as belonging to this queue and add it to the set of current requests.

        request.setRequestQueue(this);

        synchronized (mCurrentRequests) {

            mCurrentRequests.add(request);

        }

 

        // Process requests in the order they are added.

        request.setSequence(getSequenceNumber());

        request.addMarker("add-to-queue");

 

        // If the request is uncacheable, skip the cache queue and go straight to the network.

        if (!request.shouldCache()) {

            mNetworkQueue.add(request);

            return request;

        }

 

        // Insert request into stage if there's already a request with the same cache key in flight.

        synchronized (mWaitingRequests) {

            String cacheKey = request.getCacheKey();

            if (mWaitingRequests.containsKey(cacheKey)) {

                // There is already a request in flight. Queue up.

                Queue<Request> stagedRequests = mWaitingRequests.get(cacheKey);

                if (stagedRequests == null) {

                    stagedRequests = new LinkedList<Request>();

                }

                stagedRequests.add(request);

                mWaitingRequests.put(cacheKey, stagedRequests);

                if (VolleyLog.DEBUG) {

                    VolleyLog.v("Request for cacheKey=%s is in flight, putting on hold.", cacheKey);

                }

            } else {

                // Insert 'null' queue for this cacheKey, indicating there is now a request in

                // flight.

                mWaitingRequests.put(cacheKey, null);

                mCacheQueue.add(request);

            }

            return request;

        }

 

我们还是重点看红色部分

 

先是mCurrentRequests添加了request

        synchronized (mCurrentRequests) {

            mCurrentRequests.add(request);

        }

这个mCurrentRequests是干嘛的呢

mCurrentRequests是用来存储所有未完成的请求

所以我们所有请求发起都要经过这个Requests

 

最后mWaitingRequests调用put方法

      mWaitingRequests.put(cacheKey, null);

         mCacheQueue.add(request);

这里的mCacheQueue是存放所有需要先取缓存的请求

mWaitingRequests是存放同一个url后续发起的请求

 

还有mNetworkQueue

    if (!request.shouldCache()) {

            mNetworkQueue.add(request);

            return request;

        }

这是不取缓存,直接请求网络的请求

 

 

 

 

 

 

 

 

 

0 0