我在刚使用Html.fromhtml的时候,遇到了不能在主线程中加载网络图片,于是我各种的google,baidu,找到的解决方法都过于复杂,要不就是先下载到本地。再重新调用Html.fromhtml,要不就写一个很复杂的ImageGetter类来实现异步加载和UI更新。
可是在我的开发过程中由于使用了MVP模式,于是就发现了这样一个简单粗暴的解方案。
关于我这个项目中MVP结构在上一篇http://my.oschina.net/u/1392566/blog/398653 文章中已经说清楚,这里不再重复,直接贴代码说明。
## 首先,activity现实 view接口的setBodyText方法,这个是由主导器处理好后,由于已知使用者会通过导步线程调用setBodyText,所以方法内使用了Handler来实现更新
public class ContentActivity extends Activity implements ContentViewInterface
{
/*...省略..*/
/****************************************************************
* 下面所有方法为主导器接口实现
*******************************************************************/
@Override
public void setBodyText(final Spanned bodyText)
{
mHandler.post(new Runnable()
{
@Override
public void run()
{
if(BuildConfig.DEBUG) Log.d(LOG_TAG,""+bodyText);
mContentBodyTextView.setText(bodyText);
}
});
}
}
## 主导器类,获取html文本后调Html.fromhtml方法来处理,开启一个新线进行加载,这样就不会出程主线程调用网络报错了,注意ImageGetter这个类是使用网络加载img标签中的图片的,最后还记得view.setBodyText这个实现方法吗,在异步线程中对html完成加载后调用view.setBodyText,这样就完成了所有任务。
/**
* 初始化步骤
*/
private void init()
{
final String bodyText = mContentModelInterface.getBodyText();
new AsyncTask()
{
@Override
protected Object doInBackground(Object... params)
{
Spanned htmlTextSpanned = Html.fromHtml(
bodyText,
BaseImageFactory.createHtmlNetworkImageGetter(),//URL图片处理类
null);
//更新文本内容
mContentViewInterface.setBodyText(htmlTextSpanned);
return null;
}
}.execute();
}
ImageGetter
new ImageGetter()
{
@Override
public Drawable getDrawable(String source)
{
URL url;
Drawable drawable = null;
try
{
url = new URL(source);
drawable = Drawable.createFromStream(url.openStream(), null);
drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight());
} catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
return drawable;
}
};
源码地址:https://github.com/fgnna/aidaban
参考 :view.ContentActivity类 和 presenter.ContentPresenter