Android开发的网络技术,及一些框架的分析

 

0.Http协议

是什么?

计算机网络通信应用层协议

如何用?

(1)客户端->服务端

         请求URL:访问的网络地址,也可在get方式下用键值对,发送一些信息,长度不超过2048个字符(2kB)

         requestHeader:用于设定请求的元数据如,Accept-Encoding告诉服务器客户端支持的压缩格式,User-Agent告诉服务器这个请求来自什么浏览器

         requestBody(get模式没有;post有):可以用放置任何字节流。

三部分构成

(2)服务端->客户端

          responseHeader:响应头,用于返回响应的元数据,如Content-Encoding告诉客户端服务器使用了什么压缩格式,Content-Type:告诉返回的的是什么格式;Set-Cookie:可以设置多条Cookie信息给客户端。

           ResponseBody:返回服务器的响应数据

 

1.HttpURLConnection

是什么?

一个URLConnnection用于支持Http协议;Google开发的用于支持Http的客户端类。

如何用?

参考官方文档:https://developer.android.com/reference/java/net/HttpURLConnection.html

(1)获取一个新的HttpURLConnection通过调用URL.openConnection()并且转化结果为HttpURLConnection

(2)准备请求。基本的请求属性是他的URI,请求头可能包括元数据如,证书,偏好的内容类型,会话Cookies.

(3)是否上传一个请求体是可选的。实例必须被配置使用setDoOutput(true),如果包含了一个请求体。

传输数据通过写入数据流(由getOutputStream()所返回的数据流)。

(4)读取响应。响应头典型的包括元数据,如响应体的内容类型和长度,修改日期和会话Cookies。

响应体可以从数据流(由getInputStream()返回)中读取。如果响应没有响应体,这个方法将返回一个空的数据流

(5)断开连接。一旦响应体被读取,HttpURLConnection应该被关闭,通过调用disconnect().断开连接释放了有连接所

占有的资源。因此他可能被关闭或者被拒绝。

例子:

(1)获取http://www.android.com的页面

URL  url=new URL("http://www.android.com");
HttpURLConnection urlConnection=(HttpURLConnection)url.openConnecton();
try{
 InputStream in=new BufferedInputStream(urlConnection.getInputStream());
 readStream(in);
}finally{
  urlConnection.disconnected();
}

(2)发送内容(Posting Content)

上传数据到服务器,社招连接为输出,使用setDoOutput(true)

为了更好的性能做好设置setFixedLengthStreamingMode()当请求体的长度

已知,未知时设置setChunkedStreamingMode(int),否则HttpURLConnection将被

强制缓存所有的请求体在内存中于传输之前,可能会浪费甚至耗尽堆内存和增加延时。

进行上传:

HttpURLConnection urlConnection=(HttpURLConnection)url.openConnection();

try{

     urlConnection .setDoOutput(true);

     urlConnection.setChunkedStreamingMode(0);

 

    OutputStream out = new BufferedOutputStream(urlConnection.getOutputStream());

    writeStream(out);

 

    InputStream in = new BufferedInputStream(urlConnection.getInputStream());

    readStream(in);

}finally{

    urlConnection.disconnect();

}

更加详细的用法可参考:http://blog.csdn.net/iispring/article/details/51474529

2.Volley

 

是什么?

官网:https://developer.android.com/training/volley/index.html

Github:https://github.com/google/volley

是Google提供的Http开源库,用于Android应用的网络请求。

Volley提供的好处:

(1)网络请求的自动调度

(2)多并发的网络连接

(3)具有标准Http缓存一致性的透明磁盘和内存响应缓存

(4)支持请求优先级

(5)取消请求api。可以取消单个请求,也可以设置一块或一个范围的请求取消

(6)易于定制化,例如重试和后退

(7)强序列化这使得容易正确的填充UI,使用由网络异步获得的数据

(8)消沉bug和追踪工具。

 

如何用?

适用于:

(1)Volley擅长于PRC类型的操作以填充UI,例如取得一页搜索结果作为结构化的数据。

不适合于:

(2)Volley不适合于大规模下载或者数据流操作,因为Volley在解析期间将所有的返回结果存储于内存中。

对于大规模下载可以使用DownloadManager。

使用教程:

可参考:http://blog.csdn.net/guolin_blog/article/details/17482095

(1)基本用法:

      (a)发送一个简单的请求

                 (x1)添加网络权限

                  (x2)使用 newRequestQueue

 

final TextView mTextView = (TextView) findViewById(R.id.text);
...

// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
 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<String>(){

@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);

           

 

          (x3)发送一个请求

      为了发送一个请求,你必须先构建和添加一个进入RequestQueue如上所示,一旦你添加请求,它就

通过管道移动,得到服务,并对其原始响应进行解析和传送。

    请求的生命周期演示:

 

当你调用add(),Volley运行一个缓存处理线程,和一个网络分发线程池。

当你添加一个请求进入队列,他被缓存线程,接受和鉴别分类;如果请求在缓存中存在

