Android中的网络编程

好几天没写了,最近迷上了Material Design下次会写一章,好好说说。不过在学的过程中也发现自己的基础还是不行,沉下心来好好把剩下的基础部分复习一下还是很有必要的。
今天写一个大话题。

网络编程

网络部分在之后工作中绝对是必不可少的,之前的JavaWeb部分也提到过servlet,http有get和post两种请求模式。
1. get请求是在发送http请求时直接将携带的信息在链接中携带,这样弊端很明显,首先他携带的信息量并不能太多,而且这样的请求方式并不安全,但他确实较为方便。
2. post请求拥有请求体,使用请求体携带数据,安全,携带量大,但同时使用上了请求体也显得麻烦了一丁点儿。
3. android同样使用的是get与post请求。

预备知识

  1. 在使用设备网络时首先需要拥有这样一个权限:

     <uses-permission android:name="android.permission.INTERNET"/>
  2. android4.0版本之后,google强制要求访问网络的操作不允许在主线程中执行,只能创建子线程执行,访问网络属于一项耗时操作,如果放在主线程运行,会影响界面运行时的流畅性。
    这样的耗时操作还有:

    • 文件下载。
    • 音频格式转换操作。
    • 文件操作。
    • 比较大的数据的初始化操作。
    • sleep函数等 。
      之后会介绍一些关于异步任务的知识,使用AsyncTask创建异步任务,处理耗时操作,并与主线程通信。
  3. 在主线程中进行一些耗时操作的时候,会报出ANR异常:Application Not Response,这是由于耗时操作阻塞了主线程,用户点击时主线程无法进行相对应的响应呢,然后报出ANR异常。
  4. Activity的onCreate方法以及点击事件都是运行在主线程中,主线程实时体现出来的就是UI界面,所以主线程也叫UI线程。而同样的子线程是不能执行修改UI的操作的,除非使用looper。
  5. 在子线程执行了耗时操作之后,得出了结果,但是这也需要响应在UI上时,我们会使用到handler,handler是用于线程间通信的,使用在子线程中使用handler创建message对象,鞋带上子线程中的数据类型与数据内容发送至主线程的handler,之后用于显示UI。

1. HttpURLConnection

这是最基础的,android最基本的http网络访问的编程方式

  • 接下来直接在代码中进行介绍了
new Thread(new Runnable() {
            @Override
            public void run() {
            String path = "http://10.0.3.2:8080/Test/Login";
                try {
                    URL url = new URL(PATH + "?username=" + username + "&password=" + password);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setConnectTimeout(TIME_OUT);
                    connection.connect();
                    int responseCode = connection.getResponseCode();
                    if (responseCode == 200) {
                        InputStream is = connection.getInputStream();
                        //流转字符串工具,过程省略
                        String result = StreamUtils.is2Str(is);
                        Message msg = new Message();
                        msg.what = 1;
                        msg.obj = result;
                        handler.sendMessage(msg);
                    } else {
                        handler.obtainMessage(2, responseCode).sendToTarget();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    handler.obtainMessage(3, e).sendToTarget();
                }
            }
        }).start();
    }
  • 接下来来简单分析一下流程:

    1. 创建子线程,覆写run方法。
    2. 创建URL对象,即为GET请求的具体的URL,由初始的链接与数据组成,这里模拟一个登陆,get请求在链接中直接携带账号与密码进行请求。
    3. 使用url对象打开链接,创建HttpURLConnection对象
    4. 设置请求时限,超时则直接报错。
    5. 连接
    6. 使用HttpURLConnection对象的getResponse方法获取响应码
    7. 在这之后,由连接情况进行分析响应码,200即为访问成功,之后就是获取连接数据了。
    8. 使用HttpURLConnection对象的getInputStream获取流对象,而这之后省略的部分是读取流,然后存储了一个字符串对象,而这个字符串即是最后的结果。
    9. 在使用Message对象之前,我们在主线程已经创建了一个handler对象,并覆写handleMessage方法:

    private Handler handler = new Handler() {
            @Override
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
                case 1:
                    Toast.makeText(MainActivity.this, "请求成功:" + msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 2:
                    Toast.makeText(MainActivity.this, "状态码不正确:" + msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                case 3:
                    Toast.makeText(MainActivity.this, "异常:" + msg.obj, Toast.LENGTH_SHORT).show();
                    break;
                default:
                    break;
                }
            };
        };

    使用Handler分别处理三中message对象,而分别信息类型的方式是依据子线程中message绑定的what。三种不同的数据类型,显示三种不同的结果。

  • 在子线程中先创建Message对象,为msg.what赋值,用于在handler中分辨数据类型,之后使用msg.obj创建这个object类型的对象,将数据结果result赋值,传递到handler中。

    HttpURLConnection具体流程基本如上,而post方法需要改变的只是定义HttpURLConnection对象的setRequestMethod(“post”);以及在创建url、对象时,地址不需要再添加数据。之后使用其getOutputStream方法获取输出流,将数据写入。之后的流程与get相同。


