【网络编程与网络框架】

【网络编程与网络框架】,第1张

网络编程与网络框架

HttpClient、HttpURLConnection、OkHttp


提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录
  • 网络编程与网络框架
  • HttpClient
    • 一、Get
    • 二、Post
  • HttpURLConnection
    • Post
  • OkHttp
    • Get
    • Post
    • 异步上传
    • 异步下载
  • 关于封装


HttpClient

Android SDK 中包含了HttpClient。Android 6.0版本直接删除了HttpClient类库。如果你仍想使用它,解决方法就是在相应的modue下的build.gradle中加入如下代码: useLibrary 'org.apache.http.legacy'

一、Get

创建HttpClient

private HttpClient createHttpCient(){
    HttpParams mDefautHttpParams = new BasicHttpParams();
    //设置链接超时
    HttpConnectionParams.setConnectionTimeout(mDefautHttpParams,15000);
    //设置请求超时
    HttpConnectionParams.setSoTimeout(mDefautHttpParams,15000);
    HttpConnectionParams.setTcpNoDelay(mDefautHttpParams,true);
    HttpProtocolParams.setVersion(mDefautHttpParams, HttpVersion.HTTP_1_1);
    HttpProtocolParams.setContentCharset(mDefautHttpParams, HTTP.UTF_8);
    //持续握手
    HttpProtocolParams.setUseExpectContinue(mDefautHttpParams,true);
    HttpClient mHttpClient = new DefaultHttpClient(mDefautHttpParams);
    return mHttpClient;
}

创建HttpGet和HttpClient,请求网络并得到HttpResponse,并对HttpResponse进行处理

private void useHttpClientGet(String url){
        HttpGet mHttpGet = new HttpGet(url);
        mHttpGet.addHeader("Connection","Keep-Alive");
        try {
            HttpClient mHttpClient = createHttpCient();
            HttpResponse mHttpResponse = mHttpClient.execute(mHttpGet);
            HttpEntity mHttpEntity = mHttpResponse.getEntity();
            int code = mHttpResponse.getStatusLine().getStatusCode();
            if (null != mHttpEntity){
                InputStream mInputStream = mHttpEntity.getContent();
                String respose = converStreamToString(mInputStream);
                Log.e("HttpClient","请求状态码:"+code+"\n请求结果:\n"+respose);
                mInputStream.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    
    private String converStreamToString(InputStream is) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(is));
        StringBuffer sb = new StringBuffer();
        String line = null;
        while ((line = reader.readLine()) != null){
            sb.append(line + "\n");
        }
        String respose = sb.toString();
        return respose;
    }

开启线程访问具体网站

new Thread(new Runnable() {
            @Override
            public void run() {
                useHttpClientGet("http://www.baidu.com");     
            }
        }).start();
二、Post
创建Post请求
private void useHttpClientPost(String url){
        HttpPost mHttpPost = new HttpPost(url);
        mHttpPost.addHeader("Connection","Keep-Alive");
        try {
            HttpClient mHttpClient = createHttpCient();
            List<NameValuePair> postParams = new ArrayList<>();
            //要传递的参数
            postParams.add(new BasicNameValuePair("ip","59.108.54.37"));
            mHttpPost.setEntity(new UrlEncodedFormEntity(postParams));
            HttpResponse mHttpResponse = mHttpClient.execute(mHttpPost);
            HttpEntity mHttpEntity = mHttpResponse.getEntity();
            int code = mHttpResponse.getStatusLine().getStatusCode();
            if (null != mHttpEntity){
                InputStream mInputStream = mHttpEntity.getContent();
                String respose = converStreamToString(mInputStream);
                Log.e("HttpClient","请求状态码:"+code+"\n请求结果:\n"+respose);
                mInputStream.close();
            }
        }catch (Exception e){
        }
    }
开启线程访问具体网站
new Thread(new Runnable() {
        @Override
        public void run() {
            useHttpClientPost("http://ip.******.com/service/getIpinfo.php");
        }
    }).start();
HttpURLConnection

在Android 2.2及其之前的版本中,HttpURLConnection一直存在着一些令人厌烦的bug。比如对一个可读的InputStream调用close方法时,就会可能导致连接池失效。通常的解决办法就是禁用连接池功能

 private void disableConnectionReuseIfNecessary(){
        //这是Android 2.2及其之前版本的一个bug
        if (Integer.parseInt(Build.VERSION.SDK) < Build.VERSION_CODES.FROYO){
            System.setProperty("http.keepAlive","false");
        }
    }
Post
若学会了Post请求,则Get请求也就学会了。这里只举例Post

创建一个UrlConnManager类,然后在里面提供一个getHttpURLConnection方法用于配置默认参数并返回HttpURLConnection

public static HttpURLConnection getHttpURLConnection(String url){
        HttpURLConnection mHttpURLConnection = null;
        try {
            URL mUrl = new URL(url);
            mHttpURLConnection = (HttpURLConnection) mUrl.openConnection();
            //设置连接超时时间
            mHttpURLConnection.setConnectTimeout(15000);
            //设置读取超时时间
            mHttpURLConnection.setReadTimeout(15000);
            //设置请求参数
            mHttpURLConnection.setRequestMethod("POST");
            //添加Header
            mHttpURLConnection.setRequestProperty("Connection","Keep-Alive");
            //接收输入流
            mHttpURLConnection.setDoInput(true);
            //传递参数时需要开启
            mHttpURLConnection.setDoOutput(true);
        }catch (Exception e){
        }
        return mHttpURLConnection;
    }

在UrlConnManager类中再写一个postParams方法,组织一下请求参数并将请求参数写入输入流

public static void postParams(OutputStream outputStream, List<NameValuePair> pairList)throws IOException {
        StringBuffer mStringBuffer = new StringBuffer();
        for (NameValuePair pair : pairList){
            if (!TextUtils.isEmpty(mStringBuffer)){
                mStringBuffer.append("&");
            }
            mStringBuffer.append(URLEncoder.encode(pair.getName(),"UTF-8"));
            mStringBuffer.append("=");
            mStringBuffer.append(URLEncoder.encode(pair.getValue(),"UTF-8"));
        }
        BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream,"UTF-8"));
        writer.write(mStringBuffer.toString());
        writer.flush();
        writer.close();
    }