,缓存结果在缓存线程中解析并被传送到住线程。

如果在缓存中没有命中,请求被加入到网络队列。第一个可用的网络线程将请求从队列中取出。

执行Http传输,解析响应结果在工作线程,写入缓存,并传送解析后的响应返回到住线程。

   (x4)结束一个请求

       参考: https://developer.android.com/training/volley/simple.html#simple

       的最后一部分;

(b)设置请求队列

      参考https://developer.android.com/training/volley/requestqueue.html#singleton

       推荐创建一个请求队列成为单例,让请求队列在你app的生命周期里一直存在。

public class MySingleton {
	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 <T> void addToRequestQueue(Request<T> req){
		getRequestQueue().add(req);
	}
	
	public ImageLoader getImageLoader(){
		return mImageLoader;
	}

}

(c)做一个标准的请求

参考:https://developer.android.com/training/volley/request.html

 

TextView mTxtDisplay;
ImageView mImageView;
mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
String url = "http://my-json-feed";

JsonObjectRequest jsObjRequest = new JsonObjectRequest
        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        mTxtDisplay.setText("Response: " + response.toString());
    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        // TODO Auto-generated method stub

    }
});

// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest); mTxtDisplay;
ImageView mImageView;
mTxtDisplay = (TextView) findViewById(R.id.txtDisplay);
String url = "http://my-json-feed";

JsonObjectRequest jsObjRequest = new JsonObjectRequest
        (Request.Method.GET, url, null, new Response.Listener<JSONObject>() {

    @Override
    public void onResponse(JSONObject response) {
        mTxtDisplay.setText("Response: " + response.toString());
    }
}, new Response.ErrorListener() {

    @Override
    public void onErrorResponse(VolleyError error) {
        // TODO Auto-generated method stub

    }
});

// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(jsObjRequest);

(d)实现一个自定义的请求

参考:

参考链接:https://developer.android.com/training/volley/request-custom.html

(e)上传数据(post方式)

StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener); 

由于StringRequest中没有提供设置PoSt参数的方法。

但是当发送Post请求时候,Volley会尝试调用StringRequest的父类-Request中的getParams()方法来获取Post参数,

因此解决方法为新建StringRequest实例时候,在StringReques的匿名类中重新getParams()方法,在这里设置Post参数

 

  1. StringRequest stringRequest = new StringRequest(Method.POST, url,  listener, errorListener) {  
  2.     @Override  
  3.     protected Map<String, String> getParams() throws AuthFailureError {  
  4.         Map<String, String> map = new HashMap<String, String>();  
  5.         map.put("params1""value1");  
  6.         map.put("params2""value2");  
  7.         return map;  
  8.     }  
  9. };  


原理分析:

可参考:

(1)Android Volley完全解析(四),带你从源码的角度理解Volley

http://blog.csdn.net/guolin_blog/article/details/17656437

(2)https://github.com/google/volley

3.ImageLoader

(Universal Image Loader)(UIL)

附注:Android四大图片缓存(Imageloader,Picasso,Glide,Fresco)原理、特性对比

http://www.cnblogs.com/linghu-java/p/5741358.html

是什么?

一个开源的Android图片加载库:

Github地址:https://github.com/nostra13/Android-Universal-Image-Loader

致力于提供强大的灵活的和高度可定制化的工具用于图片的加载,缓存和展示。他提供了大量的

可配置化选项,和一个很好的控制在图片加载和缓存过程中。

特征:

(1)多线程图片下载(异步或同步)

(2)广泛的自定义设置(线程池,下载器,解码器,内存和硬盘缓存,

展示图片选项等等)

(3)许多定制的选项对于每一个展示图片调用(短的图像,缓存选择,解码选择,Bitmap 处理和展示等等)

(4)图片缓存与内存 和/或 硬盘(device's file system or SD card)

  (5)监听加载过程(包括下载过程)

如何用?

参考:https://github.com/nostra13/Android-Universal-Image-Loader

 

// Load image, decode it to Bitmap and display Bitmap in ImageView (or any other view 
//	which implements ImageAware interface)
imageLoader.displayImage(imageUri, imageView, options, new ImageLoadingListener() {
	@Override
	public void onLoadingStarted(String imageUri, View view) {
		...
	}
	@Override
	public void onLoadingFailed(String imageUri, View view, FailReason failReason) {
		...
	}
	@Override
	public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
		...
	}
	@Override
	public void onLoadingCancelled(String imageUri, View view) {
		...
	}
}, new ImageLoadingProgressListener() {
	@Override
	public void onProgressUpdate(String imageUri, View view, int current, int total) {
		...
	}
});

 

 

 

原理分析:

Load & Display Task Flow

Task Flow

参考:http://blog.csdn.net/ly969434341/article/details/51720852

 

 

4.OkHttp

 

是什么?

参考:https://square.github.io/okhttp/

OKHttp是一个Http客户端

特性:

(1)Http/2支持所有的请求到同一个主机去共用一个套接字

