遵循教程here我已经设置了一个应用程序,该应用程序应该能够从URL下载图像并将其放入ImageView中。唯一的问题是它无法找到findViewById,因为它位于Activity类而不是AsyncTask类中。代码在这里:
package com.example.weather2;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ImageView;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
public class ImageDownloader
extends AsyncTask<String, Integer, Bitmap> {
protected void onPreExecute(){
//Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
//TODO Auto-generated method stub
try{
URL url = new URL(params[0]);
HttpURLConnection httpCon =
(HttpURLConnection)url.openConnection();
if(httpCon.getResponseCode() != 200)
throw new Exception("Failed to connect");
InputStream is = httpCon.getInputStream();
return BitmapFactory.decodeStream(is);
}catch(Exception e){
Log.e("Image", "Failed to load image", e);
}
return null;
}
protected void onProgressUpdate(Integer... params){
//Update a progress bar here, or ignore it, I didn't do it
}
protected void onPostExecute(Bitmap img){
ImageView iv = (ImageView) findViewById(R.id.imageView); //here is where the issue is
if(iv!=null && img!=null){
iv.setImageBitmap(img);
}
}
protected void onCancelled(){
}
}
当我评论出问题的那一行时,我没有得到任何错误,这让我认为它有效,但我无法分辨,因为没有发布图像。 任何帮助解决这个问题都将非常感激。
答案 0 :(得分:4)
findViewById
是Activity类的一种方法。
你有
public class ImageDownloader
extends AsyncTask<String, Integer, Bitmap> // not a activity class
如果您需要将数据恢复为活动状态,则可以使用interface作为活动的回调。
我会在Activity中更新ui。看看@ blackbelts回答
How do I return a boolean from AsyncTask?
或者
使AsyncTask成为Activity类的内部类,并在onPostExecute
另外,您可能会发现Alex Loockwood的这篇博客很有趣
http://www.androiddesignpatterns.com/2013/04/retaining-objects-across-config-changes.html
答案 1 :(得分:3)
不是在findViewById()
中调用AsyncTask
,而是将ImageView
作为参数传递:
public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
final ImageView mImageView;
public ImageDownloader(ImageView imageView) {
mImageView = imageView;
}
// ...
答案 2 :(得分:1)
配置/获取图像时直接使用您的活动。这将解决您的问题。
public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
private Context context;
public ImageDownloader(Activity yourActivity) {
context = activity;
}
// ...
protected void onPostExecute(Void... params){
ImageView iv = (ImageView) context.findViewById(R.id.imageView);
if(iv!=null && img!=null){
iv.setImageBitmap(img);
}
}
}
答案 3 :(得分:1)
使用强制转换为AppCompatActivity,例如:
public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
private Context context;
public ImageDownloader(Activity yourActivity) {
context = yourActivity;
}
// ...
protected void onPostExecute(Void... params){
//Here
ImageView iv = (ImageView) ((AppCompatActivity) context).findViewById(R.id.imageView);
if(iv!=null && img!=null){
iv.setImageBitmap(img);
}
}
}
答案 4 :(得分:0)
您可以将AsyncTask实现为活动的内部类。并将ImageView iv = (ImageView) findViewById(R.id.imageView);
放入您的活动的onCreate()方法中。这就是我在项目中所做的。
或者您可以将activity.this作为参数传递给AsyncTask的构造函数。并在AsyncTask的onPostExecute()方法中使用ImageView iv = (ImageView)activity. findViewById(R.id.imageView)
。