请求连接并处理返回结果

private void useHttpUrlConnectionPost(String url){
        InputStream inputStream = null;
        HttpURLConnection httpURLConnection = UrlConnManager.getHttpURLConnection(url);
        try {
            List<NameValuePair> postParams = new ArrayList<>();
            postParams.add(new BasicNameValuePair("ip","59.108.54.37"));
            UrlConnManager.postParams(httpURLConnection.getOutputStream(),postParams);
            httpURLConnection.connect();
            inputStream = httpURLConnection.getInputStream();
            int code = httpURLConnection.getResponseCode();
            String respose = converStreamToString(inputStream);
            Log.e("HttpUrlConnection","请求状态码:"+code+"\n请求结果:\n"+respose);
            inputStream.close();
        }catch (IOException e){
        }
    }
OkHttp

准备工作:

配置gradle
implementation ‘com.squareup.okhttp3:okhttp:3.2.0’
implementation ‘com.squareup.okio:okio:1.7.0’

Get
private void useOkHttpGet(String url){
        Request.Builder builder = new Request.Builder().url(url);
        builder.method("GET",null);
        Request request = builder.build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Call mcall = okHttpClient.newCall(request);
        mcall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                Log.e("OkHttp","请求成功:"+str);
            }
        });
    }
Post
private void useOkHttpPost(String url){
        RequestBody formBody = new FormBody.Builder()
                .add("ip","59.108.54.37")
                .build();
        Request request = new Request.Builder()
                .url(url)
                .post(formBody)
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        Call mcall = okHttpClient.newCall(request);
        mcall.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                Log.e("OkHttp","请求成功:"+str);
            }
        });
    }
异步上传
上传文件本身也是一个POST请求,首先定义文件上传类型

一. 定义文件上传类型

public static final MediaType MEDIA_TYPE_MARKDOWN =
MediaType.parse(“text/x-markdown; charset=utf-8”);

二. 上传文件

private void useOkHttpUpload(String url){
    String filePath = "";
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
        filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
    }else {
        return;
    }
    File file = new File(filePath,"upload.txt");
    Request request = new Request.Builder()
            .url(url)
            .post(RequestBody.create(MEDIA_TYPE_MARKDOWN,file))
            .build();
    OkHttpClient okHttpClient = new OkHttpClient();
    okHttpClient.newCall(request).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {
        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            String str = response.body().string();
            Log.e("OkHttp","请求成功:"+str);
        }
    });
}

三. 上传文件

private void useOkHttpUpload(String url){
        String filePath = "";
        if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
            filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
        }else {
            return;
        }
        File file = new File(filePath,"upload.txt");
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(MEDIA_TYPE_MARKDOWN,file))
                .build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String str = response.body().string();
                Log.e("OkHttp","请求成功:"+str);
            }
        });
    }
异步下载
private void useOkHttpDown(String url){
        Request request = new Request.Builder().url(url).build();
        OkHttpClient okHttpClient = new OkHttpClient();
        okHttpClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream inputStream = response.body().byteStream();
                FileOutputStream fileOutputStream = null;
                String filePath = "";
                try {
                    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
                        filePath = Environment.getExternalStorageDirectory().getAbsolutePath();
                        File file = new File(filePath,"down.jpg");
                        if (file != null){
                            fileOutputStream = new FileOutputStream(file);
                            byte[] buffer = new byte[2048];
                            int len = 0;
                            while ((len = inputStream.read(buffer)) != -1){
                                fileOutputStream.write(buffer,0,len);
                            }
                            fileOutputStream.flush();
                        }
                    }
                    
                }catch (IOException e){
                }
            }
        });

设置超时时间和缓存

File sdcache = new File("");
        OkHttpClient.Builder builder = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(20,TimeUnit.SECONDS)
                .readTimeout(20,TimeUnit.SECONDS)
                .cache(new Cache(sdcache,10 * 1024 * 1024));
        
        OkHttpClient okHttpClient = builder.build();

取消请求
1、使用call.cancel,不管是同步还是异步都可以取消
2、使用OkHttpClient.cancel(Object tag)进行取消

关于封装

这里就不多讲了,可参考OkHttpFinal源码进行学习

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/917661.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-16
下一篇 2022-05-16

发表评论

登录后才能评论

评论列表(0条)

保存