(2)连接池减少请求延时

(3)透明的GZIP压缩下载的大小(透明压缩)--------亮点

(4)缓存响应结果避免网络重复请求

如何用?

参考:https://square.github.io/okhttp/3.x/okhttp/

可参考:https://www.jianshu.com/p/ca8a982a116b

Get A URL

This program downloads a URL and print its contents as a string 

package okhttp3.guide;

import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class GetExample {
  OkHttpClient client = new OkHttpClient();

  String run(String url) throws IOException {
    Request request = new Request.Builder()
        .url(url)
        .build();

    try (Response response = client.newCall(request).execute()) {
      return response.body().string();
    }
  }

  public static void main(String[] args) throws IOException {
    GetExample example = new GetExample();
    String response = example.run("https://raw.github.com/square/okhttp/master/README.md");
    System.out.println(response);
  }
}

Post To A Server

This program posts data to a service.

 

package okhttp3.guide;

import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

public class PostExample {
  public static final MediaType JSON
      = MediaType.parse("application/json; charset=utf-8");

  OkHttpClient client = new OkHttpClient();

  String post(String url, String json) throws IOException {
    RequestBody body = RequestBody.create(JSON, json);
    Request request = new Request.Builder()
        .url(url)
        .post(body)
        .build();
    try (Response response = client.newCall(request).execute()) {
      return response.body().string();
    }
  }

  String bowlingJson(String player1, String player2) {
    return "{'winCondition':'HIGH_SCORE',"
        + "'name':'Bowling',"
        + "'round':4,"
        + "'lastSaved':1367702411696,"
        + "'dateStarted':1367702378785,"
        + "'players':["
        + "{'name':'" + player1 + "','history':[10,8,6,7,8],'color':-13388315,'total':39},"
        + "{'name':'" + player2 + "','history':[6,10,5,10,10],'color':-48060,'total':41}"
        + "]}";
  }

  public static void main(String[] args) throws IOException {
    PostExample example = new PostExample();
    String json = example.bowlingJson("Jesse", "Jake");
    String response = example.post("http://www.roundsapp.com/post", json);
    System.out.println(response);
  }
}

 

原理分析:

 

参考:https://github.com/square/okhttp

参考:https://blog.piasy.com/2016/07/11/Understand-OkHttp/

https://blog.piasy.com/2016/07/11/Understand-OkHttp/index.html

该博主文章非常不错值得关注学习。

在将request如何变成response这就事情上使用了一连串的intercepter,每个Interceptor

都可能完成这件事,所以我们循着链条,让每个Interceptor自行决定能否完成任务已经怎么完成任务

(自力更生或者交给下一个Interceptor)。这样一来,完成网络请求这件事就彻底RealCall类剥离了出来。

简化了各自的责任和逻辑。——责任链模式

 

最后的总结分析:

 

轮子的构造使用参考:https://xiaozhuanlan.com/topic/4615238709

 

网络“三板斧”架构回顾

 

对比分析参考:http://blog.csdn.net/carson_ho/article/details/73732076

 

 

完美的安卓 model 层架构:

https://xiaozhuanlan.com/topic/6182975340

可以去参考这篇博客:走心的中级安卓工程师跳槽经验分享https://xiaozhuanlan.com/topic/0625137489

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要成为一名高级 Android 开发技术员,需要具备以下技能和经验: 1. 扎实的 Java 编程基础:Android 应用程序开发基于 Java 编程语言,因此需要熟悉 Java 语言的基础知识和高级特性。 2. Android 系统架构和组件:需要了解 Android 系统的架构和各种组件,包括 Activity、Service、BroadcastReceiver、ContentProvider 等,以及它们之间的关系和交互方式。 3. Android 开发框架和工具:需要熟悉 Android 开发框架和相关工具,如 Android Studio、Gradle、Android SDK、Android NDK 等。 4. 用户界面设计和开发:需要熟悉 Android 应用程序的用户界面设计和开发,包括布局、控件、样式、主题等。 5. 数据存储和管理:需要了解 Android 中的数据存储和管理方式,包括 SharedPreferences、SQLite 数据库、ContentProvider 等。 6. 网络编程和数据交互:需要了解 Android 中的网络编程和数据交互方式,包括 HTTP、WebSocket、TCP/IP 等协议,以及 JSON、XML 等数据格式。 7. 性能优化和调试:需要熟悉 Android 应用程序的性能优化和调试技术,包括内存管理、性能分析、调试工具等。 8. 版本控制和团队协作:需要熟悉版本控制工具和团队协作流程,如 Git、SVN 等。 9. 具备良好的沟通和协作能力,能够与其他开发人员、产品经理、设计师等进行有效的沟通和协作。 10. 持续学习和自我提升的能力,能够关注最新的 Android 开发技术和趋势,并不断学习和实践。 以上是成为一名高级 Android 开发技术员所需的技能和经验,需要不断学习和实践,才能不断提升自己的技能水平。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值