Android 网络连接基本方式

本文主要探讨Android应用程序中进行网络连接的基本方法,包括使用HttpURLConnection和HttpClient。详细解析了HTTP请求的构建过程,以及如何处理响应数据。同时,还讨论了Android网络操作的异步处理,确保UI线程不被阻塞,提升用户体验。
就目前我所了解,可以分为两大类,Socket方式 和 Http方式。
其中,Socket方式所需使用的类,及Http方式中HttpUrlConnection类,都是JDK中的java类,跟传统java网络编程无差异。
1.Socket是针对传输层协议的,据说可以支持多种协议,不过java中貌似主要用来进行基于TCP/IP协议的网络编程。
它只是在两个网络进程间建立起稳定点到点连接,可以互相发送字节流,至于这些字节流双方按照什么协议解析,完全看程序开发者自己怎么设计。
2.Http方式,故名思议,是按照应用层HTTP协议规范进行网络连接。至于具体底层如何按照HTTP协议来编写程序实现网络连接,作为应用层开发者并不需要很清楚,因为已经有很多现成的程序包实现了这些功能,并且向我们提供简便易用的java api接口,其中既有JDK提供的HttpUrlConnection方式,也有开源组织Apache提供的HttpClient方式。(还有很多其它第三方方式。任何一个人假如足够牛,又肯花功夫,也可以自己来实现相关功能,并提供自己的java api编程接口。)
注意:这是很早之前写的内容,HttpClient方式在Android5.0只有已经被废弃。现在一般也不会直接去用HttpUrlConnection方式,现在主流的方式一般是OkHttp或者 OkHttp + Retrofit。
以下为使用上述api来编写程序的大致步骤:
一、Socket方式
1.客户端:
try{
    //新建一个Socket,同时会向网络上 【IP地址:端口号】指定的进程发起连接
    //端口号共256*256个,从0开始,其中前1024个为保留端口号,已经公共定义用途,或者留待未来公共定义,剩下的端口号用户可以自己定义
    Socket socket = new Socket( 【IP地址】, 【端口号】);
    ............
    //分别获取输入输出流,至于按照什么协议流程来进行数据输入输出,以及如何解析数据,看编写者自己的需要了
    //往往会利用其它流对象对这两个数据流进一步处理,来优化输入输出。例如数据为字符串时,可以用BufferedReader和PrinterWriter
    InputStream in = socket.getInputStream();
    OutputStream out = socket.getOutputStream();
    ...........
    //完事了,关闭相关的流以及网络连接
    in.close();
    out.close();
    socket.close();

} catch (...){
    ...
}
2.服务端:
try{
    //新建一个ServerSocket对象,监控本机指定端口
    ServerSocket server = new ServerSocket( 【端口号】 );
    ..............
    //阻塞再次,直到有客户端向自己发起请求,然后生成与之连接的对应的Socket对象,作为accept()方法的返回值
    //获取到Socket对象后,剩下的用法,跟上面客户端Socket用法无异
    Socket socket = server.accept();
    ..............
} catch (...){
    ......
}

