zoukankan      html  css  js  c++  java
  • Android训练课程(Android Training)

    使用Volley传输网络数据(Transmitting Network Data Using Volley)

    Volley 是一个 HTTP 库,它使得在Android应用程序中操作网络更容易,是重要的,更多快速的。Volley 属于“开放源代码项目”。.

    Volley 提供了下列好处:

    • 自动化的网络请求调度安排。 
    • 多并发的网络连接。 
    • 对标准HTTP 透明化的硬盘和内存 响应缓存。   cache coherence.
    • 支持请求的优先级。 
    • 支持终止请求的 API. 你可以终止一个单独的请求,或者终止一些范围内的,或者一定请求周期段的请求。 
    • 轻松的定制化,比如重试和回退。 
    • 强顺序,它使得在网络操作时,更容易的正确处理UI和提取数据的异步。 
    • 调试和跟踪工具。.

    Volley擅长的RPC类型(远程过程调用)的操作过去常常应用于填充UI,例如提取一页的搜索结果作为结构化数据。它更容易和其他协议整合,和出色的支持原始字符串,图片和JSON。它为你想要的特性提供内建的支持,Volley 将你从样板的代码中解放处理,使得你将注意力集中在你的业务细节。

    Volley 不适合用于 大文件的下载 或者流操作,因为Volley在解析过程中会持有所有的响应内容在内存中。如果要大文件下载操作,考虑是使用其他替代,比如DownloadManager

    核心的Volley包开放在AOSP工程下的  frameworks/volley,并且包含了主要的请求调度通道,类似于公共应用事业,在Volley "toolbox."是有效的。最简单的添加Volley到你的项目中的方式是 克隆Volley仓库并且做为你项目中的library项目:

    1. 使用Git克隆Volley仓库,在你的命令提示行下输入下面的内容:
      git clone https://android.googlesource.com/platform/frameworks/volley
    2. 导入下载的源代码到你的项目中,并且作为你的library项目 (如果你使用 Eclipse,更多描述请阅读 Managing Projects from Eclipse with ADT,) 或者编译成一个 .jar 文件.

    课程


    发送一个简单请求 (Sending a Simple Request
    学习如何使用Volley的默认行为发送简单请求,和如何去终止一个请求。 
    设置请求队列(Setting Up a RequestQueue
    学习如何设置一个请求队列,和如何使用一个单例模式来创建一个和你的App的生命周期一致的请求队列 .
    构造一个标准请求(Making a Standard Request
    学习如何使用Volley的out-of-the-box请求类型(比如原始字符串,图片,JSON)发送一个请求。 
    实现自定义的请求(Implementing a Custom Request
    学习如何实现自定义请求。 

    发送一个简单请求(Sending a Simple Request)

    在一个较高的水平,你使用Volley创建一个请求队列并且传入一个 请求对象 作为参数。请求队列负责管理工作线程来 启动网络操作,读取和写入到缓存,和解析响应。请求执行解析原始响应,Volley小心的分发解析的响应传送到主线程。 

    这节课描述了如何使用Volley.newRequestQueue 这个便利的方法来发送一个请求。它为你配置了一个请求队列。你可以通过学习下一课,“设置一个请求队列( Setting Up a RequestQueue)”的内容掌握如何配置请求队列。 

    这节课也描述了如何添加一个请求到消息队列,和终止一个请求。 

    添加网络访问权限(Add the INTERNET Permission)

    要使用 Volley, 你必须在你的manifest文件中添加  android.permission.INTERNET 权限. 没有这个,你的app将不能访问网络。 

    使用 newRequestQueue

    Volley 提供了一个便利的方法 Volley.newRequestQueue 配置一个消息队列,使用默认值,和启动队列,例如:

    final TextView mTextView = (TextView) findViewById(R.id.text);
    ...
    
    // Instantiate the RequestQueue.
    RequestQueue queue = Volley.newRequestQueue(this);
    String url ="http://www.google.com";
    
    // Request a string response from the provided URL.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
                new Response.Listener() {
        @Override
        public void onResponse(String response) {
            // Display the first 500 characters of the response string.
            mTextView.setText("Response is: "+ response.substring(0,500));
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {
            mTextView.setText("That didn't work!");
        }
    });
    // Add the request to the RequestQueue.
    queue.add(stringRequest);
    

    Volley 总是传递那些解析后的响应到主线程。运行在主线程的好处是非常便利的使用收到的数据去通知UI控件,就像 你可以在你的响应handler里自由的直接修改UI控件,但是类库提供的语义格外的重要,尤其是关联到取消请求时。 

    阅读 Setting Up a RequestQueue 章节可以获得更多 设置请求队列的内容,它可以用来替代Volley.newRequestQueue便利的方法。 

    发送一个请求(Send a Request)

    要发送一个请求,你可以简单的构造一个请求,并使用add() 方法添加到请求队列,像上面描述的那样.一旦你添加了请求,它被通过管道移动,获得服务,和获得原始响应和传递。

    当你调用了add() 方法,Volley启动一个缓存处理线程和一个网络分发线程池。当你添加请求到队列中,它被缓存线程获拾取和分类: 如果请求可以从缓存中服务,缓存中的原始响应内容被在缓存进程中解析,并且解析后的响应内容被传递到主线程。如果请求无法从缓存中服务,它将被放置在网络队列中。第一个活动的网络线程从队里中拿到它,处理HTTP传输,在工作线程中解析响应的内容,写入响应内容到缓存,并且发送解析后的响应传递到主线程中。

    注意哪些 昂贵的操作,比如阻塞I/O,和解析/解码,都是在工作线程中完成的。你可以在任何线程中添加请求,但是响应总是被传递到主线程中。

    图表 1 插图说明一个请求的生命周期:

     

    图 1. 请求的生命周期.

    中断一个请求(Cancel a Request)

    要中断一个请求, 在你的请求对象上 调用 cancel()方法.一旦被中断后,Volley会确保 你的响应处理器 绝对不被调用。实际意义是你可在你的activity中的onStop()方法中中断你的等待中的请求,而且你不会被迫乱丢你的请求处理器,比如检查getActivity() == null ,onSaveInstanceState() 方法是否已经被调用,或者其他自卫性的样板代码。  

    要获得这样行为的好处,典型情况下你不得不追踪所有 “飞行中的(in-flight)”请求,以使得在合适的时机去终止它。这有一个更简单的方法: 你可以为每一个请求关联一个 标签对象。你可以使用这个标签来提供可被中断请求的范围。比如,你可以使用 Activity对象 标记你所有的请求,并且在 onStop() 时调用  requestQueue.cancelAll(this) 。同样的,你可以 在一个ViewPager选项卡中,使用他们各自的 选项卡对象 标记 它们自己的所有的 缩略图 请求,并在切换时触发终止操作,以确保 新的选项卡对象不会被 其他选项卡的请求 所持有。

    下面是一个使用 字符串值作为标签 的示例: 

    1. 定义你的标签并且添加到你的请求上。 
      public static final String TAG = "MyTag";
      StringRequest stringRequest; // Assume this exists.
      RequestQueue mRequestQueue;  // Assume this exists.
      
      // Set the tag on the request.
      stringRequest.setTag(TAG);
      
      // Add the request to the RequestQueue.
      mRequestQueue.add(stringRequest);
    2. 在你的 activity的 onStop() 方法中, 终止所有标记过这个标签的请求。 
      @Override
      protected void onStop () {
          super.onStop();
          if (mRequestQueue != null) {
              mRequestQueue.cancelAll(TAG);
          }
      }
      

    当调用终止请求时要非常小心。如果你 依赖 你的响应处理器,以变动一个状态或者踢开一些步骤,你需要记得这些。再次强调,在终止后相应处理绝不会被调用。   

    设置一个请求队列(Setting Up a RequestQueue)

    上节课展示了如何使用 Volley.newRequestQueue 这个便利的方法来设置一个请求队列,以获得Volley提供的默认行为的好处。这节课教你通过明确的几个步骤来创建一个请求队列,使得你可以定制它。 

    这节课也描述一个推荐的实践方式,使用单例模式创建一个请求队列,这个请求队列会持续整个App的生命周期。

    设置一个网络和缓存(Set Up a Network and Cache)

    一个请求队列要完成它自己的工作需要两样东西: 一个 network(网络) 对象处理请求的传输,和一个 cache(缓存)对象来处理缓存。在Volley 工具盒 中已经有了里那两个标准的可用的实现: DiskBasedCache提供了一个 “每响应单文件(one-file-per-response)” 的缓存并在内存中建立索引; BasicNetwork对象提供了以 你自己选择的AndroidHttpClient 或 HttpURLConnection 对象 为基础的网络传输。

    BasicNetwork 是Volley的默认 network(网络) 实现。一个 BasicNetwork 对象必须先被  使用HTTP客户端 来初始化后才能连接网络。比较有代表性的是AndroidHttpClient or HttpURLConnection:

    要创建一个可运行在Android全版本的应用,你可用检查Android硬件设备上运行的Android系统的版本号,以做出选择是HTTP 客户端,比如: 

    HttpStack stack;
    ...
    // If the device is running a version >= Gingerbread...
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
        // ...use HttpURLConnection for stack.
    } else {
        // ...use AndroidHttpClient for stack.
    }
    Network network = new BasicNetwork(stack);
    

    这个代码片段展示了设置请求队列的步骤: 

    RequestQueue mRequestQueue;
    
    // Instantiate the cache
    Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
    
    // Set up the network to use HttpURLConnection as the HTTP client.
    Network network = new BasicNetwork(new HurlStack());
    
    // Instantiate the RequestQueue with the cache and network.
    mRequestQueue = new RequestQueue(cache, network);
    
    // Start the queue
    mRequestQueue.start();
    
    String url ="http://www.myurl.com";
    
    // Formulate the request and handle the response.
    StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
            new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            // Do something with the response
        }
    },
        new Response.ErrorListener() {
            @Override
            public void onErrorResponse(VolleyError error) {
                // Handle error
        }
    });
    
    // Add the request to the RequestQueue.
    mRequestQueue.add(stringRequest);
    ...
    

    如果你仅仅需要构建单次的请求,并且不想离开线程池的范围,你可用创建在任何地方创建请求队列,和在收到响应或者错误后调用stop()方法,使用Volley.newRequestQueue()的方法可参阅 Sending a Simple Request。但是更多一般的使用情形是 使用单例模式创建请求队列并且让它和你的应用的生命周期一致,更多描述在下一章节。

    使用单例模式(Use a Singleton Pattern)

    如果你的应用需要经常访问网络,那么配置一个单例模式的请求队列并保持在app的整个生命周期的方式是非常有效率的。你可以有多种方式这样实现。推荐的方式是实现一个单例类来封装请求队列和其他的Volley功能方法/函数。其他的实现方式比如实现 Applicaton的子类并在Application.onCreate()方法中配置请求队列,这样的方式现在是被劝阻的;一个静态的单例能够以模块化的方式提供同样的功能。

    一个关键概念是请求队列必须使用Application的context对象来初始化,而不时 Activity的context.这样确保请求队列会持续在整个app的生命周期,而在activity的context的实现会在activity被重新创建时被创建多次(比如,当用户旋转了屏幕就会重新创建activity)。

    下面是一个实现了单例模式的类的示例,它提供了请求队列和图片下载器(ImageLoader)的功能: 

    private static MySingleton mInstance;
        private RequestQueue mRequestQueue;
        private ImageLoader mImageLoader;
        private static Context mCtx;
    
        private MySingleton(Context context) {
            mCtx = context;
            mRequestQueue = getRequestQueue();
    
            mImageLoader = new ImageLoader(mRequestQueue,
                    new ImageLoader.ImageCache() {
                private final LruCache<String, Bitmap>
                        cache = new LruCache<String, Bitmap>(20);
    
                @Override
                public Bitmap getBitmap(String url) {
                    return cache.get(url);
                }
    
                @Override
                public void putBitmap(String url, Bitmap bitmap) {
                    cache.put(url, bitmap);
                }
            });
        }
    
        public static synchronized MySingleton getInstance(Context context) {
            if (mInstance == null) {
                mInstance = new MySingleton(context);
            }
            return mInstance;
        }
    
        public RequestQueue getRequestQueue() {
            if (mRequestQueue == null) {
                // getApplicationContext() is key, it keeps you from leaking the
                // Activity or BroadcastReceiver if someone passes one in.
                mRequestQueue = Volley.newRequestQueue(mCtx.getApplicationContext());
            }
            return mRequestQueue;
        }
    
        public <T> void addToRequestQueue(Request<T> req) {
            getRequestQueue().add(req);
        }
    
        public ImageLoader getImageLoader() {
            return mImageLoader;
        }
    }

    下面是使用单例类处理请求队列操作的示例: 

    // Get a RequestQueue
    RequestQueue queue = MySingleton.getInstance(this.getApplicationContext()).
        getRequestQueue();
    ...
    
    // Add a request (in this example, called stringRequest) to your RequestQueue.
    MySingleton.getInstance(this).addToRequestQueue(stringRequest);
    

    (全文完结)

  • 相关阅读:
    gitlab10+版本删除项目工程
    Ubuntu16.04上通过anaconda3离线安装Tensorflow2.0详细教程
    android中根据smartRefeshLayout自定义上下拉刷新效果
    android高德地图根据经纬度添加标注(Marker)
    android设置状态栏颜色
    android复制内容到剪贴板
    android拨打电话的两种方式
    java集合转String数组
    解决jenkins部署TomcatManagerException问题
    SpringCloud 微服务消费者之间相互调用的方式
  • 原文地址:https://www.cnblogs.com/vir56k/p/4707351.html
Copyright © 2011-2022 走看看