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

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

編輯:關於android開發

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



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