二、Http方式
1.使用HttpUrlConnection
(JDK中的java.net.HttpURLConnection类)
1.1 Get请求:
try {
    URL url = new URL(urlStr);
    HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
    // 设置请求类型为Get类型
    urlConn.setRequestMethod("GET");
    // 设置连接超时为5秒
    urlConn.setConnectTimeout(5000);
    //进行连接
    urlConn.connect();
    //请求成功时
    if(urlConn.getResponseCode() == HttpURLConnection.HTTP_OK){
        //获取网络结果的读取流
        InputStream in = urlConn.getInputStream();
        //创建结果数据的目标输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //读过程的缓冲区
        byte[] temp = new byte[4096];
        //不断读数据,并写入目标输出流
        int len;
        while((len = in.read(temp)) != -1){
            bos.write(temp, 0, len);
        }
        bos.flush();
        //从目标输出流一次性取出结果数据
        byte[] res = bos.toByteArray();
        in.close();
        bos.close();
        return res;
    }
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}
1.2 Post请求
可以发送Http请求报文数据体,多了一些相关设置。
try {
    URL url = new URL(urlStr);
    HttpURLConnection urlConn = (HttpURLConnection)url.openConnection();
    // 设置请求类型为POST类型
    urlConn.setRequestMethod("POST");
    // 设置连接超时为5秒,针对的是建立连接的过程
    urlConn.setConnectTimeout(5000);
    //设置读取超时为5秒,针对的是从inputStream读数据的过程,若超过5秒无数据可读则超时
    urlConn.setReadTimeout(5000);
    //设置用于输入,输出
    urlConn.setDoOutput(true);
    urlConn.setDoInput(true);
    //Post方式不能缓存,需手动设置为false
    urlConn.setUseCaches(false);
    //.....根据自己需要,设置Http请求头部信息.....
    urlConn.setRequestProperty("Connection", "Keep-Alive");
    //.....根据自己的需要,组装Http请求数据体内容.....
    String data = "xxxxxxxxxxxxx";
    //获取输出流,并写入请求数据体内容
    OutputStream out = urlConn.getOutputStream();
    out.write(data.getBytes());
    out.flush();
    //进行连接
    urlConn.connect();
    //请求成功时
    if(urlConn.getResponseCode() == HttpURLConnection.HTTP_OK){
        //获取网络结果的读取流
        InputStream in = urlConn.getInputStream();
        //创建结果数据的目标输出流
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        //读过程的缓冲区
        byte[] temp = new byte[4096];
        //不断读数据,并写入目标输出流
        int len;
        while((len = in.read(temp)) != -1){
            bos.write(temp, 0, len);
        }
        bos.flush();
        //从目标输出流一次性取出结果数据
        byte[] res = bos.toByteArray();
        in.close();
        bos.close();
        return res;
    }
} catch (MalformedURLException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

2.使用HttpClient
(Android5.0之后已经废弃)
(org.apache.http.client.HttpClient接口,开源组织Apache提供的Java请求网络框架向上层提供的接口类)
     HttpClient对JDK中的HttpUrlConnection各API进行了封装和简化,提高了性能并简化了使用步骤。Android SDK中引进了这个jar包,不需要额外导入任何jar或者类库就可以直接使用,但是,看到网上的信息称,Android官方已经宣布不建议使用HttpClient了,是故日后还是别以之为惯用方式为妙。
2.1 Get请求
String path = ".....";//url字符串
HttpGet httpGet = new HttpGet( path );//请求对象
HttpClient httpClient = new DefaultClient();//连接对象
try{
    HttpResponse httpResponse = httpClient.execute( httpGet );//进行连接,并获取响应对象
    int code = httpResponse.getStatusLine().getStatusCode();
    if( code == 200 ){
        InputStream in = httpResponse.getEntity().getContent();
        .......
    }
    ......
} catch( ... ){
    ......
}

2.2 Post请求
大同小异,只不过HttpGet要换为HttpPost,多了一些头部信息设置;
多了一个环节,需要组装数据体,并绑定到HttpPost对象上,但并不需要我们来写发送的代码,貌似执行httpClient.execute( httpPost )时会自动发送吧,该环节如下所示:    
     List<NameValuePair> params = new ArrayList<NameValuePair>();  
     params.add(new BasicNameValuePair("id", "helloworld"));  
     params.add(new BasicNameValuePair("pwd", "android"));  
     // 设置字符集  
     HttpEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8);  
     // 设置参数实体  
     httpPost.setEntity(entity); 
三、Http报文格式简略说明
1.请求报文结构:
      请求行     {     请求方法(get/post等)+     URL     +     协议版本号     }     
+    头部        {     按照规范,根据自己需要来选择性添加     }
+    包体        {     即数据内容,post请求时,这部分才有数据;get请求时,数据附在URL参数里,格式为【URL?参数名=参数值】     }
2.响应报文格式
      状态行     {     协议版本号     +     状态码     +     状态码说明     }     
+    头部        {     按照规范,根据自己需要来选择性添加     }
+    包体        {     服务端返回给客户端的数据     }
     我们做应用层开发,无非就是借助已经写好的程序包,发送发文时,调用相关api接口,往HTTP报文里塞数据,对应的字段要塞上对应的数据;接收报文时,调用相关api接口,从所需字段取出数据,来解析。 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值