网络

Android 笔记 —— Http 网络探索

2017-05-04  本文已影响51人  GinkWang

Http 请求及相应

请求包结构

请求包

示例:

   POST /meme.php/home/user/login HTTP/1.1
   Host: 114.215.86.90
   Cache-Control: no-cache
   Postman-Token: bd243d6b-da03-902f-0a2c-8e9377f6f6ed
   Content-Type: application/x-www-form-urlencoded
​
   tel=13637829200&password=123456

响应包结构

相应包

示例:

 HTTP/1.1 200 OK
   Date: Sat, 02 Jan 2016 13:20:55 GMT
   Server: Apache/2.4.6 (CentOS) PHP/5.6.14
   X-Powered-By: PHP/5.6.14
   Content-Length: 78
   Keep-Alive: timeout=5, max=100
   Connection: Keep-Alive
   Content-Type: application/json; charset=utf-8
​
   {"status":202,"info":"\u6b64\u7528\u6237\u4e0d\u5b58\u5728\uff01","data":null}

Http 请求方式

GET & POST

使用 HttpURLConnection 发送 HTTP 请求

以前,Android 上发送 HTTP 请求有两种方式,HttpURLConnection 和 HttpClient。不过由于 HttpClient 存在 API 数量众多,维护困难等缺点,Android 大版本6.0之后,HttpClient 就被完全移除了。现在官方建议使用 HttpURLConnection。

流程
URL lURL = new URL("https://www.baidu.com/");//请求 url
lHttpURLConnection = (HttpURLConnection) lURL.openConnection();
lHttpURLConnection.setRequestMethod("GET");//请求方法,       HttpURLConnection 默认请求方式即为 GET 请求,所以本句可省略
lHttpURLConnection.setConnectTimeout(8000);//与服务器建立连接超时设置
lHttpURLConnection.setReadTimeout(8000);//与服务器传递数据的超时设置
InputStream lInputStream = lHttpURLConnection.getInputStream();
lHttpURLConnection.disconnect();
示例
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
         package="com.ginkwang.networktest">
​
   <uses-permission android:name="android.permission.INTERNET"/>
​
   <application
       android:allowBackup="true"
       android:icon="@mipmap/ic_launcher"
       android:label="@string/app_name"
       android:supportsRtl="true"
       android:theme="@style/AppTheme">
       <activity android:name=".MainActivity">
           <intent-filter>
               <action android:name="android.intent.action.MAIN"/>
​
               <category android:name="android.intent.category.LAUNCHER"/>
           </intent-filter>
       </activity>
   </application>
​
</manifest>
public class MainActivity extends AppCompatActivity {
​
   private Button mBtnSendRequest;
   private TextView mTvResponseTxt;
​
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       initView();
   }
​
   private void initView() {
       mBtnSendRequest = (Button) findViewById(R.id.btn_send_request);
       mBtnSendRequest.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               sendRequestWithHttpURLConnection();
           }
       });
​
       mTvResponseTxt = (TextView) findViewById(R.id.tv_response_txt);
   }
​
   private void sendRequestWithHttpURLConnection() {
       //开启线程发起请求
       new Thread(new Runnable() {
           @Override
           public void run() {
               HttpURLConnection lHttpURLConnection = null;
               BufferedReader lBufferedReader = null;
               try {
                   URL lURL = new URL("https://www.baidu.com/");//请求 url
                   lHttpURLConnection = (HttpURLConnection) lURL.openConnection();
                   lHttpURLConnection.setRequestMethod("GET");//请求方法,HttpURLConnection 默认请求方式即为 GET 请求,所以本句可省略
                   lHttpURLConnection.setConnectTimeout(8000);//与服务器建立连接超时设置
                   lHttpURLConnection.setReadTimeout(8000);//与服务器传递数据的超时设置
​
                   InputStream lInputStream = lHttpURLConnection.getInputStream();
                   //读取获取到的输入流
                   lBufferedReader = new BufferedReader(new InputStreamReader(lInputStream));
                   StringBuilder lStringBuilder = new StringBuilder();
                   String line = "";
                   while ((line = lBufferedReader.readLine()) != null) {
                       lStringBuilder.append(line);
                   }
                   showResponse(lStringBuilder.toString());
               } catch (Exception pE) {
                   pE.printStackTrace();
               } finally {
                   if (lBufferedReader != null) {
                       try {
                           lBufferedReader.close();
                       } catch (IOException pE) {
                           pE.printStackTrace();
                       }
                   }
​
                   if (lHttpURLConnection != null) {
                       lHttpURLConnection.disconnect();
                   }
               }
           }
       }).start();
   }
​
   private void showResponse(final String result) {
       runOnUiThread(new Runnable() {
           @Override
           public void run() {
               // 线程切回到主线程,进行 UI 更新操作
               mTvResponseTxt.setText(result);
           }
       });
   }
}
<uses-permission android:name="android.permission.INTERNET"/>
效果

HttpURLConnection 参数详解

基于 HttpURLConnection 的 HTTP 请求封装

直接上代码

/**
 * 网络请求类
 * Created by Wang-gk on 2017/5/2.
 */
