Android 网络通信机制

前言:通过网上查询Android网络通信机制,大部分都是介绍这三种。因此,自己通过代码来实现网络通信。
首先先通过该网址 http://www.w3school.com.cn/tags/html_ref_httpmethods.asp 了解http中最常用的get和post请求区别。

一、标准的java接口(java.NET)

HttpURLConnection

HttpURLconnection是基于http协议的,支持get,post,put,delete等各种请求方式,最常用的就是get和post,下面针对这两种请求方式进行讲解。
HttpURLconnection是同步的请求,所以必须放在子线程中,下面以登录功能,来进行分析。(亲测)

private String getUrl = "网址/login.shtml?loginName=xxxxx&password=xxxxx";
private String headUrl = "网址/login.shtml";
MyHttpURLConnection( ) {
    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(getUrl);
                //得到connection对象。
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                //设置请求方式
                connection.setRequestMethod("GET");
                connection.setConnectTimeout(3000);//连接的超时时间
                //连接
                connection.connect();
                //得到响应码
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    //得到响应流  connection.getInputStream()只是得到一个流对象,并不是数据,从这个流对象中只能读取一次数据,第二次读取时将会得到空数据
                    InputStream inputStream1 = connection.getInputStream();
                    //将响应流转换成字符串
                    String result1 = stream2String(inputStream1);//将流转换为字符串。
                    Log.d("getHttpURLConnection","result=============" + result1);

                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(getUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");//设置请求方式为POST
                connection.setConnectTimeout(3000);//连接的超时时间
                connection.setDoOutput(true);//允许写出
                connection.setDoInput(true);//允许读入
                connection.setUseCaches(false);//不使用缓存
                connection.connect();//连接
                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    String result = stream2String(inputStream);//将流转换为字符串。
                    Log.d("postHttpURLConnection1","result=============" + result);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {
        @Override
        public void run( ) {
            try {
                URL url = new URL(headUrl);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                connection.setRequestMethod("POST");
                connection.setDoOutput(true);
                connection.setDoInput(true);
                connection.setUseCaches(false);
                connection.connect();

                String body = "loginName=xxxx&password=xxxx";
                BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(connection.getOutputStream(),
                        "UTF-8"));
                writer.write(body);
                writer.close();

                //post Json数据
                //                    connection.setRequestProperty("Content-Type", "application/json;
                // charset=utf-8");//设置参数类型是json格式
                //                    connection.connect();
                //                    String body = "{userName:xxxx,password:xxxx}";
                //                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter
                // (connection.getOutputStream(), "UTF-8"));
                //                    writer.write(body);
                //                    writer.close();

                //post上传文件
                //                    connection.setRequestProperty("Content-Type", "file/*");//设置数据类型
                //                    connection.connect();
                //                    OutputStream outputStream = connection.getOutputStream();
                //                    FileInputStream fileInputStream = new FileInputStream("file");//把文件封装成一个流
                //                    int length = -1;
                //                    byte[] bytes = new byte[1024];
                //                    while ((length = fileInputStream.read(bytes)) != -1){
                //                        outputStream.write(bytes,0,length);//写的具体操作
                //                    }
                //                    fileInputStream.close();
                //                    outputStream.close();

                int responseCode = connection.getResponseCode();
                if (responseCode == HttpURLConnection.HTTP_OK) {
                    InputStream inputStream = connection.getInputStream();
                    String result = stream2String(inputStream);//将流转换为字符串。
                    Log.d("postHttpURLConnection2","result=============" + result);
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }).start();

}

/**
 * 将get获取的字节流转换为字符串
 * @param is
 * @return
 * @throws IOException
 */
private String stream2String(InputStream is) throws IOException {
    if (is != null) {// ByteArrayOutputStream好处:边读,边缓冲数据// 可以捕获内存缓冲区的数据,转换成字节数组
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        byte[] buffer = new byte[1024];
        int temp = -1;
        while ((temp = is.read(buffer)) != -1) {
            baos.write(buffer,0,temp);
        }
        is.close();
        baos.close();
        return baos.toString();
    }
    return null;
}

以上是简单的HttpURLConnection数据请求,得到的结果是一样的,通过以上代码可以清晰的看得出,post和get请求数据的基本差异,以及它们通过网址的不同请求。

以下是http://www.w3school.com.cn/tags/html_ref_httpmethods.asp中的关于post和get请求区别列表

Android 网络通信机制_第1张图片
QQ截图20181010173916.png

图上标记为目前我所能看到和实现的。

socket(这个比较特殊,下次有空详细介绍)

二、Apache接口(org.apache.http)

HttpClient
private String getUrl = "网址/login.shtml?loginName=xxx&password=xxx";
private String headUrl = "网址/login.shtml";
private final BasicCookieStore cookieStore = new BasicCookieStore();
private HttpResponse getResp;
private HttpResponse postResp;
private HttpClient mHttpClient;

public MyHttpClient( ) {
    new Thread(new Runnable() {//get请求数据
        @Override
        public void run( ) {
            mHttpClient = new DefaultHttpClient();
            // 保持和服务器登录状态一直是登录着的,必不可少设置全局唯一的Cookie(不了解这步的意图,加不加都可get数据)
            ((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
            HttpGet httpGet = new HttpGet(getUrl);
            httpGet.addHeader("contentType","application/json");
            try {
                getResp = mHttpClient.execute(httpGet);
                if (getResp.getStatusLine().getStatusCode() == 200) {
                    String result = EntityUtils.toString(getResp.getEntity());
                    Log.i(TAG,"get请求结果: " + result);
                } else {
                    Log.i(TAG,"get请求结果: error");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {//post请求数据
        @Override
        public void run( ) {
            mHttpClient = new DefaultHttpClient();
            // 保持和服务器登录状态一直是登录着的,必不可少设置全局唯一的Cookie
            ((AbstractHttpClient) mHttpClient).setCookieStore(cookieStore);
            HttpPost httpPost = new HttpPost(getUrl);
            httpPost.addHeader("contentType","application/json");
            try {
                postResp = mHttpClient.execute(httpPost);
                if (postResp.getStatusLine().getStatusCode() == 200) {
                    String result = EntityUtils.toString(postResp.getEntity());
                    Log.i(TAG,"post请求结果: " + result);
                } else {
                    Log.i(TAG,"post请求结果: error");
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }).start();

    new Thread(new Runnable() {//post请求数据
        @Override
        public void run( ) {

            //创建客户端对象
            mHttpClient = new DefaultHttpClient();
            //创建post请求对象
            HttpPost httpPost = new HttpPost(headUrl);

            //封装form表单提交的数据
            BasicNameValuePair basicNameValuePair1 = new BasicNameValuePair("loginName","xxx");
            BasicNameValuePair basicNameValuePair2 = new BasicNameValuePair("password","xxx");
            List parameters = new ArrayList<>();
            //把BasicNameValuePair放入集合中
            parameters.add(basicNameValuePair1);
            parameters.add(basicNameValuePair2);

            try {
                //要提交的数据都已经在集合中了,把集合传给实体对象
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
                //设置post请求对象的实体,其实就是把要提交的数据封装至post请求的输出流中
                httpPost.setEntity(entity);
                //3.使用客户端发送post请求
                postResp = mHttpClient.execute(httpPost);
                if (postResp.getStatusLine().getStatusCode() == 200) {
                    InputStream result = postResp.getEntity().getContent();
                    Log.i(TAG,"post请求结果: " + getTextFromStream(result));
                } else {
                    Log.i(TAG,"post请求结果: error");
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

        }
    }).start()
  }

/**
 * 字节流转换为字符串
 * @param result
 * @return
 */
private String getTextFromStream(InputStream result) {

    byte[] b = new byte[1024];
    int len = 0;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
        while ((len = result.read(b)) != -1) {
            bos.write(b,0,len);
        }
        String text = new String(bos.toByteArray());
        bos.close();
        return text;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

以上是HttpClient的get和post请求数据,简单的三种数据请求,得到的结果相同,在httpClient中post和get请求数据除了HttpPost 和httpGet的对象不同,其余的没有什么差异,不过也能实现上图中get和post的区别表中的特性。

三、Android.net网络接口

对于android.net网络接口本人不了解,但从网上查询了解了一下之后,知道这就是一个api接口,android自带的接口,常常使用此包下的类进行Android特有的网络编程,如:访问WiFi,访问Android联网信息,邮件等功能。这个我用的比较少,一般用的都是别人写好的。

 private Context mContext;
 AndroidNet(Context context) {
    this.mContext = context;

}

/**
 *     确定您是否连入了互联网
 *     如果您未连入互联网,则无需安排基于互联网资源的更新。 下面这段代码展示了如何利用 ConnectivityManager 查询活动网络并确定其是否连入了互联网。
 * @return true 已连接
 */
private boolean IsNoConnected( ) {
    ConnectivityManager cm =
            (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
    boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
    //是否是wifi
    //boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
    return isConnected;
}

Android 网络通信机制_第2张图片
androidnet.png

这个 https://developer.android.google.cn/reference/android/net/wifi/package-summary
网址是官网提供的,里面有对android.net的详解

以上是我对于通信机制类型的简单了解,若有补充不到或理解有误的地方,望赐教。

你可能感兴趣的:(Android 网络通信机制)