Android網路編程 HttpUrlConnection HttpClient AsyncTask

來源:互聯網
上載者:User

標籤:android   asynctask   httpurl   

前面幾篇文章介紹了Android中常用的http架構:volley,所謂架構者無非就是對我們所需的一系列操作進行了封裝,簡化了我們的工作。
但萬變不離其宗,我們還是需要掌握Android原生的網路操作類,所以這篇文章主要介紹這兩個類,
HTTPUrlConnection HTTPClient,以及常需要用到的AsyncTask.

本文代碼github地址:UseAsyncTask

1,HttpUrlConnection

一個UrlConnection常用來通過網路發送和擷取資料,資料可以使任何類型任何長度,HttpUrlConnection通常用於發送和接收長度未知的流資料;

  1. 建立HttpURLConnection:通過調用Url.openConnection()並將其類型轉換為HttpUrlConnection
  2. 建立Request:要包含最基本的Url,你可以佈建要求頭部(請求資料類型,長度等)
  3. 佈建要求主體(body):這不是必須的,如果需要設定,確保setOutput(true);
  4. 讀取Response:返迴響應,頭部包含資料類型,長度等資料,可以通過getInputStream()讀取響應資料的主體(body),如果沒有Response沒有body,則返回一個Empty Stream
  5. 中斷連線:調用HttpUrlConnection的disconnect()方法

使用HttpUrlConnection的一個簡單樣本:從遠程擷取圖片並顯示在ImageView中

