Android开发中给服务器发送Http请求获取响应
来源:互联网 发布:vue vendor.js 编辑:程序博客网 时间:2024/06/03 15:57
在android中,有很多的情况都要用到网络的功能,而发送HTTP请求的代码基本上是一样的。所以我觉得很有必要将这些通用的操作提取到一个公共类里,并提供一个静态的方法,当想要发起网络请求的时候只需要简单的调用一下这个方法即可。发送HTTP请求的方式在安卓开发中一般有两种,HttpURLConnection和HttpClient。在这里采用HttpURLConnection的写法:
public class HttpUtil {public static String sendHttpRequest(String address) {private HttpURLConnection connection;try {URL url = new URL(address);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuilder builder = new StringBuilder();String line;while ((line = reader.readLine()) != null) {builder.append(line);// 一行行的读取内容并追加到builder中去}return builder.toString();} catch (Exception e) {e.printStackTrace();return e.getMessage();} finally {if (connection != null) {connection.disconnect();//连接不为空就关闭连接}}}}
以后每当发起一条HTTP请求的时候就可以这样写:
String address = "https://www.baidu.com";String response = HttpUtil.sendHttpRequest(address);在获取到服务器的响应数据后我们就可以对它进行解析和处理了。但是需要注意的是网络操作属于耗时的操作,而sendHttpRequest()方法的内部并没有开启线程,这样就有可能导致在调用sendHttpRequest()方法的时候使得主线程被阻塞。
为什么可能会导致主线程阻塞呢?
这是因为在主线程中执行了耗时操作,如果耗时过久,就会使应用程序出现ANR异常,如果不知道这个异常的话自己百度一下就好了。一般主线程中用户的输入事件操作超过5s就会出现上述的异常,所以发送请求从服务器上获取数据是可能会导致主线程阻塞的。
你这时可能会说,很简单,在sendHttpRequest()方法内部开启一个线程不就解决这个问题了吗?其实不是你想的那么简单,如果我们在sendHttpRequest()方法中开启了一个线程来发HTTP请求,那么服务器响应的数据是无法进行返回的,所有的耗时操作逻辑都是在子线程里进行的,sendHttpRequest()方法会在服务器没来得及响应的时候就执行结束了,当然也就无法返回响应的数据了。
为什么会没响应就执行结束呢?
那是因为线程是并发的。懂了吗?不懂得话自己百度一下。
那么遇到上面说的"服务器没来得及响应的时候就执行结束了"这一情况,我们就要使用Java的回调机制了。下面来学习一下回调机制到底是如何使用的。
首先需要定义一个接口,比如将它命名为HttpCallbackListener,代码如下:
/** * 定义一个接口,接口中定义了两个方法 * @author Administrator * */public interface HttpCallbackListener {void onFinish(String response);//当服务器成功响应的时候会调用该方法void onError(Exception e);//当进行网络操作错误的时候会调用该方法}可以看到,我们在接口中定义了两个方法,onFinish()方法表示当服务器成功响应我们请求的时候调用,onError()表示进行网络操作出现错误的时候调用,而onError()方法中的参数记录着错误的详细信息。
接着修改HttpUtil中的代码,如下:
package com.example.android_ydhl_system.util;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.HttpURLConnection;import java.net.URL;public class HttpUtil {/** * 发送网络请求的时候调用该方法 * @param address URL对象 * @param listener实例化的接口对象,回调方法需要实例化接口 */public static void sendHttpRequest(final String address,final HttpCallbackListener listener) {new Thread() {private HttpURLConnection connection;public void run() {try {URL url = new URL(address);connection = (HttpURLConnection) url.openConnection();connection.setRequestMethod("GET");connection.setConnectTimeout(8000);connection.setReadTimeout(8000);connection.setDoInput(true);connection.setDoOutput(true);InputStream in = connection.getInputStream();BufferedReader reader = new BufferedReader(new InputStreamReader(in));StringBuilder builder = new StringBuilder();// 创建一个StringBuilder对象String line;while ((line = reader.readLine()) != null) {builder.append(line);// 一行行的读取内容并追加到builder中去}if (listener != null) {// 回调onFinish()方法listener.onFinish(builder.toString());}} catch (Exception e) {e.printStackTrace();// 回调onError()方法listener.onError(e);} finally {if (connection != null) {connection.disconnect();//连接不为空就关闭连接}}};}.start();}}我们首先给sendHttpRequest()方法添加了一个HttpCallbackListener参数,并在方法的内部开启了一个子线程,然后在子线程里去执行具体的网络操作。注意子线程中是无法通过return语句来返回数据的。
这时候又有人会说这是为什么呢?
其实很简单,因为run()方法是没有返回值的。大家可以看看上面线程中的run()方法就知道了。
接下来怎么办?既然无法通过return语句返回数据,那么我们可以将服务器响应的数据传入HttpCallbackListener的onFinish()方法中,如果出现了异常就将异常原因传入到onError()方法中。
现在sendHttpRequest()方法接收两个参数了,因此我们在调用它的时候还需要将HttpCallbackListener的实例传入,如下所示:
HttpUtil.sendHttpRequest(address, new HttpCallbackListener() {@Overridepublic void onFinish(String response) {Log.d("TAG", response.toString());}@Overridepublic void onError(Exception e) {}});这样的话,当服务器成功响应的时候我们就可以在onFinish()方法里对响应的数据进行处理了,类似地,如果出现了异常,就可以在onError()方法里对异常情况进行处理。如此一来,我们就其巧妙的利用回调机制将响应的数据成功返回给调用方了。
另外需要注意的是,onFinish()方法和onError()方法最终是运行在子线程中的,因此我们不可以在这里执行UI操作,如果需要根据返回的结果来更新UI,则要使用异步消息处理机制,即handler发消息。
每天进步一点点,加油!
- Android开发中给服务器发送Http请求获取响应
- Android开发中给服务器发送Http请求获取响应
- 发送http请求获取响应
- Android中对服务器发送http请求
- Android发送GET和POST以及HttpClient发送POST请求给服务器响应
- Android发送GET和POST以及HttpClient发送POST请求给服务器响应
- Android发送GET和POST以及HttpClient发送POST请求给服务器响应
- 我的Android进阶之旅------>Android发送GET和POST以及HttpClient发送POST请求给服务器响应
- 我的Android进阶之旅------>Android发送GET和POST以及HttpClient发送POST请求给服务器响应
- Android向EasyN摄像头发送http get请求获取媒体数据响应包
- java发送http请求获取响应结果【工具包系列】
- WEB客户端发送给WEB服务器的HTTP请求消息
- Android中Http网络请求响应基本知识
- Android HTTP实例 发送请求和接收响应
- Android HTTP实例 发送请求和接收响应
- Android Http连接 实例:发送请求和接收响应
- Android向Http服务器发送Http请求异常-UnknowHostException
- Android向Http服务器发送Http请求异常-UnknowHostException
- Codeforces Round #343 (Div. 2) -B. Far Relative’s Problem(模拟)
- 关于android 视频压缩的几个技术,java层面就可以解决
- ios 音频队列实现录音和播音(转)
- ASP.NET @Page指令属性(vs2010)
- 机房收费系统个人版重构——报表制作
- Android开发中给服务器发送Http请求获取响应
- detached entity passed to persist: com.china.user.entity.Employee
- js 限制输入框的字节数,中文两个字节,英文字母一个字节
- [UOJ35]后缀排序 做题笔记
- Window环境WordPress部署
- poj1014 Dividing 多重背包DP+神剪枝
- 线程状态转换图
- WPF-DataTemplate创建数据模版
- java并发编程基础之线程安全