Android TextView 顯示HTML加圖片

TextView顯示網絡圖片,我用android2.3的系統,可以顯示圖片出來,並且如果圖片比較大,應用會卡的現象,肯定是因為使用主線程去獲取網絡圖片造成的,但如果我用android4.0以上的系統運行,則不能顯示圖片,隻顯示小方框。

究其原因,是在4.0的系統上執行的時候報錯瞭,異常是:android.os.NetworkOnMainThreadException 經過查文檔,原來是4.0系統不允許主線程(UI線程)訪問網絡,因此導致瞭其異常。說白瞭就是在主線程上訪問網絡,會造成主線程掛起,系統不允許使用瞭。

 

此處有作部分修改,代碼獨立。圖片實現異步加載。解決上述問題

用法,調用代碼activity

 

[html]
//TextView 控件 
textViewContent = (TextView) getActivity().findViewById(R.id.textview_prodcut_detail_more_zp_content); 
//HTML文本 
zp_content = "測試圖片信息:<br><img src=\"http://b2c.zeeeda.com/upload/2013/05/10/136814766742544.jpg\" />"; 
//默認圖片,無圖片或沒加載完顯示此圖片 
Drawable defaultDrawable = MainActivity.ma.getResources().getDrawable(R.drawable.stub); 
//調用 
Spanned sp = Html.fromHtml(zp_content, new HtmlImageGetter(textViewContent, "/esun_msg", defaultDrawable), null); 
textViewContent.setText(sp); 

//TextView 控件
textViewContent = (TextView) getActivity().findViewById(R.id.textview_prodcut_detail_more_zp_content);
//HTML文本
zp_content = "測試圖片信息:<br><img src=\"http://b2c.zeeeda.com/upload/2013/05/10/136814766742544.jpg\" />";
//默認圖片,無圖片或沒加載完顯示此圖片
Drawable defaultDrawable = MainActivity.ma.getResources().getDrawable(R.drawable.stub);
//調用
Spanned sp = Html.fromHtml(zp_content, new HtmlImageGetter(textViewContent, "/esun_msg", defaultDrawable), null);
textViewContent.setText(sp);
HtmlImageGetter類[html]
mport java.io.InputStream; 
 
import android.graphics.Canvas; 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.AsyncTask; 
import android.os.Environment; 
import android.text.Html.ImageGetter; 
import android.util.Log; 
import android.widget.TextView; 
 
public class HtmlImageGetter implements ImageGetter{ 
    private TextView _htmlText; 
    private String _imgPath; 
    private Drawable _defaultDrawable; 
    private String TAG = "HtmlImageGetter"; 
  
    public HtmlImageGetter(TextView htmlText, String imgPath, Drawable defaultDrawable){ 
        _htmlText = htmlText; 
        _imgPath = imgPath; 
        _defaultDrawable = defaultDrawable; 
    } 
  
    @Override 
    public Drawable getDrawable(String imgUrl) { 
  
        String imgKey = String.valueOf(imgUrl.hashCode()); 
        String path = Environment.getExternalStorageDirectory() + _imgPath; 
        FileUtil.createPath(path); 
  
        String[] ss = imgUrl.split("\\."); 
        String imgX = ss[ss.length-1]; 
        imgKey = path+"/" + imgKey+"."+imgX; 
  
  
        if(FileUtil.exists(imgKey)){ 
            Drawable drawable = FileUtil.getImageDrawable(imgKey); 
            if(drawable != null){ 
                drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); 
                return drawable; 
            }else{ 
                Log.v(TAG,"load img:"+imgKey+":null"); 
            } 
        } 
  
        URLDrawable urlDrawable = new URLDrawable(_defaultDrawable); 
        new AsyncThread(urlDrawable).execute(imgKey, imgUrl); 
        return urlDrawable; 
    } 
  
    private class AsyncThread extends AsyncTask<String, Integer, Drawable> { 
        private String imgKey; 
        private URLDrawable _drawable; 
  
        public AsyncThread(URLDrawable drawable){ 
            _drawable = drawable; 
        } 
  
        @Override 
        protected Drawable doInBackground(String… strings) { 
            imgKey = strings[0]; 
            InputStream inps = NetWork.getInputStream(strings[1]); 
            if(inps == null) return _drawable; 
  
            FileUtil.saveFile(imgKey, inps); 
            Drawable drawable = Drawable.createFromPath(imgKey); 
            return drawable; 
        } 
  
        public void onProgressUpdate(Integer… value) { 
  
        } 
  
        @Override 
        protected void onPostExecute(Drawable result) { 
            _drawable.setDrawable(result); 
            _htmlText.setText(_htmlText.getText()); 
        } 
    } 
  
    public class URLDrawable extends BitmapDrawable { 
  
        private Drawable drawable; 
  
        public URLDrawable(Drawable defaultDraw){ 
            setDrawable(defaultDraw); 
        } 
  
        private void setDrawable(Drawable ndrawable){ 
            drawable = ndrawable; 
            drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable 
                    .getIntrinsicHeight()); 
            setBounds(0, 0, drawable.getIntrinsicWidth(), drawable 
                    .getIntrinsicHeight()); 
        } 
  
        @Override 
        public void draw(Canvas canvas) { 
            drawable.draw(canvas); 
        } 
    } 

