2

我在这里看过一些答案,但他们都问了不同的问题。结果我想出了下面的代码。我使用 AsyncTask 解析我的 JSON,我可以在两个地方访问它。doInBackground() 结束;和 onPostExecute();

我在两者中都尝试了以下代码并得到了两个不同的错误:

编码:

try {
   ImageView one = (ImageView)findViewById(R.id.one);
   String getImage = bookDet.get(0).image;
   Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(getImage).getContent());
   one.setImageBitmap(bitmap); 
} catch (MalformedURLException e) {
   e.printStackTrace();
} catch (IOException e) {
   e.printStackTrace();
}

BookDet 是保存数据的 ArrayList,它已被转换为字符串并放在那里。

我尝试 doInBackground() 时的错误:

E/AndroidRuntime(14007): FATAL EXCEPTION: AsyncTask #2
E/AndroidRuntime(14007): java.lang.RuntimeException: An error occured while executing doInBackground()
E/AndroidRuntime(14007):    at android.os.AsyncTask$3.done(AsyncTask.java:299)
E/AndroidRuntime(14007):    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:352)
E/AndroidRuntime(14007):    at java.util.concurrent.FutureTask.setException(FutureTask.java:219)
E/AndroidRuntime(14007):    at java.util.concurrent.FutureTask.run(FutureTask.java:239)
E/AndroidRuntime(14007):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
E/AndroidRuntime(14007):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
E/AndroidRuntime(14007):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
E/AndroidRuntime(14007):    at java.lang.Thread.run(Thread.java:856)
E/AndroidRuntime(14007): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

这只是其中的一部分,但最后一行似乎是关键。只有一个 AsyncTask 所以是的。

当我在 onPostExecute 中执行此操作时出错:

E/AndroidRuntime(16801): FATAL EXCEPTION: main
E/AndroidRuntime(16801): android.os.NetworkOnMainThreadException
E/AndroidRuntime(16801):    at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
E/AndroidRuntime(16801):    at java.net.InetAddress.lookupHostByName(InetAddress.java:385)
E/AndroidRuntime(16801):    at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
E/AndroidRuntime(16801):    at java.net.InetAddress.getAllByName(InetAddress.java:214)
E/AndroidRuntime(16801):    at libcore.net.http.HttpConnection.<init>(HttpConnection.java:70)
E/AndroidRuntime(16801):    at libcore.net.http.HttpConnection.<init>(HttpConnection.java:50)
E/AndroidRuntime(16801):    at libcore.net.http.HttpConnection$Address.connect(HttpConnection.java:340)
E/AndroidRuntime(16801):    at libcore.net.http.HttpConnectionPool.get(HttpConnectionPool.java:87)
E/AndroidRuntime(16801):    at libcore.net.http.HttpConnection.connect(HttpConnection.java:128)
E/AndroidRuntime(16801):    at libcore.net.http.HttpEngine.openSocketConnection(HttpEngine.java:316)
E/AndroidRuntime(16801):    at libcore.net.http.HttpEngine.connect(HttpEngine.java:311)
E/AndroidRuntime(16801):    at libcore.net.http.HttpEngine.sendSocketRequest(HttpEngine.java:290)
E/AndroidRuntime(16801):    at libcore.net.http.HttpEngine.sendRequest(HttpEngine.java:240)
E/AndroidRuntime(16801):    at libcore.net.http.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:81)
E/AndroidRuntime(16801):    at java.net.URLConnection.getContent(URLConnection.java:190)
E/AndroidRuntime(16801):    at java.net.URL.getContent(URL.java:447)

所以我不能在主线程中做到这一点......?

目前我能做的最好的事情就是有一个 TextView 将那个 url 拉到一个字符串中,并且显示得很好,但这显然是没用的。

有任何想法吗?如何从一组异步完成的解析数据中显示图像?

感谢任何人的帮助。谢谢。

4

4 回答 4

4

我向你推荐一种不同的方式,就像一个魅力:Android Query。

您可以从这里下载该 jar 文件:http ://code.google.com/p/android-query/downloads/list

AQuery androidAQuery=new AQuery(this);

举个例子:

androidAQuery.id(YOUR IMAGEVIEW).image(YOUR IMAGE TO LOAD, true, true, getDeviceWidth(), ANY DEFAULT IMAGE YOU WANT TO SHOW);

使用上面的代码,您可以通过 url 直接显示您的图像。现在下面的代码是直接从 url 获取位图:

androidAQuery.ajax(YOUR IMAGE URL,Bitmap.class,0,new AjaxCallback<Bitmap>(){
                        @Override
                        public void callback(String url, Bitmap object, AjaxStatus status) {
                            super.callback(url, object, status);

                            //You will get Bitmap from object.
                        }

});

这个库是由 Android 自己提供的,所以使用它并查看你想要的结果。

它非常快速和准确,使用它您可以在加载时找到更多功能,例如动画;如果需要,获取位图;等等

于 2013-10-17T12:59:23.043 回答
0

您可以使用droidQuery大大简化此操作:

ImageView one = (ImageView)findViewById(R.id.one);
String getImage = bookDet.get(0).image;
$.with(one).image(getImage);

这将从 URL 延迟加载图像,并处理所有异步调用和数据解析。

于 2013-10-20T16:12:34.170 回答
0

您应该异步获取文件,然后为您的 imageview 设置它。

我已经使用了很多这个轻量级库来简化进行异步 HTTP 调用的所有操作:http: //loopj.com/android-async-http/

例子:

AsyncHttpClient client = new AsyncHttpClient();
String[] allowedContentTypes = new String[] { "image/png", "image/jpeg" };
client.get("http://example.com/file.png", new BinaryHttpResponseHandler(allowedContentTypes) {
    @Override
    public void onSuccess(byte[] fileData)
    {
         Bitmap bmp = BitmapFactory.decodeByteArray(fileData, 0, fileData.length);

         if(imageView != null)
         {
             imageView.setImageBitmap(bmp);
         }
    }
});

其中 imageView 是您之前获得的 ImageView 的参考:

imageView = (ImageView) view.findViewById(R.id.YOUR_IMAGEVIEW_ID);

希望能帮助到你。

于 2013-10-17T12:34:36.057 回答
0

您必须在 doBackground() 中下载图像,然后将 doBackground 的结果设置为您刚刚下载的位图。在 onPostExecute(Bitmap bmp) 中,您可以将其设置为所需的 imageView。不要忘记更改 AsyncTask 的参数:

AsyncTask<SomeObject, Integer, Bitmap>

代码应如下所示。

public class DownloadFilesTask extends AsyncTask<SomeObject, Integer, Bitmap> {
    protected Long doInBackground(SomeObject object) {

        //do the networking and parse json here

        try {
            String getImage = bookDet.get(0).image;
            Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(getImage).getContent()); 
            return bitmap;
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } 
        return null;
    }

    protected void onPostExecute(Bitmap bmp) {

        //set the bitmap to image here

        ImageView one = (ImageView)findViewById(R.id.one);
        one.setImageBitmap(bmp);
    }
}
于 2013-10-17T13:09:17.307 回答