Android TextView 显示HTML加图片

TextView显示网络图片,我用android2.3的系统,可以显示图片出来,并且如果图片比较大,应用会卡的现象,肯定是因为使用主线程去获取网络图片造成的,但如果我用android4.0以上的系统运行,则不能显示图片,只显示小方框。

究其原因,是在4.0的系统上执行的时候报错了,异常是:android.os.NetworkOnMainThreadException 经过查文档,原来是4.0系统不允许主线程(UI线程)访问网络,因此导致了其异常。说白了就是在主线程上访问网络,会造成主线程挂起,系统不允许使用了。

原文来自铃不铃不铃的博客:http://www.mjix.com/archives/1046.html

此处有作部分修改,代码独立。图片实现异步加载。解决上述问题

用法,调用代码activity

//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类
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 类
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类
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;
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android 中,可以通过以下两种方式在 TextView显示图片: 1. 使用 HTML 标记 可以在 TextView 中使用 HTML 标记来显示图片。具体做法如下: 在 strings.xml 中定义一个包含 HTML 标记的字符串: ```xml <string name="html_text">这是一个包含图片的文本:<br><img src="android.resource://com.example.app/drawable/ic_launcher"/></string> ``` 在代码中获取该字符串,并将其设置给 TextView: ```java textView.setText(Html.fromHtml(getString(R.string.html_text))); ``` 其中,`android.resource://com.example.app/drawable/ic_launcher` 是图片的路径,需要根据实际情况进行修改。 2. 使用 SpannableString 使用 SpannableString 可以在 TextView 中插入图片,并且可以控制图片的大小和位置。具体做法如下: ```java SpannableString spannableString = new SpannableString("这是一个包含图片的文本:"); Drawable drawable = getResources().getDrawable(R.drawable.ic_launcher); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); ImageSpan imageSpan = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE); spannableString.setSpan(imageSpan, spannableString.length() - 1, spannableString.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); textView.setText(spannableString); ``` 其中,`R.drawable.ic_launcher` 是图片的资源 ID,需要根据实际情况进行修改。`setBounds()` 方法用于设置图片的大小和位置,`ALIGN_BASELINE` 表示将图片和基线对齐。`setSpan()` 方法用于将图片插入到 SpannableString 中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值