2. HttpClient

  1. HttpClient是apache开源组织研发的api,它是一个简单的HTTP客户端,能够发送和接收http请求和响应。HttpClient设计思想是模拟浏览器的操作来实现网络访问。
  2. Android成功了集成了HttpClient,所以在Android项目中可以直接使用HttpClient来想Web站点提交请求以及接受响应。
  3. HttpClient是一个interface类型,HttpClient封装了对象需要执行的Http请求,身份验证,连接管理和一些其他特性。它提供了三个实现类,而也专门为Android应用提供了一个实现类AndroidHttpClient,相对于DefaultHttpClient做了一些改进:
    • 关掉了过期检查,自连接可以打破所有的时间限制。
    • 可以设置ConnectionTimeOut(连接超时)和SoTimeout(读取时间超时)。
    • 关掉了重定向。
    • 如果服务器支持,使用gzip压缩方式用于在服务器和客户端传递的数据。
    • 默认情况下不保留Cookie
    • 使用一个Session缓冲用于SSL Sockets。

这些东西只需要了解,以后并不会用了,并且在6.0之后不再支持。

使用步骤:

在使用之前需要创建子线程。

  1. 定义一个客户端对象:即获得一个HttpClient对象,等同于打开浏览器。
  2. 定义请求方法GET/POST,等同于在浏览器输入网址。
  3. 设置请求的参数/其牛头信息/连接超时时间/读取数据超时时间等。
  4. execute方法执行请求,等同于敲回车,此方法会返回一个HttpResponse对象。
  5. 获取了HttpResponse对象之后,获取其状态码,getStatusLine().getStatusCode()。
  6. 如果状态码为200,获取服务器返回的数据流,getEntity().getContent()。
  7. 结束操作后断开连接,getConnectionManager().shutdown()。

1.GET请求方式

