Android的HTML ImageGetter作为AsyncTask

好的,我对这个失去了主意。 我在我的程序parsingHTML的方法。 我想包括内联图像,我的印象是使用Html.fromHtml(string,Html.ImageGetter,Html.TagHandler)将允许这种情况发生。

由于Html.ImageGetter没有实现,所以我写一个。 但是,由于将URLparsing为Drawables需要networking访问,因此我无法在主线程上执行此操作,因此它必须是AsyncTask。 我认为。

但是,当您将ImageGetter作为parameter passing给Html.fromHtml时,它将使用必须重写的getDrawable方法。 因此,无法调用触发doInBackground方法的整个ImageGetter.execute处理,因此无法真正实现这种asynchronous处理。

我是否完全错误,或者更糟的是,这是不可能的? 谢谢

我做了一些非常相似的事情(我认为)要做你想做的事情。 我当时需要做的是parsingHTML并将其设置回TextView,同时我也需要使用Html.ImageGetter ,并且在获取主线程上的图像时也有同样的问题。

我做的基本步骤是:

  • 为Drawable创build我自己的子类以方便重绘,我把它叫做URLDrawable
  • URLDrawablegetDrawable方法中Html.ImageGetter
  • 一旦onPostExecute被调用,我重绘onPostExecute结果的容器

现在URLDrawable的代码如下

 public class URLDrawable extends BitmapDrawable { // the drawable that you need to set, you could set the initial drawing // with the loading image if you need to protected Drawable drawable; @Override public void draw(Canvas canvas) { // override the draw to facilitate refresh function later if(drawable != null) { drawable.draw(canvas); } } } 

很简单,我只是重写draw所以它会select我在AsyncTask完成后设置的Drawable。

下面的类是Html.ImageGetter的实现,以及从AsyncTask中获取图像并更新图像的类

 public class URLImageParser implements ImageGetter { Context c; View container; /*** * Construct the URLImageParser which will execute AsyncTask and refresh the container * @param t * @param c */ public URLImageParser(View t, Context c) { this.c = c; this.container = t; } public Drawable getDrawable(String source) { URLDrawable urlDrawable = new URLDrawable(); // get the actual source ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask( urlDrawable); asyncTask.execute(source); // return reference to URLDrawable where I will change with actual image from // the src tag return urlDrawable; } public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> { URLDrawable urlDrawable; public ImageGetterAsyncTask(URLDrawable d) { this.urlDrawable = d; } @Override protected Drawable doInBackground(String... params) { String source = params[0]; return fetchDrawable(source); } @Override protected void onPostExecute(Drawable result) { // set the correct bound according to the result from HTTP call urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0 + result.getIntrinsicHeight()); // change the reference of the current drawable to the result // from the HTTP call urlDrawable.drawable = result; // redraw the image by invalidating the container URLImageParser.this.container.invalidate(); } /*** * Get the Drawable from URL * @param urlString * @return */ public Drawable fetchDrawable(String urlString) { try { InputStream is = fetch(urlString); Drawable drawable = Drawable.createFromStream(is, "src"); drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0 + drawable.getIntrinsicHeight()); return drawable; } catch (Exception e) { return null; } } private InputStream fetch(String urlString) throws MalformedURLException, IOException { DefaultHttpClient httpClient = new DefaultHttpClient(); HttpGet request = new HttpGet(urlString); HttpResponse response = httpClient.execute(request); return response.getEntity().getContent(); } } } 

最后,下面是演示事情如何工作的示例程序:

 String html = "Hello " + "<img src='http://www.gravatar.com/avatar/" + "f9dd8b16d54f483f22c0b7a7e3d840f9?s=32&d=identicon&r=PG'/>" + " This is a test " + "<img src='http://www.gravatar.com/avatar/a9317e7f0a78bb10a980cadd9dd035c9?s=32&d=identicon&r=PG'/>"; this.textView = (TextView)this.findViewById(R.id.textview); URLImageParser p = new URLImageParser(textView, this); Spanned htmlSpan = Html.fromHtml(html, p, null); textView.setText(htmlSpan); 

很不错。 但是,不build议使用DefaultHttpClienttypes。 在获取方法上试试这个:

 private InputStream fetch(String urlString) throws MalformedURLException, IOException { URL url = new URL(urlString); HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection(); InputStream stream = urlConnection.getInputStream(); return stream; } 

我有点困惑,是你想呈现静态的HTML只是为了格式化,或者它是dynamic的来自networking? 如果你想要后者,就是渲染HTML并检索图像,那么会有点痛苦(build议 – 只使用WebView?)。

无论如何,您首先必须运行AsyncTask来检索最初的HTML。 然后,您将使用Html.ImageGetter类的自定义实现将这些结果传递给Html.fromHtml() 。 然后在那个实现中,你必须启动一个单独的AsyncTask来检索每个图像(你可能想实现一些caching)。

然而,从阅读文档(我想我已经看到一些样本),在我看来,这不是他们的意思是Html.ImageGetter 。 我认为它的意思是硬编码的HTML引用内部 drawables,但这只是我的看法。

如果您使用毕加索,请将@momo代码的一部分更改为

 /*** * Get the Drawable from URL * @param urlString * @return */ public Drawable fetchDrawable(String urlString) { try { Drawable drawable = fetch(urlString); drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0 + drawable.getIntrinsicHeight()); return drawable; } catch (Exception e) { return null; } } private Drawable fetch(String urlString) throws MalformedURLException, IOException { return new BitmapDrawable(c.getResources(), Picasso.with(c).load(urlString).get()); } 

AsyncTask task = new AsyncTask(){

  @Override protected String doInBackground(Integer... params) { span = Html.fromHtml(noticeList.get(0) .getContent(), imgGetter, null); return null; } @Override protected void onPostExecute(String result) { super.onPostExecute(result); text.setMovementMethod(ScrollingMovementMethod .getInstance()); if(span != null){ text.setText(span); } } }; task.execute();