Android讀取網狀圖片,
本文是自己學習所做筆記,歡迎轉載,但請註明出處:http://blog.csdn.net/jesson20121020
在android4.0之後,已不允許在主線程中進行網路請求操作了, 否則會出現NetworkOnMainThreadException異常。而為瞭解決在android4.0之上可以進行網路的請求,可以有兩種方法來解決,以讀取網路的圖片為例,先看:
當點擊按鈕時,會將指定地址的網狀圖片載入在imageVIew中進行顯示。
讀取網狀圖片: 1. 獲得指定地址網狀圖片資料
有兩種方式將指定地址的網路讀取到Bitmap中,然後通過imageView載入顯示。
1). 將輸入資料流解碼成Bitmap
private static String path = "http://221.203.108.70:8080/jxzy/UploadFiles_4517/201005/2010052615165701.jpg";
public Bitmap getData(){Bitmap bitmap = null;try {URL url = new URL(path);URLConnection conn = url.openConnection();conn.connect();InputStream is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is);} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return bitmap;} 2). 通過位元組資料將輸入資料流寫入到輸入資料流中,並通過BitmapFactory.decodeByteArray()方法將其轉換成Bitmap
public Bitmap getData1(){Bitmap bitmap = null;ByteArrayOutputStream bos = null;try {URL url = new URL(path);URLConnection conn = url.openConnection();InputStream is = conn.getInputStream();bos = new ByteArrayOutputStream();byte[] data = new byte[1024];int len = 0;while((len = is.read(data))!= -1){bos.write(data, 0, len);}byte[] data1 = bos.toByteArray();bitmap = BitmapFactory.decodeByteArray(bos.toByteArray(), 0, data1.length);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}return bitmap;}
2. 將得到的Bitmap裝載在imageView中顯示。
開始也提到了,在android4.0之上不就不能在主線程中直接進行網路請求等操作了,因此為了將網狀圖片載入到ImageView中,也有兩種方法,具體如下:
方法1:不建立線程;
直接在onCreate()方法中加入以下兩行代碼,然後直接在主線程中進行讀取網狀圖片的操作。
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder().detectDiskReads().detectDiskWrites().detectNetwork().penaltyLog().build());StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder().detectLeakedSqlLiteObjects().detectLeakedClosableObjects().penaltyLog().penaltyDeath().build());
有了這兩行代碼,當然了,這些只適用android4.0之上,你如果targetSDK在4.0之下,也可以不加這兩行代碼,直接在主線程中進行讀取網狀圖片的操作,但是這種方法並不推薦。
接下來就是將第一步兩種方法得到Bitmap載入到imageView中,主要代碼如下:
imageView = (ImageView)findViewById(R.id.imageView);button = (Button)findViewById(R.id.button);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubimageView.setImageBitmap(getData());}});
方法2: 利用Thread+Handler
因為,android也不允許在非UI線程中更新UI,所以不能直接將imageView.setImageBitmap()寫線上程中,這就要藉助於Handler了,因為Handler是運行在主線程中的,所以在讀取網路資料利用Message訊息來通知Handler來通知更新UI。主要代碼如下:
Handler handler = new Handler(){public void handleMessage(Message msg) {if(msg.what == 1){imageView.setImageBitmap(mBitmap);}};};Runnable runnable = new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubMessage msg = new Message();msg.what = 1;//mBitmap = getData();mBitmap = getData1();handler.sendMessage(msg);}}; 接下來,就是在按鈕的單擊事件中建立一個線程並啟動即可。
button = (Button)findViewById(R.id.button);button.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubnew Thread(runnable).start();}});
最後,給出布局檔案,如下:
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" ><Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="讀取網狀圖片" /> <ImageView android:id="@+id/imageView" android:layout_width="match_parent" android:layout_height="wrap_content" /></RelativeLayout>