1. 程式人生 > >Android使用HttpUrlConnection來實現網路請求,親測有效

Android使用HttpUrlConnection來實現網路請求,親測有效

產品提出需求,需要再視訊播放完畢後把當前的播放位置上傳給伺服器。作為一名不愛造輪子的程式設計師,我果斷的使用了三方的視屏播放器,以module依賴的形式匯入到了工程,也由此產生了一個問題,三方module沒有Application的,也就無法進行整合OkGo來進行簡單的網路請求了。這裡插入一句,在主module裡通過呼叫輔助module的方法來給三方實現okGo的初始化為什麼不可以呢?

迴歸正題,於是我就在三方的視訊回退操作中用原生的網路請求了,程式碼如下(原生的網路請求必須開啟子執行緒):

new Thread(new Runnable() {
    @Override
public void 
run() { //自己寫一個HttpUrlConnection發起網路請求 String urlPath = new String("http://47.104.108.249:8081/api/edu/mmtb/app/res/multi_media_record/"); JSONObject jsonObject=new JSONObject(); try { jsonObject.put("resMultiMediaId",1); jsonObject.put("record","10000"); } catch
(JSONException e) { e.printStackTrace(); } //建立連線f URL url = null; try { url = new URL(urlPath); } catch (MalformedURLException e) { e.printStackTrace(); } HttpURLConnection httpConn = null; try { httpConn = (HttpURLConnection) url.openConnection(); } catch
(IOException e) { e.printStackTrace(); } //設定連線超時,2000ms httpConn.setConnectTimeout(2000); //設定指定時間內伺服器沒有返回資料的超時,5000ms httpConn.setReadTimeout(5000); //設定引數 httpConn.setDoOutput(true); //需要輸出 httpConn.setDoInput(true); //需要輸入 httpConn.setUseCaches(false); //不允許快取 try { httpConn.setRequestMethod("POST"); //設定POST方式連線 } catch (ProtocolException e) { e.printStackTrace(); } //設定請求屬性,給請求頭新增東西 httpConn.setRequestProperty("Content-Type", "application/json;charset=UTF-8"); httpConn.setRequestProperty("accept", "application/json"); httpConn.setRequestProperty("Connection", "Keep-Alive");// 維持長連線 httpConn.setRequestProperty("Charset", "UTF-8"); httpConn.setRequestProperty("token", "VjJaMzQxcE9ENjkJMDAwMDYJOHhkTAloZWp1bi5lZHUuYXBwMTUyNDc5NzEwNQ=="); //建立輸入流,向指向的URL傳入引數 DataOutputStream dos = null; try { dos = new DataOutputStream(httpConn.getOutputStream()); } catch (IOException e) { e.printStackTrace(); } try { dos.writeBytes(String.valueOf(jsonObject)); } catch (IOException e) { e.printStackTrace(); } try { dos.flush(); } catch (IOException e) { e.printStackTrace(); } try { dos.close(); } catch (IOException e) { e.printStackTrace(); } //獲得響應狀態 //獲得響應狀態 int resultCode = 0; try { resultCode = httpConn.getResponseCode(); } catch (IOException e) { e.printStackTrace(); } if (HttpURLConnection.HTTP_OK == resultCode) { StringBuffer sb = new StringBuffer(); String readLine = new String(); BufferedReader responseReader = null; try { responseReader = new BufferedReader(new InputStreamReader(httpConn.getInputStream(), "UTF-8")); } catch (IOException e) { e.printStackTrace(); } try { while ((readLine = responseReader.readLine()) != null) { sb.append(readLine).append("\n"); } } catch (IOException e) { e.printStackTrace(); } try { responseReader.close(); } catch (IOException e) { e.printStackTrace(); } Log.i("zhangjiaren", sb.toString()); } } }).start();

因為後臺需要以json的形式來上傳資料,幸好我經常用JsonObject和JsonArray,拼一個傳過去就可以了。當然,前提是已經成功的連結上了伺服器,再把拼接好的json字串通過io流的方式傳輸過去,並且以位元組流的形式,即二進位制,很明顯,這樣是為了保證資料不會解析錯誤。以上就是“Android使用HttpUrlConnection來實現網路請求”了。

最後說一句,後來題主靈機一動,想想EventBus是線上程間進行操作的,兩個module的主執行緒應該是一樣的,為何不試試呢?於是果然不出所料,EventBus也是可以的。程式碼如下:

VideoEvents videoEvents = new VideoEvents().setType(VideoEvents.VE_SURFACEHOLDER_FINISH_FULLSCREEN);
videoEvents.duration=currentPosition;
videoEvents.obj = CURRENT_STATE;
EventBus.getDefault().post(videoEvents);

上面的是傳送訊息的,下面的是接收資料後的處理:

public void onEventMainThread(VideoEvents videoEvents) {
        if (videoEvents.type == VideoEvents.VE_SURFACEHOLDER_FINISH_FULLSCREEN) {
            Log.i("zhangjiaren","wa,amazing");
            String position=String.valueOf(videoEvents.duration);
            Map<String, String> map = new HashMap<>();
            map.put("resMultiMediaId","1");
            map.put("record",position);
            JSONObject jsonObject=new JSONObject(map);
            OkGo.<String>post(Constants.POST_MEDIA_POINT)
                    .headers("token", SPUtil.DEFAULT.getString("token",""))
                    .upJson(jsonObject)
                    .execute(new com.lzy.okgo.callback.StringCallback() {
                        @Override
public void onSuccess(Response<String> response) {
                            //拉取書本資訊成功,進行資料繫結
Log.i("zhangjiaren",response.body());
                            if (200==response.code()){
                                try {
//                                    parserData(response.body());
} catch (Exception e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                        @Override
public void onError(Response<String> response) {
                            Log.i("zhangjiaren","拉取書本資訊請求出錯了");
                        }
                    });
        }
    }
ok,寫一下,兩年後又需要用到HttpUrlConnection時候,可以15分鐘搞定了。