mport java.io.InputStream;

import android.graphics.Canvas;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Environment;
import android.text.Html.ImageGetter;
import android.util.Log;
import android.widget.TextView;

public class HtmlImageGetter implements ImageGetter{
 private TextView _htmlText;
 private String _imgPath;
 private Drawable _defaultDrawable;
 private String TAG = "HtmlImageGetter";
 
 public HtmlImageGetter(TextView htmlText, String imgPath, Drawable defaultDrawable){
  _htmlText = htmlText;
  _imgPath = imgPath;
  _defaultDrawable = defaultDrawable;
 }
 
 @Override
 public Drawable getDrawable(String imgUrl) {
 
  String imgKey = String.valueOf(imgUrl.hashCode());
  String path = Environment.getExternalStorageDirectory() + _imgPath;
  FileUtil.createPath(path);
 
  String[] ss = imgUrl.split("\\.");
  String imgX = ss[ss.length-1];
  imgKey = path+"/" + imgKey+"."+imgX;
 
 
  if(FileUtil.exists(imgKey)){
   Drawable drawable = FileUtil.getImageDrawable(imgKey);
   if(drawable != null){
    drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
    return drawable;
   }else{
    Log.v(TAG,"load img:"+imgKey+":null");
   }
  }
 
  URLDrawable urlDrawable = new URLDrawable(_defaultDrawable);
  new AsyncThread(urlDrawable).execute(imgKey, imgUrl);
  return urlDrawable;
 }
 
 private class AsyncThread extends AsyncTask<String, Integer, Drawable> {
  private String imgKey;
  private URLDrawable _drawable;
 
  public AsyncThread(URLDrawable drawable){
   _drawable = drawable;
  }
 
  @Override
  protected Drawable doInBackground(String… strings) {
   imgKey = strings[0];
   InputStream inps = NetWork.getInputStream(strings[1]);
   if(inps == null) return _drawable;
 
   FileUtil.saveFile(imgKey, inps);
   Drawable drawable = Drawable.createFromPath(imgKey);
   return drawable;
  }
 
  public void onProgressUpdate(Integer… value) {
 
  }
 
  @Override
  protected void onPostExecute(Drawable result) {
   _drawable.setDrawable(result);
   _htmlText.setText(_htmlText.getText());
  }
 }
 
 public class URLDrawable extends BitmapDrawable {
 
  private Drawable drawable;
 
  public URLDrawable(Drawable defaultDraw){
   setDrawable(defaultDraw);
  }
 
  private void setDrawable(Drawable ndrawable){
   drawable = ndrawable;
   drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
     .getIntrinsicHeight());
   setBounds(0, 0, drawable.getIntrinsicWidth(), drawable
     .getIntrinsicHeight());
  }
 
  @Override
  public void draw(Canvas canvas) {
   drawable.draw(canvas);
  }
 }
}
NetWork 類[html] 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.PrintWriter; 
import java.net.HttpURLConnection; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.HashMap; 
import java.util.Iterator; 
import java.util.Map; 
import java.util.zip.GZIPInputStream; 
import java.util.zip.InflaterInputStream; 
 
import org.apache.http.HttpEntity; 
import org.apache.http.HttpResponse; 
import org.apache.http.client.HttpClient; 
import org.apache.http.client.methods.HttpGet; 
import org.apache.http.entity.BufferedHttpEntity; 
import org.apache.http.impl.client.DefaultHttpClient; 
 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.util.Log; 
 
 
 
 
public class NetWork { 
    private static String TAG = "NetWork"; 
     
    public static String getHttpData(String baseUrl){ 
        return getHttpData(baseUrl, "GET", "", null); 
    } 
  
