如何从AsyncTask中的html加载图像

时间:2014-11-24 00:28:24

标签: java android android-asynctask

在AsyncTask中,我得到一个带有一些值的json作为图像。以下是我的json样本

{ 
  "text": "some text",
  "html1": "Hi, check out my fb profile picture at <img src = 'http:\/\/abc.com/image1.png'\/> ",
  "html2": "Hi, check out my whatsapp profile picture at <img src = 'http:\/\/abc.com\/image1.png'\/> ",
   .
   .
   .
}

在异步任务中执行postExecute方法我有

( ( TextView ) findViewById( R.id.html1 ) ).setText( Html.fromHtml( ( String ) jsonObj.get( "html1" ), new ImageGetter()
{
    @Override
    public Drawable getDrawable( String source )
    {
        return loadImage( source );
    }
}, null ) );
 ( ( TextView ) findViewById( R.id.html2) ).setText( Html.fromHtml( ( String ) jsonObj.get( "html2" ), new ImageGetter()
    {
        @Override
        public Drawable getDrawable( String source )
        {
            return loadImage( source );
        }
    }, null ) );

我的loadImage方法如下所示

private Drawable loadImage( String source )
    {
        Drawable drawable = null;
        URL sourceURL;
        try
        {
            sourceURL = new URL( source );
            URLConnection urlConnection = sourceURL.openConnection();
            urlConnection.connect();
            InputStream inputStream = urlConnection.getInputStream();
            BufferedInputStream bufferedInputStream = new BufferedInputStream( inputStream );
            Bitmap bm = BitmapFactory.decodeStream( bufferedInputStream );

            // convert Bitmap to Drawable
            drawable = new BitmapDrawable( getResources(), bm );

            drawable.setBounds( 0, 0, bm.getWidth(), bm.getHeight() );

        }
        catch ( MalformedURLException e )
        {
            e.printStackTrace();
        }
        catch ( IOException e )
        {
            e.printStackTrace();
        }
        return drawable;
    }

我认为代码已足够但我得到 android.os.NetworkOnMainThreadException

我在manifest.xml中添加了互联网权限

2 个答案:

答案 0 :(得分:0)

看起来url的json格式会导致所有麻烦

该问题有一篇很棒的帖子:Decode Json urls

但它最终会出现死链接..所以..一点点谷歌搜索:https://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringEscapeUtils.html

你应该用unescapeJavaScript函数取消你的url字符串以获得一个合适的url

答案 1 :(得分:0)

当应用程序尝试在其主线程上执行网络操作时,抛出此异常。在AsyncTask

中运行您的代码

&#13;
&#13;
public class MainActivity extends Activity implements ImageGetter {
    private final static String TAG = "MainActivity";
    private TextView mTv;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        String source = <your source from json here>;

        Spanned spanned = Html.fromHtml(source, this, null);
        mTv = (TextView) findViewById(R.id.text);
        mTv.setText(spanned);
    }

    @Override
    public Drawable getDrawable(String source) {
        LevelListDrawable d = new LevelListDrawable();
        Drawable empty = getResources().getDrawable(R.drawable.ic_launcher);
        d.addLevel(0, 0, empty);
        d.setBounds(0, 0, empty.getIntrinsicWidth(), empty.getIntrinsicHeight());

        new LoadImage().execute(source, d);

        return d;
    }

    class LoadImage extends AsyncTask<Object, Void, Bitmap> {

        private LevelListDrawable mDrawable;

        @Override
        protected Bitmap doInBackground(Object... params) {
            String source = (String) params[0];
            mDrawable = (LevelListDrawable) params[1];
            Log.d(TAG, "doInBackground " + source);
            try {
                InputStream is = new URL(source).openStream();
                return BitmapFactory.decodeStream(is);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (MalformedURLException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            Log.d(TAG, "onPostExecute drawable " + mDrawable);
            Log.d(TAG, "onPostExecute bitmap " + bitmap);
            if (bitmap != null) {
                BitmapDrawable d = new BitmapDrawable(bitmap);
                mDrawable.addLevel(1, 1, d);
                mDrawable.setBounds(0, 0, bitmap.getWidth(), bitmap.getHeight());
                mDrawable.setLevel(1);
                // i don't know yet a better way to refresh TextView
                // mTv.invalidate() doesn't work as expected
                CharSequence t = mTv.getText();
                mTv.setText(t);
            }
        }
    }
}
&#13;
&#13;
&#13;

或者: 在setContentView(...);

下的OnCreate中添加StrictMode代码

&#13;
&#13;
StrictMode.ThreadPolicy policy = new
StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
&#13;
&#13;
&#13;

但添加StrictMode.ThreadPolicy是一种不好的做法