我在这里看了几个答案,但他们都问了不同的事情。结果我想出了下面的代码。我使用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拉到一个字符串中,显示得很好,但这显然没用。
有什么想法吗?如何从异步完成的已分析数据集中显示图像?
感谢任何人的帮助。感谢。
答案 0 :(得分:4)
我建议你使用另一种方式,就像魅力:Android查询。
您可以从此处下载该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:
直接获取BitmapandroidAQuery.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本身提供,因此请使用它并查看您想要的结果。
它非常快速和准确,使用它你可以在加载时找到更多功能,如动画;如果需要,获取位图;等
答案 1 :(得分: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);
希望它有所帮助。
答案 2 :(得分:0)
你必须在doBackground()中下载图像,然后将doBackground的结果设置为刚刚下载的位图。在onPostExecute(位图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);
}
}
答案 3 :(得分:0)
您可以使用droidQuery大大简化此操作:
ImageView one = (ImageView)findViewById(R.id.one);
String getImage = bookDet.get(0).image;
$.with(one).image(getImage);
这将从URL延迟加载图像,并处理所有异步调用和数据解析。