目录

一、使用HttpUrlConnection访问网络

1、发送GET请求

tips: 如何处理302重定向

2、发送POST请求

二、OkHttp的使用方法

三、WebView的使用方法


 

一、使用HttpUrlConnection访问网络

在Android 6.0以前,Android上发送HTTP请求一般有两种方式,HttpUrlConnection和HttpClient。HttpClient是Apache的开源库,存在API数量过多、扩展困难等缺点,在Android6.0系统中,将HttpClient的功能完全移除了。官方建议使用HttpUrlConnection来进行网络请求。

1、发送GET请求

/*    使用HttpUrlConnection发送GET请求    */    public static void sendHttpGetRequest(final String address){        new Thread(new Runnable() {            @Override            public void run() {                URL url = null;//请求的url地址                HttpURLConnection conn = null;                InputStream is = null;                ByteArrayOutputStream baos = null;                String requestHeader = null;//请求头                String requestBody = null;//请求体                String responseHeader = null;//响应头                String responseBody = null;//响应体                try {                    //创建一个URL对象                    url = new URL(address);                    //打开一个HttpUrlConnection连接                    conn = (HttpURLConnection)url.openConnection();                    //设置GET、POST请求方式,默认使用GET发送请求                    conn.setRequestMethod("GET");                    //设置连接超时时间                    conn.setConnectTimeout(5000);                    //设置从服务器读取数据超时时间                    conn.setReadTimeout(5000);                    //设置是否使用缓存,默认true                    conn.setUseCaches(true);                    //设置从服务端读取结果流,默认true                    conn.setDoInput(true);                    //用来设置请求头                    conn.setRequestProperty("Connection", "Keep-Alive");                    conn.setRequestProperty("TestDemo", "GET");                    //在对各种参数配置完成后,通过调用connect方法建立TCP连接,但是并未真正获取数据                    //connect()方法不必主动调用,当调用getInputStream()方法时内部也会自动调用connect方法                    conn.connect();                    if(conn.getResponseCode() == 200){                        //调用getInputStream方法后,服务端才会收到请求,并阻塞式地接收服务端返回的数据                        is = conn.getInputStream();                        baos = new ByteArrayOutputStream();                        byte[] bytes = new byte[1024];                        int len = 0;                        while((len = is.read(bytes)) != -1){                            baos.write(bytes, 0, len);                        }                        requestBody = baos.toString();                        Log.d(TAG, "run: response " + requestBody);                    }else if(conn.getResponseCode() == 302){                        //处理重定向,这里只是一个简单的例子,不是标准写法                        String location = conn.getHeaderField("Location");                        url = new URL(location);                        //打开一个HttpUrlConnection连接                        conn = (HttpURLConnection)url.openConnection();                        conn.setRequestMethod("GET");                        conn.setConnectTimeout(5000);                        conn.setReadTimeout(5000);                        conn.setUseCaches(true);                        conn.connect();                    }                } catch (Exception e) {                    e.printStackTrace();                }finally {                    try {                        if (baos != null){                            baos.close();                        }                        if(is != null){                            is.close();                        }                        if(conn != null){                            conn.disconnect();                        }                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }        }).start();    }

tips: 如何处理302重定向

1、网络请求属于耗时操作,不可以在主线程内进行,需要单独起一个线程进行网络请求操作;

2、HttpUrlConnection有两个方法来设置是否自动处理重定向setFollowRedirects()和setInstanceFollowRedirects(),但我设置后访问http://www.baidu.com,并没有自动重定向,还会返回302的错误码,手动处理后,可以获取response header里的Location,是重定向后的url。而OkHttp可以自动处理重定向,okhttp的重定向默认是开启的,可以手动设置为关闭。

 

2、发送POST请求

/*    * 使用HttpUrlConnection发送POST请求    * */    public static void sendHttpPostRequest(final String address){        new Thread(new Runnable() {            @Override            public void run() {                URL url = null;                HttpURLConnection conn = null;                DataOutputStream dos = null;                InputStream is = null;                ByteArrayOutputStream baos = null;                String requestHeader = null;//请求头                String requestBody = null;//请求体                String responseHeader = null;//响应头                String responseBody = null;//响应体                try {                    //创建一个URL对象                    url = new URL(address);                    //打开一个HttpUrlConnection连接                    conn = (HttpURLConnection)url.openConnection();                    //设置请求方式为POST,必须设置,默认GET                    conn.setRequestMethod("POST");                    //设置允许输出,POST请求必须设置,默认false                    conn.setDoOutput(true);                    //设置请求默认输入,默认true                    conn.setDoInput(true);                    //设置请求头                    conn.setRequestProperty("TestDemo", "POST");                    //设置连接超时时间                    conn.setConnectTimeout(5000);                    //设置从服务器读取数据超时时间                    conn.setReadTimeout(5000);                    //设置本次连接是否自动处理重定向                    conn.setInstanceFollowRedirects(true);                    //开始连接                    conn.connect();                    //发送请求的POST参数,键值对形式                    dos = new DataOutputStream(conn.getOutputStream());                    dos.writeBytes("username=prance&password=123456");                    dos.flush();                    dos.close();                    if(conn.getResponseCode() == 200){                        is = conn.getInputStream();                        baos = new ByteArrayOutputStream();                        byte[] bytes = new byte[1024];                        int len = 0;                        while((len = is.read(bytes))!=-1){                            baos.write(bytes, 0 , len);                        }                        responseBody = baos.toString();                        Log.d(TAG, "run: response" + responseBody);                    }                } catch (Exception e) {                    e.printStackTrace();                }finally {                    try {                        if (baos != null){                            baos.close();                        }                        if(is != null){                            is.close();                        }                        if(conn != null){                            conn.disconnect();                        }                    } catch (IOException e) {                        e.printStackTrace();                    }                }            }        }).start();    }

二、OkHttp的使用方法

    1、添加OkHttp库的依赖

       在app/build.gradle文件中,dependencies闭包中加入依赖:

   dependencies {       ......       implementation 'com.squareup.okhttp3:okhttp:3.12.1'}        其他引入方式,见github上okhttp库的说明:https://github.com/square/okhttp

     2、使用方法

      (1)Get请求

 /*发送HTTP Get请求    * 参数:    *    address:请求的url地址    * */    public static void sendOkHttpRequest(final String address){        new Thread(new Runnable() {            @Override            public void run() {                //创建一个OkHttpClient的实例                OkHttpClient okHttpClient = new OkHttpClient();                //创建一个Request对象                Request request = new Request.Builder().url(address).build();                try {                    //调用OkHttpClient的newCall()方法来创建一个Call对象,通过它的execute()方法来发送请求并获取服务器返回的数据                    Response response = okHttpClient.newCall(request).execute();                    Log.d(TAG, "run: " + response.body().string());                } catch (IOException e) {                    e.printStackTrace();                }            }        }).start();    }

需要注意的是,发送网络请求属于耗时操作,无法在UI线程(主线程)进行,使用的时候一定单独起一个子线程去发送网络请求,否则会抛出android.os.NetworkOnMainThreadException的异常导致程序崩溃。

因此,OkHttp提供了一个回调接口,可供调用方有时机去处理服务器返回的数据

/*发送HTTP Get请求 * 参数: *    address: 请求的url地址 *    callback: OkHttp回调接口 * */public static void sendOkHttpRequest2(String address, Callback callback){    //创建一个OkHttpClient的实例    OkHttpClient okHttpClient =  new OkHttpClient();    //创建一个Request对象    Request request = new Request.Builder().url(address).build();    //调用OkHttpClient的newCall()方法来创建一个Call对象    //enqueue()方法内部会开启一个子线程去执行http请求,并将最终的请求结果回调到Callback中    okHttpClient.newCall(request).enqueue(callback);}

调用方式:

HttpUtilty.sendOkHttpRequest("http://www.baidu.com", new Callback() {    @Override    public void onFailure(Call call, IOException e) {        runOnUiThread(new Runnable() {            @Override            public void run() {                Toast.makeText(getApplicationContext(), "http connected failed", Toast.LENGTH_SHORT).show();            }        });    }    @Override    public void onResponse(Call call, Response response) throws IOException {        Log.d(TAG, "onResponse: " + response.body().string());        runOnUiThread(new Runnable() {            @Override            public void run() {                Toast.makeText(getApplicationContext(), "success", Toast.LENGTH_SHORT).show();            }        });    }});

需要注意的是,Callback最终的回调接口还是在okhttp起的子线程中运行的,因此不可以直接在回调接口里执行任何UI操作,可以借助runOnUiThread()方法来进行线程切换。

(2)Post请求     

public static void sendOkHttpPostRequest(String address, Callback callback){    //创建一个OkHttpClient的实例    OkHttpClient okHttpClient =  new OkHttpClient ();    //构建一个RequestBody对象来存放待提交的参数    RequestBody requestBody = new FormBody.Builder()            .add("username", "admin")            .add("password", "123456")            .build();    //创建一个Request对象    Request request = new Request.Builder()            .url(address)            .post(requestBody)            .build();    //调用OkHttpClient的newCall()方法来创建一个Call对象    //enqueue()方法内部会开启一个子线程去执行http请求,并将最终的请求结果回调到Callback中    okHttpClient.newCall(request).enqueue(callback);}

 

三、WebView的使用方法

Android提供了一个WebView控件,借助它可以在自己的应用程序里嵌入一个浏览器,从而非常轻松的展示各种各样的网页。

1、创建一个布局文件,引入WebView控件

<?xml version="1.0" encoding="utf-8"?>        

2、在Activity中使用WebView控件

    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_http_demo);        WebView webView = findViewById(R.id.webview);        webView.getSettings().setJavaScriptEnabled(true);        webView.setWebViewClient(new WebViewClient());        webView.loadUrl("http://www.baidu.com");    }

注意,这里使用了WevView的setWebViewClient()方法,并传入了一个WevViewClient的实例,作用是,希望目标网页仍然在当前WebView中展示,而不是打开系统浏览器。如果没有设置这个,那应用中会弹窗提示使用哪个浏览器打开目标网页,而不会在当前你自己的应用中展现网页。

更多相关文章

  1. EasyPermission Android(安卓)6.0 最简洁的权限框架
  2. android app设置亮屏的几种方式以及功耗对比
  3. react-native调用Android原生控件
  4. Android(安卓)边框圆角
  5. Android(安卓)TextView中文字设置超链接、颜色、字体 大杂烩
  6. Android(安卓)ViewPager 取消预加载
  7. android Xutils Http模块分析
  8. 为什么应用商店里搜索不到你的App?
  9. Android(安卓)Adapter 源码笔记(3)

随机推荐

  1. Android 上实现微信微博上的应用语言切换
  2. Android监听屏幕屏幕锁屏与解锁
  3. android 图片浏览器 APP 源码
  4. android分组数据适配器demo
  5. android 之 读取本地json文件返回string
  6. Android标题栏(titlebar)显示进度条
  7. RemoteViews使用setImageResource出错
  8. Socket编程java[简单易懂],附带Android S
  9. 1.Android系统架构
  10. android 数据库更改数据库位置【DbFlow示