public void HttpClientTest(){
    new Thread(){
        @Override
        public void run() {
            super.run();
            String path = PATH+"?username="+username+"&pwd="+pwd;
            //1.获取一个客户端对象
            HttpClient client = new AndroidHttpClient();
            //2.定义请求方式,并传递请求地址
            HttpGet httpGet = new HttpGet(path);
            //3.获取参数对象
            HttpParams params = httpGet.getParams();
            //4.设置链接超时时间
            HttpConnectionParams.setConnectionTimeout(params,
                    5000);
            //5.设置读取数据超时时间
            HttpConnectionParams.setSoTimeout(params, 5000);
            //6.开始发送请求,同时返回HttpResponse 对象,该句代码属于耗
            时操作
            HttpResponse httpResponse = client.execute(httpGet);
            //7.获取状态码
            int code =
                    httpResponse.getStatusLine().getStatusCode();
            if (code==200) {
            //8.获取返回数据流对象
                InputStream in =
                        httpResponse.getEntity().getContent();
                ByteArrayOutputStream bos = new
                        ByteArrayOutputStream();
                byte[] buff = new byte[1024];
                int len;
                while((len=in.read(buff))!=-1){
                    bos.write(buff, 0, len);
                }
                in.close();
                result = bos.toString();
                bos.close();
            }else {
                result = "请求失败!";
            }
            //9.关闭链接
            client.getConnectionManager().shutdown();
        }
    }

2.POST请求方式

//1.创建客户端对象
HttpClient client = new AndroidHttpClient();
//2.创建一个POST 请求对象
HttpPost httpPost = new HttpPost(PATH);
//3.获取请求对象的参数
HttpParams httpParams = httpPost.getParams();
//4.设置链接超时时间
HttpConnectionParams.setConnectionTimeout(httpParams, 5000);
//5.设置读取数据流超时时间
HttpConnectionParams.setSoTimeout(httpParams, 5000);
//6.设置请求参数集合,将请求参数都添加到该集合
List<BasicNameValuePair> parameters = new
ArrayList<BasicNameValuePair>();
//7.将用户信息添加到集合中
parameters.add(new BasicNameValuePair("username", username));
parameters.add(new BasicNameValuePair("pwd", pwd));
//8.创建一个请求体对象
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters );
//9.给httpPost 对象设置请求体
httpPost.setEntity(entity);
HttpResponse httpResponse = client.execute(httpPost);
//10.获取状态码
int code = httpResponse.getStatusLine().getStatusCode();
if (code==200) {
  //11.获取返回数据流对象
  InputStream in = httpResponse.getEntity().getContent();
  ByteArrayOutputStream bos = new ByteArrayOutputStream();
  byte[] buff = new byte[1024];
  int len = -1;
  while((len=in.read(buff))!=-1){
    bos.write(buff, 0, len);
  }
  in.close();
  result = bos.toString();
  bos.close();
}else {
  result = "请求失败!";
}
//12.关闭链接
client.getConnectionManager().shutdown();

3.AsyncHttpClient

  1. AsyncHttpClient是一个Android的异步Http函数库,属于开源框架,##它无需开启子线程##,因为调用其方法时传递的接口参数中的方法就是执行在主线程中的。
  2. github地址:https://github.com/loopj/android-async-http,使用前仔细阅读README,将依赖添加至gradle:compile
 com.loopj.android:android-async-http:1.4.9

1.GET请求

//创建一个AsyncHttpClient 对象
AsyncHttpClient client = new AsyncHttpClient();
//调用get 方法,发送get 方式的请求
client.get(PATH, new AsyncHttpResponseHandler() {
    /**
    * 处理成功的结果
    * statusCode 状态码
    * headers 响应头消息
    * responseBody 相应的主体内容
    */
    @Override
    public void onSuccess(int statusCode, Header[] headers,byte[] responseBody) {
        String result = new String(responseBody);
        Toast.makeText(MainActivity.this, "请求结果:"+result,1).show();
    }
    /**
    * 处理失败的结果
    * statusCode 状态码
    * headers 响应头消息
    * responseBody 相应的主体内容
    */
    @Override
    public void onFailure(int statusCode, Header[] headers,byte[] responseBody, Throwable throwable) {
        Toast.makeText(MainActivity.this, "请求网络失败!",0).show();
    }
});

2.POST方式

基本逻辑与GET方式相同,GET方式将请求参数凭借在URL后面传输给服务器,POST方式需要使用RequestParams对象封装请求参数给post。

AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put("username", "heima");
params.put("pwd", "12346");
client.post(PATH, params,new AsyncHttpResponseHandler() {
    //相同代码省略
});

这部分属于过时的方法,但是需要了解他的思想

4.okhttp

这部分稍微查了一下,就看见张大神的博客了,直接贴出来吧:

Android OkHttp完全解析 是时候来了解OkHttp了
【张鸿洋的博客】

不仅如此,在他的github上也对okhttp的各项功能都进行了进一步的封装:

hongyangAndroid/okhttp-utils

这在今后进行网络的开发中非常常用,6.0中也删除了httpClient相关的API。而okhttp便是最常用的网络请求框架了。

5.volley

由于volley底层使用HttpClient,无法兼容6.0版本,使用时可以将编译版本改为22,但不建议使用。
Android Volley完全解析(一),初识Volley的基本用法

郭霖大神的专栏

6.Retrofit

Android中的网络编程2——Retrofit

未完待续。。。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值