TextViewで非同期的に画像を読み込む

Android TextViewがHTMLタグをサポートすることは秘密ではありません。 中でも、タグはサポートされており、ImageGetterクラスを使用して処理されます。 また、ローカル画像ファイルの表示に問題がない場合、TextViewでプログラムからリモート図面をロードしようとすると、Androidバージョン3.0以降でNetworkOnMainThreadExceptionが発生します。 判明したように、検索エンジンにはこの問題を解決するための情報がほとんどなく、提案されたすべてのソリューションが実行可能ではありません。 ただし、実用的なソリューションが存在します。

解決策は、図面を読み込んだ後、TextViewにSpannedを再インストールすることです。 ダウンロードした画像をキャッシュして、フィールドが表示されるたびに読み込まないようにします(実装は異なる場合があります)。 したがって、ImageGetterの2つの実装を作成する必要があります。



static final Map<String, WeakReference<Drawable>> mDrawableCache = Collections.synchronizedMap(new WeakHashMap<String, WeakReference<Drawable>>()); @Override public void onCreate(Bundle savedInstanceState) { //... //  ImageGetter Html.ImageGetter igLoader = new Html.ImageGetter() { public Drawable getDrawable(String source) { //    ,          if (mDrawableCache.containsKey(source)) return mDrawableCache.get(source).get(); //  ,     new ImageDownloadAsyncTask(source, message, messageView).execute(); //      return new BitmapDrawable(getResources()); } }; //     messageView.setText(Html.fromHtml(message, igLoader, null)); } //  ImageGetter. //   ,    Html.ImageGetter igCached = new Html.ImageGetter() { public Drawable getDrawable(String source) { //      if (mDrawableCache.containsKey(source)) return mDrawableCache.get(source).get(); return null; } };
      
      







ここで、画像のダウンロードに直接関与するAsyncTaskからクラスを定義します。



 class ImageDownloadAsyncTask extends AsyncTask<Void, Void, Void> { private String source; private String message; private TextView textView; public ImageDownloadAsyncTask(String source, String message, TextView textView) { this.source = source; this.message = message; this.textView = textView; } @Override protected Void doInBackground(Void... params) { if (!mDrawableCache.containsKey(source)) { try { //     URL url = new URL(source); URLConnection connection = url.openConnection(); InputStream is = connection.getInputStream(); Drawable drawable = Drawable.createFromStream(is, "src"); //  ,    , //       // . /* Bitmap bmp = BitmapFactory.decodeStream(is); DisplayMetrics dm = MainActivity.this.getResources().getDisplayMetrics(); bmp.setDensity(dm.densityDpi); Drawable drawable=new BitmapDrawable(MainActivity.this.getResources(),bmp); */ is.close(); drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); mDrawableCache.put(source, new WeakReference<Drawable>( drawable)); } catch (MalformedURLException e) { e.printStackTrace(); } catch (Throwable t) { t.printStackTrace(); } } return null; } @Override protected void onPostExecute(Void result) { //     textView.setText(Html.fromHtml(message, igCached, null)); } }
      
      







もちろん、マニフェストにandroid.permission.INTERNET



権限を設定することを忘れないでください。



ソース / プロジェクト全体



All Articles