本章寫一個程式用來讀取網狀圖片的功能,實現一個功能讀取到伺服器上的一張圖片,然後下載到本地的程式本程式使用多線程來讀取網狀圖片,包括自動判斷快取檔案,還有進度條。別的不多說,上內容,我把實現過程都當做注釋寫到程式裡了,很完全。希望對初學的朋友有協助!
1、讀取進度條的效果
2、成功讀取到圖片的效果
1.首先是Activity
package cn.itcast.pic;import android.app.Activity;import android.app.ProgressDialog;import android.graphics.Bitmap;import android.os.Bundle;import android.os.Handler;import android.view.View;import android.widget.ImageView;import android.widget.TextView;import android.widget.Toast;public class mainActivity extends Activity { private TextView addressET; private ImageView imageIV; private Handler handler=new Handler(); //在主線程中建立handler private ProgressDialog dialog; private ImageService service; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); //1、擷取對話方塊的id addressET = (TextView) this.findViewById(R.id.addressET); imageIV = (ImageView) this.findViewById(R.id.imageIV); service = new ImageService(this); } public void onClick(View v){ //把圖片放在一個新的線程裡面來讀取. new Thread(){//建立一個新的線程 public void run(){ try { String address = addressET.getText().toString(); handler.post(new Runnable() {//此處用一個匿名內部類,runnable自動把訊息發送給主線程建立處理的handler,主線程會自動更新。 public void run() { dialog=new ProgressDialog(mainActivity.this); dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//設定進度條樣式 dialog.setMessage("請稍候..."); dialog.setCancelable(false);//判斷是否取消進度條 dialog.show(); } }); //由於網路操作比較耗時,所以在新線程中操作 final Bitmap image = service.getImage(address); handler.post(new Runnable() { public void run() { dialog.dismiss(); imageIV.setImageBitmap(image);//新線程更新介面,需要使用handler } }); } catch (Exception e) { e.printStackTrace(); Toast.makeText(getApplicationContext(), "伺服器忙,請稍後再試!", 0).show(); } } }.start(); }}
2.然後是讀取圖片的service
package cn.itcast.pic;import java.io.File;import java.io.FileOutputStream;import java.net.HttpURLConnection;import java.net.URL;import java.net.URLEncoder;import android.accounts.NetworkErrorException;import android.content.Context;import android.graphics.Bitmap;import android.graphics.Bitmap.CompressFormat;import android.graphics.BitmapFactory;public class ImageService { private Context context; public ImageService(Context context) { super(); this.context = context; } public Bitmap getImage(String address) throws Exception { // 1.通過Url對象封裝url對象 URL url = new URL(address); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setReadTimeout(3000); // 2.判斷是否有快取檔案 File cacheFile = new File(context.getCacheDir(), URLEncoder.encode(address));// 快取檔案 if (cacheFile.exists())// 判斷是否有緩衝 conn.setIfModifiedSince(cacheFile.lastModified());// 發送快取檔案的最後修改時間 // 3.擷取狀態代碼,根據狀態嗎來判斷接下來的操作。讀取檔案?還是寫緩衝,寫緩衝的時候記著用多個線程 int code = conn.getResponseCode(); if (code == 200) { byte[] data = Util.read(conn.getInputStream()); Bitmap bm = BitmapFactory.decodeByteArray(data, 0, data.length);// 轉化為圖片 weiteCache(cacheFile, bm); return bm; } else if(code==304){ return BitmapFactory.decodeFile(cacheFile.getAbsolutePath());//讀取本機資料,並轉為圖片來顯示 } // 如果不成功,拋異常,給我們自己看的 throw new NetworkErrorException("訪問伺服器出錯:"+code); } // 4. 寫快取檔案 private void weiteCache(final File cacheFile, final Bitmap bm) { // 使用一個新的線程來寫,這樣的好處就是在頁面開啟的時候不會因為寫緩衝而等待時間 new Thread() { public void run() { try { FileOutputStream fos = new FileOutputStream(cacheFile); bm.compress(CompressFormat.JPEG, 100, fos);//指定格式 儲存到本地 fos.close(); } catch (Exception e) { throw new RuntimeException(e); } } }.start(); }}
3.讀取網路檔案的一個工具類
package cn.itcast.pic;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;public class Util { public static byte[] read(InputStream in) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len; while ((len = in.read(buffer)) != -1) baos.write(buffer, 0, len); baos.close(); byte[] data = baos.toByteArray(); return data; } }
4.主介面XML
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" > <EditText android:id="@+id/addressET" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:inputType="textEmailAddress" > <requestFocus /> </EditText> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:onClick="onClick" android:text=" GO " /> </LinearLayout> <ImageView android:id="@+id/imageIV" android:layout_width="wrap_content" android:layout_height="wrap_content" /></LinearLayout>