    public static String postHttpData(String baseUrl, String reqData){ 
        return getHttpData(baseUrl, "POST", reqData, null); 
    } 
  
    public static String postHttpData(String baseUrl, String reqData, HashMap<String, String> propertys){ 
        return getHttpData(baseUrl, "POST", reqData, propertys); 
    } 
  
    /** 
     * 獲取賽事信息 
     * @return 
     */ 
    public static String getHttpData(String baseUrl, String method, String reqData, HashMap<String, String> propertys){ 
        String data = "", str; 
        PrintWriter outWrite = null; 
        InputStream inpStream = null; 
        BufferedReader reader = null; 
  
        HttpURLConnection urlConn = null; 
        try{ 
            URL url = new URL(baseUrl); 
            urlConn = (HttpURLConnection)url.openConnection(); 
            //啟用gzip壓縮 
            urlConn.addRequestProperty("Accept-Encoding", "gzip, deflate"); 
            urlConn.setRequestMethod(method); 
            urlConn.setDoOutput(true); 
            urlConn.setConnectTimeout(3000); 
  
            if(propertys != null && !propertys.isEmpty()){ 
                Iterator<Map.Entry<String, String>> props = propertys.entrySet().iterator(); 
                Map.Entry<String, String> entry; 
                while (props.hasNext()){ 
                    entry = props.next(); 
                    urlConn.setRequestProperty(entry.getKey(), entry.getValue()); 
                } 
            } 
  
            outWrite = new PrintWriter(urlConn.getOutputStream()); 
            outWrite.print(reqData); 
            outWrite.flush(); 
  
            urlConn.connect(); 
  
            //獲取數據流 
            inpStream = urlConn.getInputStream(); 
            String encode = urlConn.getHeaderField("Content-Encoding"); 
  
            //如果通過gzip 
            if(encode !=null && encode.indexOf("gzip") != -1){ 
                Log.v(TAG, "get data :" + encode); 
                inpStream = new GZIPInputStream(inpStream); 
            }else if(encode != null && encode.indexOf("deflate") != -1){ 
                inpStream = new InflaterInputStream(inpStream); 
            } 
  
            reader = new BufferedReader(new InputStreamReader(inpStream)); 
  
            while((str = reader.readLine()) != null){ 
                data += str; 
            } 
        }catch (MalformedURLException ex){ 
            ex.printStackTrace(); 
        }catch (IOException ex){ 
            ex.printStackTrace(); 
        }finally{ 
            if(reader !=null && urlConn!=null){ 
                try { 
                    outWrite.close(); 
                    inpStream.close(); 
                    reader.close(); 
                    urlConn.disconnect(); 
                } catch (IOException ex) { 
                    ex.printStackTrace(); 
                } 
            } 
        } 
  
        Log.d(TAG, "[Http data]["+baseUrl+"]:" + data); 
        return data; 
    } 
  
    /** 
     * 獲取Image信息 
     * @return 
     */ 
    public static Bitmap getBitmapData(String imgUrl){ 
        Bitmap bmp = null; 
        Log.d(TAG, "get imgage:"+imgUrl); 
  
        InputStream inpStream = null; 
        try{ 
            HttpGet http = new HttpGet(imgUrl); 
            HttpClient client = new DefaultHttpClient(); 
            HttpResponse response = (HttpResponse)client.execute(http); 
            HttpEntity httpEntity = response.getEntity(); 
            BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity); 
  
            //獲取數據流 
            inpStream = bufferedHttpEntity.getContent(); 
            bmp = BitmapFactory.decodeStream(inpStream); 
  
        }catch (Exception ex){ 
            ex.printStackTrace(); 
        }finally{ 
            if(inpStream !=null){ 
                try { 
                    inpStream.close(); 
                } catch (IOException ex) { 
                    ex.printStackTrace(); 
                } 
            } 
        } 
  
        return bmp; 
    } 
  
    /** 
     * 獲取url的InputStream 
     * @param urlStr 
     * @return 
     */ 
    public static InputStream getInputStream(String urlStr){ 
        Log.d(TAG, "get http input:"+urlStr); 
        InputStream inpStream = null; 
        try{ 
            HttpGet http = new HttpGet(urlStr); 
            HttpClient client = new DefaultHttpClient(); 
            HttpResponse response = (HttpResponse)client.execute(http); 
            HttpEntity httpEntity = response.getEntity(); 
            BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity); 
  
            //獲取數據流 
            inpStream = bufferedHttpEntity.getContent(); 
        }catch (Exception ex){ 
            ex.printStackTrace(); 
        }finally{ 
            if(inpStream !=null){ 
                try { 
                    inpStream.close(); 
                } catch (IOException ex) { 
                    ex.printStackTrace(); 
                } 
            } 
        } 
        return inpStream; 
    } 

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.InflaterInputStream;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.BufferedHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

 