public class NetworkHandler {
​
   private static final String TAG = "NetworkHandler";
   private static final int TIMEOUT = 15000;//超时设置
​
   /**
     * 请求参数格式转换
     * @param pMap 请求参数
     * @return
     */
   private static String prepareParam(Map<String, Object> pMap) {
       StringBuffer lStringBuffer = new StringBuffer();
       if (pMap.isEmpty()) {
           return "";
       } else {
           for (String key : pMap.keySet()) {
               String value = (String) pMap.get(key);
               if (lStringBuffer.length() < 1) {
                   lStringBuffer.append(key).append("=").append(value);
               } else {
                   lStringBuffer.append("&").append(key).append("=").append(value);
               }
           }
       }
       return lStringBuffer.toString();
   }
​
   /**
     * Get 请求
     * @param pUrl 请求地址
     * @param pParamMap 请求参数
     * @param pListener 接口回调
     */
   public static void doGet(String pUrl, Map<String, Object> pParamMap, NetworkCallbackListener pListener) {
       HttpURLConnection lHttpURLConnection = null;
       BufferedReader lBufferedReader = null;
       if (pParamMap != null && pParamMap.size() > 0) {
           pUrl += prepareParam(pParamMap);
       }
       try {
           URL lURL = new URL(pUrl);
           lHttpURLConnection = (HttpURLConnection) lURL.openConnection();//初始化 HttpURLConnection
           lHttpURLConnection.setRequestMethod("GET");//设置请求方法
           lHttpURLConnection.setDoOutput(false);//设置是否向connection输出, get请求用不到 lHttpURLConnection.getOutputStream(),因为参数直接追加在地址后面,因此默认是false
           lHttpURLConnection.setDoInput(true);// 设置是否从 HttpUrlConnection 读入,默认情况下是 true;指示应用程序要从 URL 连接读取数据。
           lHttpURLConnection.setConnectTimeout(TIMEOUT);//与服务器建立连接超时设置
           lHttpURLConnection.setReadTimeout(TIMEOUT);//与服务器传递数据的超时设置
           lHttpURLConnection.setInstanceFollowRedirects(true);//设置本次连接是否自动重定向
           lHttpURLConnection.setRequestProperty("Content-Type","text/html; charset=UTF-8");//设置头信息,如格式等,一般不设置,有默认设置
           lHttpURLConnection.connect();//不必要调用connect方法(调用也无妨),实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
           InputStream lInputStream = lHttpURLConnection.getInputStream();
           //读取获取到的输入流
           lBufferedReader = new BufferedReader(new InputStreamReader(lInputStream));
           StringBuilder lStringBuilder = new StringBuilder();
           String line = "";
           while ((line = lBufferedReader.readLine()) != null) {
               lStringBuilder.append(line);
           }
           Log.i(TAG, "doGet: output <<< " + lStringBuilder.toString());
           if (pListener != null) {
               pListener.onFinish(lStringBuilder.toString());
           }
       } catch (Exception pE) {
           if (pListener != null) {
               pListener.onError(pE);
           }
       } finally {
           if (lHttpURLConnection != null) {
               lHttpURLConnection.disconnect();
           }
​
           if (lBufferedReader != null) {
               try {
                   lBufferedReader.close();
               } catch (IOException pE) {
                   pE.printStackTrace();
               }
           }
       }
   }
​
   /**
     * Post 请求
     * @param pUrl 请求地址
     * @param pParamMap 请求参数
     * @param pListener 接口回调
     */
   public static void doPost(String pUrl, Map<String, Object> pParamMap, NetworkCallbackListener pListener) {
       HttpURLConnection lHttpURLConnection = null;
       BufferedReader lBufferedReader = null;
       try {
           URL lURL = new URL(pUrl);
           lHttpURLConnection = (HttpURLConnection) lURL.openConnection();//初始化 HttpURLConnection
           lHttpURLConnection.setRequestMethod("POST");//设置请求方法
           lHttpURLConnection.setDoOutput(true);//设置是否向connection输出,因为这个是 post 请求,参数要放在 http 正文内,因此需要设为 true
           lHttpURLConnection.setDoInput(true);// 设置是否从 HttpUrlConnection 读入,默认情况下是 true;指示应用程序要从 URL 连接读取数据。
           lHttpURLConnection.setConnectTimeout(TIMEOUT);//与服务器建立连接超时设置
           lHttpURLConnection.setReadTimeout(TIMEOUT);//与服务器传递数据的超时设置
           lHttpURLConnection.setInstanceFollowRedirects(true);//设置本次连接是否自动重定向
           lHttpURLConnection.setRequestProperty("Content-Type","text/html; charset=UTF-8");//设置头信息,如格式等,一般不设置,有默认设置
           lHttpURLConnection.connect();//不必要调用connect方法(调用也无妨),实际上只是建立了一个与服务器的tcp连接,并没有实际发送http请求。无论是post还是get,http请求实际上直到HttpURLConnection的getInputStream()这个函数里面才正式发送出去。
           InputStream lInputStream = lHttpURLConnection.getInputStream();
           //读取获取到的输入流
           lBufferedReader = new BufferedReader(new InputStreamReader(lInputStream));
           StringBuilder lStringBuilder = new StringBuilder();
           String line = "";
           while ((line = lBufferedReader.readLine()) != null) {
               lStringBuilder.append(line);
           }
           Log.i(TAG, "doPost: output <<< " + lStringBuilder.toString());
           if (pListener != null) {
               pListener.onFinish(lStringBuilder.toString());
           }
       } catch (Exception pE) {
           if (pListener != null) {
               pListener.onError(pE);
           }
       } finally {
           if (lHttpURLConnection != null) {
               lHttpURLConnection.disconnect();
           }
​
           if (lBufferedReader != null) {
               try {
                   lBufferedReader.close();
               } catch (IOException pE) {
                   pE.printStackTrace();
               }
           }
       }
   }
}

其中,网络请求的回调操作也封装在内。主要就是交易完成 onFinish() 和 onError() 两个回调方法,在接口回调类 NetworkCallbackListener 中定义

/**
 * 网络处理接口
 * Created by Wang-gk on 2017/5/4.
 */
public interface NetworkCallbackListener {
    void onFinish(String pResponse);
    void onError(Exception pE);
}

参考

上一篇 下一篇

猜你喜欢

热点阅读