ImageView imageView=(ImageView).findViewById(R.id.imageview);URL url=new URL(http://www.jycoder.com/json/movies/1.jpg);    HttpUrlConnection conn= (HttpUrlConnection) url.openConnection();conn.connect();try{    InputStream in=conn.getInputStream();    //將擷取到的圖片顯示在ImageView中    Bitmap bitmap=BitmapFactory.decodeStream(in);    imageView.setImageBitmap(BitmapFactory.decode(is));    }    finally{        conn.disconnect();    }

上面就是HttpUrlConnection的基本用法,還有些需要掌握的主題:

  1. Http Response錯誤:有時候響應錯誤或者異常,直接getInputStream()就會拋出異常,我們可以通過getErrorStream();讀取Response錯誤資訊,getHeaderFields()讀取回應標頭部;
  2. Post Content:發送資料到伺服器,首先需要setOutput(true);為了效能,如果你知道你所Post內容的大小,你可以使用setFixedLengthStreamingMode(int),如果不知道,可以使用setChunkedStreamingMode(int);
  3. HTTP Method:可以通過setRequestMethod(String)設定
  4. Cookie和Cache:HttpUrlConnection擁有CookieManager和CookieHandler方法來設定Cookie,對於Cache提供了HttpResponseCache類;關於這部分參考資料:HttpUrlConnection
    HttpResponseCache
2,HttpClient

Android 官方在API 22之後已經棄用,盡量使用HttpUrlConnection

3,AsyncTask

AsyncTask是實現非同步作業的一種機制,我們常常需要更新UI,但主線程不能執行耗時操作,否則會引發錯誤;AsyncTask用於執行後台操作,無需手動處理線程的建立和執行;它常用來處理一些短時操作,如果長時間操作考慮使用Service

AsyncTask的使用:

  1. 建立一個Task:我們需要建立一個Task繼承自AsyncTask,

    1. AsyncTask中需要三個參數Params,Progress,Result:
      1. Params 代表task執行時需要傳給的參數:new MyTask.execute(Params);
      2. Progress 代表任務內需要傳遞的任務進度,與之相關的方法是publisProgress()和onUpdateProgress()
      3. Result 代表最終Task執行完我們所得到的結果
    2. 我們還需要覆寫AsyncTask中的四個方法:
      1. onPreExecute() Task執行前調用,在主線程(UI線程)中運行,進行諸如建立最初的進度條視圖之類的工作
      2. doInBackground() 後台線程中運行,擷取網路資料等耗時操作都在這裡進行
      3. onUpdateProgress() 主線程中運行,用於更新進度,在doInBackground()方法中調用publishProgress()方法時回調。
      4. onPostExecute() 主線程中運行,當task完成時調用,

    Tips:可以看到AsyncTask中的四個方法只有doInBackground()實在後台線程中啟動並執行,因此在它裡面執行一些耗時操作,而其它方法運行在UI線程,執行更新UI視圖等操作。

  2. 在主線程中執行Task:必須在主線程中執行個體化和執行AsyncTask,而且每個AsyncTask只執行一次
  3. 取消一個Task:AsyncTask可以在任何時候通過調用cancel(true)取消。

綜合以上我們來做個練習:

  1. 建立項目:UseAsyncTask
  2. Manifest.xml中添加連網許可權

  3. 建立布局,我們這裡用來顯示一張電影圖片,

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"        xmlns:tools="http://schemas.android.com/tools"        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <TextView            android:text="豆瓣電影Top10"            android:background="#1C9439"            android:textSize="24sp"            android:textColor="#fff"            android:layout_marginTop="5dp"            android:layout_marginBottom="10dp"            android:gravity="center"            android:layout_marginLeft="10dp"            android:layout_marginRight="10dp"            android:layout_width="match_parent"            android:layout_height="wrap_content"/>        <ImageView            android:id="@+id/movie_image"            android:layout_gravity="center"            android:background="#ffcc"            android:layout_margin="3dp"            android:layout_width="wrap_content"            android:layout_height="wrap_content"/>    </LinearLayout>
  1. 完成MainActivity
public class MainActivity extends ActionBarActivity {    private ImageView imageView;    //圖片地址    private final String url="http://www.jycoder.com/json/movies/2.jpg";    //顯示進度    private ProgressDialog pDialog;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //用來顯示進度        pDialog=new ProgressDialog(this);            pDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);        pDialog.setMessage("Loading...");        pDialog.setMax(100);        imageView= (ImageView) findViewById(R.id.movie_image);                //執行Task        new ImageDownloadTask().execute(url);   }   public class ImageDownloadTask extends AsyncTask<String,Integer,Bitmap>{       @Override       protected void onPreExecute() {           super.onPreExecute();           pDialog.show();       }       @Override       protected Bitmap doInBackground(String... urls) {           HttpURLConnection connection = null;           Bitmap bitmap=null;           try {               URL url=new URL(urls[0]);               connection= (HttpURLConnection) url.openConnection();               InputStream in= new BufferedInputStream(connection.getInputStream());               bitmap= BitmapFactory.decodeStream(in);                    //擷取檔案流大小,用於更新進度               int length=connection.getContentLength();               int len=0,total_length=0,value=0;               byte[] data=new byte[1024];               while((len = in.read(data)) != -1){                   total_length += len;                   value = (int)((total_length/(float)length)*100);                   //調用update函數,更新進度                   publishProgress(value);               }               } catch (IOException e) {                    e.printStackTrace();            }finally {                   if (connection!=null)                    connection.disconnect();            }            return bitmap;        }       @Override       protected void onProgressUpdate(Integer... values) {            super.onProgressUpdate(values);            pDialog.setProgress(values[0]);        }        @Override        protected void onPostExecute(Bitmap bitmap) {            if(pDialog!=null)                pDialog.dismiss();            pDialog = null;            //將Bitmap填充進Imageview            imageView.setImageBitmap(bitmap);        }    }}   
總結:

這部分內容很簡單吧~,其實這部分難的就是我們需要理解UI線程,以及瞭解AsyncTask與Service的適用情境。

參考資料:Android AsyncTask

  • 微博: @明桑Android黑曆史
  • 郵箱: <[email protected]>
  • 個人首頁: 明桑戰勝Android汪的黑曆史

Android網路編程 HttpUrlConnection HttpClient AsyncTask

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.