public class NetWork {
 private static String TAG = "NetWork";
 
 public static String getHttpData(String baseUrl){
  return getHttpData(baseUrl, "GET", "", null);
 }
 
 public static String postHttpData(String baseUrl, String reqData){
  return getHttpData(baseUrl, "POST", reqData, null);
 }
 
 public static String postHttpData(String baseUrl, String reqData, HashMap<String, String> propertys){
  return getHttpData(baseUrl, "POST", reqData, propertys);
 }
 
 /**
  * 獲取賽事信息
  * @return
  */
 public static String getHttpData(String baseUrl, String method, String reqData, HashMap<String, String> propertys){
  String data = "", str;
  PrintWriter outWrite = null;
  InputStream inpStream = null;
  BufferedReader reader = null;
 
  HttpURLConnection urlConn = null;
  try{
   URL url = new URL(baseUrl);
   urlConn = (HttpURLConnection)url.openConnection();
   //啟用gzip壓縮
   urlConn.addRequestProperty("Accept-Encoding", "gzip, deflate");
   urlConn.setRequestMethod(method);
   urlConn.setDoOutput(true);
   urlConn.setConnectTimeout(3000);
 
   if(propertys != null && !propertys.isEmpty()){
    Iterator<Map.Entry<String, String>> props = propertys.entrySet().iterator();
    Map.Entry<String, String> entry;
    while (props.hasNext()){
     entry = props.next();
     urlConn.setRequestProperty(entry.getKey(), entry.getValue());
    }
   }
 
   outWrite = new PrintWriter(urlConn.getOutputStream());
   outWrite.print(reqData);
   outWrite.flush();
 
   urlConn.connect();
 
   //獲取數據流
   inpStream = urlConn.getInputStream();
   String encode = urlConn.getHeaderField("Content-Encoding");
 
   //如果通過gzip
   if(encode !=null && encode.indexOf("gzip") != -1){
    Log.v(TAG, "get data :" + encode);
    inpStream = new GZIPInputStream(inpStream);
   }else if(encode != null && encode.indexOf("deflate") != -1){
    inpStream = new InflaterInputStream(inpStream);
   }
 
   reader = new BufferedReader(new InputStreamReader(inpStream));
 
   while((str = reader.readLine()) != null){
    data += str;
   }
  }catch (MalformedURLException ex){
   ex.printStackTrace();
  }catch (IOException ex){
   ex.printStackTrace();
  }finally{
   if(reader !=null && urlConn!=null){
    try {
     outWrite.close();
     inpStream.close();
     reader.close();
     urlConn.disconnect();
    } catch (IOException ex) {
     ex.printStackTrace();
    }
   }
  }
 
  Log.d(TAG, "[Http data]["+baseUrl+"]:" + data);
  return data;
 }
 
 /**
  * 獲取Image信息
  * @return
  */
 public static Bitmap getBitmapData(String imgUrl){
  Bitmap bmp = null;
  Log.d(TAG, "get imgage:"+imgUrl);
 
  InputStream inpStream = null;
  try{
   HttpGet http = new HttpGet(imgUrl);
   HttpClient client = new DefaultHttpClient();
   HttpResponse response = (HttpResponse)client.execute(http);
   HttpEntity httpEntity = response.getEntity();
   BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
 
   //獲取數據流
   inpStream = bufferedHttpEntity.getContent();
   bmp = BitmapFactory.decodeStream(inpStream);
 
  }catch (Exception ex){
   ex.printStackTrace();
  }finally{
   if(inpStream !=null){
    try {
     inpStream.close();
    } catch (IOException ex) {
     ex.printStackTrace();
    }
   }
  }
 
  return bmp;
 }
 
 /**
  * 獲取url的InputStream
  * @param urlStr
  * @return
  */
 public static InputStream getInputStream(String urlStr){
  Log.d(TAG, "get http input:"+urlStr);
  InputStream inpStream = null;
  try{
   HttpGet http = new HttpGet(urlStr);
   HttpClient client = new DefaultHttpClient();
   HttpResponse response = (HttpResponse)client.execute(http);
   HttpEntity httpEntity = response.getEntity();
   BufferedHttpEntity bufferedHttpEntity = new BufferedHttpEntity(httpEntity);
 
   //獲取數據流
   inpStream = bufferedHttpEntity.getContent();
  }catch (Exception ex){
   ex.printStackTrace();
  }finally{
   if(inpStream !=null){
    try {
     inpStream.close();
    } catch (IOException ex) {
     ex.printStackTrace();
    }
   }
  }
  return inpStream;
 }
}

