Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android AsynTask處理返回數據和AsynTask使用get,post請求

android AsynTask處理返回數據和AsynTask使用get,post請求

編輯:關於Android編程

Android是一個單線程模型,Android界面(UI)的繪制都只能在主線程中進行,如果在主線程中進行耗時的操作,就會影響UI的繪制和事件的響應。所以在android規定,不可在主線中進行耗時操作,否則將發生程序無響應(ANR)問題。

解決辦法:開啟新的線程進行耗時操作

開啟新的線程可以new Thread() 或實現Runnable接口

什麼要使用AsyncTask呢?

如果是使用Thread的run()方法,run()結束之後沒有返回值。所以必須要自己建立通信機制

AsyncTask將所有的線程通信都封裝成回調函數,調用邏輯容易書寫。尤其是在異步處理結束之後,有回調函數進行收尾處理。咳咳,程序員都懶的麼

Android給我們提供的一個輕量級的用於處理異步任務的類:AsyncTask   當然是那個簡單就用那個咯

最後還有一點就是:Android 4.0後禁止在UI線程中執行網絡操作~不然會報:android.os.NetworkOnMainThreadException

什麼是AsyncTask(原諒寶寶偷的圖   嘿嘿  不過真的解釋的很清楚呢)

注意:

 Task的實例必須在UI Thread中創建

 execute方法不惜在UI thread中創建

 task只能被執行一次 多次調用時會出現異常

通用AsyncTask 以及在主線程中使用網絡請求回返的數據

   通用AsyncTask是什麼意思呢 發送不同的請求返回不同類型的數據 難道要一個類型寫個AsyncTask 豈不是麻煩死咯

   還有一種情況  我們通過異步任務得到了一個對象然後在一下行立刻使用這個對象邏輯完全沒問題但是運行之後會報空指針異常。這是怎麼回事呢?       

   AsycnTask開始了一個新的線程,但是主線程並沒有停止還在繼續運行,馬上就使用這個對象,而你新開的線程可能正在訪問網絡這個對象為空

   你無法確定AsycnTask什麼時候才能獲取到數據,網快嗖的一下就好了,網慢就要等好久。

看一個簡略的小例子

首先呢  我們使用異步任務的時候要處理不同類型的數據把這個Http設置泛型類第三個參數返回值類型設置為泛型不管你是什麼類型的數據全部ok

我又寫了一個接口作為Http的屬性  在onPostExecute方法調用其中的onResponse方法在Test中實現接口

這個接口的作用完全可以理解為一個監聽事件 checkbox的改變監聽觸發條件是 是否選中這個接口監聽是否有數據  完成網絡訪問有數據的時候就調用

我們在主線程中完成接口的實現已經在主線程中實現了返回來的數據還不是任君宰割阿~~~~~

 public class Http<T> extends AsyncTask<String,Void,T> {
 private OnResponseListener<T> listener;
 public void setListener(OnResponseListener<T> listener) {
 this.listener = listener;
 }
 @Override
 protected T doInBackground(String... params) {
 return null;
 }
 @Override
 protected void onPostExecute(T t) {
 super.onPostExecute(t);
 if (listener!=null){
  listener.onResponse(t);
 }
 }
 //接口 類似一個監聽事件
 public interface OnResponseListener<T>{
 void onResponse(T t);
 }
}
//獲取數據的測試類
public class Test {
 //要獲取的user對象
 private User user1=null;
 public void get(){
 //創建網絡訪問實例
 Http<User> http=new Http<User>();
 //重寫接口
 http.setListener(new Http.OnResponseListener<User>() {
  @Override
  public void onResponse(User user) {
  user1=user;
  }
 });
 http.execute("xxx.balabala.com");
 }
}

在發送請求的時候很容易就帶個參數,請求的方式呢 無非就是get,post 兩者的區別呢大白話的說get不安全參數通過url直接傳過去post安全參數加密一下子

下面貼一下AsyncTask在get和post請求時核心代碼doInBackground方法

GET

protected T doInBackground(String... params) {
 //網絡連接對象
 HttpURLConnection connection=null;
 //輸入流 獲取網絡數據
 InputStream is=null;
 //字節數組輸出流
 ByteArrayOutputStream bos=null;
 try {
  //獲取網絡連接對象
  connection=(HttpURLConnection) new URL(params[0]).openConnection();
  //設置get請求 必須大寫
  connection.setRequestMethod("GET");
  //獲取網絡請求碼 200 400 500之類 不懂百度
  int code=connection.getResponseCode();
  if(code==200){
  //獲取流
  is=connection.getInputStream();
  //臨時字節數組
  byte [] b=new byte[1024];
  int len=-1;
  bos=new ByteArrayOutputStream();
  while ((len=is.read(b))!=-1){
   //寫入數據
   bos.write(b,0,len);
  }
  String json=bos.toString("utf-8");
  T t=JSON.parseObject(json,type);
  return t;
  }else{
  Log.e("error","網絡訪問失敗==========="+code);
  }
 } catch (IOException e) {
  e.printStackTrace();
 }finally {
  try {
  if (bos!=null){
   bos.close();
  }
  if (is!=null){
   is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  if (connection!=null){
  connection.disconnect();
  }
 }
 return null;
 }

POST

post和get的區別  就是post多了一段處理參數的代碼

protected T doInBackground(String... params) {
 //分割url 分為地址和參數兩部分
 String[] strArr=params[0].split("\\?");
 HttpURLConnection connection=null;
 //輸出流
 OutputStream os=null;
 //輸入流
 InputStream is=null;
 ByteArrayOutputStream bos=null;
 try {
  connection=(HttpURLConnection) new URL(strArr[0]).openConnection();
  connection.setRequestMethod("POST");
  //設置允許輸入 輸出 默認值true 不寫也可以
  connection.setDoOutput(true);
  connection.setDoInput(true);
  os=connection.getOutputStream();
  //把參數寫入
  os.write(strArr[1].getBytes("utf-8"));
  os.close();
  int code=connection.getResponseCode();
  if(code==200){
  is=connection.getInputStream();
  byte [] b=new byte[1024];
  int len=-1;
  bos=new ByteArrayOutputStream();
  while ((len=is.read(b))!=-1){
   bos.write(b,0,len);
  }
  String json=bos.toString("utf-8");
  T t=JSON.parseObject(json,type);
  return t;
  }else{
  Log.e("error","網絡訪問失敗==========="+code);
  }
 } catch (IOException e) {
  e.printStackTrace();
 }finally {
  try {
  if (bos!=null){
   bos.close();
  }
  if (is!=null){
   is.close();
  }
  } catch (IOException e) {
  e.printStackTrace();
  }
  if (connection!=null){
  connection.disconnect();
  }
 }
 return null;
 }

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持本站!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved