Android 解读Volley

之前有学过异步加载, 但由于是新到的一家公司上班,   要自己手动搭建一个新的框架, 很蛋疼,  朋友们推荐使用Volley 于是 今天就测试爽了下, 表示还行..


不说废话, 直接上代码..


package com.example.testvolley;

import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.res.Resources.Theme;
import android.os.Bundle;

import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonObjectRequest;
import com.android.volley.toolbox.Volley;

public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		getJson();
	}

	private void getJson() {
		RequestQueue queue = Volley.newRequestQueue(this);
		String jsonURL = "http://192.168.1.118:8000/Learning3/app/LoginAuth.action?username=admin&userpwd=123";
		final ProgressDialog progressDialog = ProgressDialog.show(this,
				"请稍后...", "正在加载...");
		try {
			Thread.sleep(2000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET,
				jsonURL, null, new Response.Listener<JSONObject>() { //返回来有数据的监听
					// 获取到的JSON的数据
					@Override
					public void onResponse(JSONObject json) {
						if(progressDialog.isShowing()){
							progressDialog.dismiss();
						}
						String josnstr = json.toString();
					}

				}, new Response.ErrorListener() {  //返回的没有数据报错的监听
					@Override
					public void onErrorResponse(VolleyError error) {
						System.out.println("error:" + error);
					}
				});
		queue.add(request); //这步是在队列里执行request请求..
	}

}


效果还行.. 自己打印出Log看下就知道了...


然后分析下源码吧..  我们都知道 他是个异步线程加载的过程, 那么,, 这个异步的代码到底到哪里了?

上面的DEMO里的方法.. 是用add..  于是LZ就杀到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;
        }
    }

这么长一段代码.. LZ 就这样蛋疼的看了一个下午的源码.. 把工作都丢一边了...

而且 add代码里面写了这么多.. 只是做了一个线程的同步与异步的控制, 并没有start()方法..

好吧.. 既然add方法没有, 那我们从第一个方法开始看吧

 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;
    }

原来一开始 他们就已经创建了一个等待请求的请求队列了!!!

根据包名+/加版本号..  然后开启了一个新的Http客户端的栈的请求队列

到这里 我们大概可以很肤浅的知道 代码是在一开始就已经创建好一个栈等着结果进入..


然后在往下看..

Network network = new BasicNetwork(stack);

我们stack传进来的参数为空

    public BasicNetwork(HttpStack httpStack) {
        // If a pool isn't passed in, then build a small default pool that will give us a lot of
        // benefit and not use too much memory.
        this(httpStack, new ByteArrayPool(DEFAULT_POOL_SIZE));
    }

由这步我们可以得知, 可能这里是要存放一个缓存池的一个数量

返回 再往下执行看


    public RequestQueue(Cache cache, Network network, int threadPoolSize) {
        this(cache, network, threadPoolSize,
                new ExecutorDelivery(new Handler(Looper.getMainLooper())));
    }

    public ExecutorDelivery(final Handler handler) {
        // Make an Executor that just wraps the handler.
        mResponsePoster = new Executor() {
            @Override
            public void execute(Runnable command) {
                handler.post(command);
            }
        };
    }

从这步我们可以得知, 要把前面NetWork的数据丢到线程里面了...


往下看 执行..


    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();
        }
    }

public class CacheDispatcher extends Thread


闹了大半圈 终于明白了...


整理下


首先Volley会创建一个等待的请求队列, 然后会开启一个Handler, 然后Handler 里所做的操作就是 将当前线程post进去 无限等待数据...(阻塞, 不懂的自己看Handler底层),


最后如果有请求进来, 就会去创建线程, 最后开启....蛋疼啊!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值