FileUtil類[html] 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
 
import android.graphics.drawable.BitmapDrawable; 
import android.graphics.drawable.Drawable; 
import android.os.Environment; 
import android.util.Log; 
 
public class FileUtil { 
    private static int FILE_SIZE = 4*1024; 
    private static String TAG = "FileUtil";  
     
    public static boolean hasSdcard(){ 
        String status = Environment.getExternalStorageState(); 
        if(status.equals(Environment.MEDIA_MOUNTED)){ 
            return true; 
        } 
        return false; 
    } 
  
    public static boolean createPath(String path){ 
        File f = new File(path); 
        if(!f.exists()){ 
            Boolean o = f.mkdirs(); 
            Log.i(TAG, "create dir:"+path+":"+o.toString()); 
            return o; 
        } 
        return true; 
    } 
  
    public static boolean exists(String file){ 
        return new File(file).exists(); 
    } 
  
    public static File saveFile(String file, InputStream inputStream){ 
        File f = null; 
        OutputStream outSm = null; 
  
        try{ 
            f = new File(file); 
            String path = f.getParent(); 
            if(!createPath(path)){ 
                Log.e(TAG, "can't create dir:"+path); 
                return null; 
            } 
  
            if(!f.exists()){ 
                f.createNewFile(); 
            } 
  
            outSm = new FileOutputStream(f); 
            byte[] buffer = new byte[FILE_SIZE]; 
            while((inputStream.read(buffer)) != -1){ 
                outSm.write(buffer); 
            } 
            outSm.flush(); 
        }catch (IOException ex) { 
            ex.printStackTrace(); 
            return null; 
  
        }finally{ 
            try{ 
                if(outSm != null) outSm.close(); 
            }catch (IOException ex) { 
                ex.printStackTrace(); 
            } 
        } 
        Log.v(TAG,"[FileUtil]save file:"+file+":"+Boolean.toString(f.exists())); 
  
        return f; 
    } 
  
    public static Drawable getImageDrawable(String file){ 
        if(!exists(file)) return null; 
        try{ 
            InputStream inp = new FileInputStream(new File(file)); 
            return BitmapDrawable.createFromStream(inp, "img"); 
        }catch (Exception ex){ 
            ex.printStackTrace(); 
        } 
        return null; 
    } 

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Environment;
import android.util.Log;

public class FileUtil {
 private static int FILE_SIZE = 4*1024;
 private static String TAG = "FileUtil";
 
 public static boolean hasSdcard(){
  String status = Environment.getExternalStorageState();
  if(status.equals(Environment.MEDIA_MOUNTED)){
   return true;
  }
  return false;
 }
 
 public static boolean createPath(String path){
  File f = new File(path);
  if(!f.exists()){
   Boolean o = f.mkdirs();
   Log.i(TAG, "create dir:"+path+":"+o.toString());
   return o;
  }
  return true;
 }
 
 public static boolean exists(String file){
  return new File(file).exists();
 }
 
 public static File saveFile(String file, InputStream inputStream){
  File f = null;
  OutputStream outSm = null;
 
  try{
   f = new File(file);
   String path = f.getParent();
   if(!createPath(path)){
    Log.e(TAG, "can't create dir:"+path);
    return null;
   }
 
   if(!f.exists()){
    f.createNewFile();
   }
 
   outSm = new FileOutputStream(f);
   byte[] buffer = new byte[FILE_SIZE];
   while((inputStream.read(buffer)) != -1){
    outSm.write(buffer);
   }
   outSm.flush();
  }catch (IOException ex) {
   ex.printStackTrace();
   return null;
 
  }finally{
   try{
    if(outSm != null) outSm.close();
   }catch (IOException ex) {
    ex.printStackTrace();
   }
  }
  Log.v(TAG,"[FileUtil]save file:"+file+":"+Boolean.toString(f.exists()));
 
  return f;
 }
 
 public static Drawable getImageDrawable(String file){
  if(!exists(file)) return null;
  try{
   InputStream inp = new FileInputStream(new File(file));
   return BitmapDrawable.createFromStream(inp, "img");
  }catch (Exception ex){
   ex.printStackTrace();
  }
  return null;
 }
}

 

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *