美文网首页Android 理论
Android 网络通信机制

Android 网络通信机制

作者: alsheng | 来源:发表于2018-10-13 14:47 被阅读1334次

    前言:通过网上查询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请求区别列表

    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<BasicNameValuePair> 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;
    }
    
    androidnet.png
    这个https://developer.android.google.cn/reference/android/net/wifi/package-summary
    网址是官网提供的,里面有对android.net的详解

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

    相关文章

      网友评论

        本文标题:Android 网络通信机制

        本文链接:https://www.haomeiwen.com/subject/umaeaftx.html