Java Android-异步下载图像并显示它
这是代码,图像确实已下载,但问题是我无法显示它,因为无法解析方法findViewByIdJava Android-异步下载图像并显示它,java,android,Java,Android,这是代码,图像确实已下载,但问题是我无法显示它,因为无法解析方法findViewById public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> { protected void onPreExecute(){ //Setup is done here } @Override protected Bitmap doInBackground(String... params) {
public class ImageDownloader
extends AsyncTask<String, Integer, Bitmap> {
protected void onPreExecute(){
//Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
//this where i get the image using HttpURLConnection
}
protected void onProgressUpdate(Integer... params){
//Update a progress bar here, or ignore it, it's up to you
}
protected void onPostExecute(Bitmap img){
//here is the problem with findViewById beeing undefined
ImageView image_view = (ImageView) findViewById(R.id.remote_image);
if(image_view!=null && img!=null){
image_view.setImageBitmap(img);
}
}
`要访问
findViewById
,您需要实际视图。只能在活动
、片段
或视图
类中使用该方法
传递引用,不要做你的类不应该做的事情:
// add the constructor
public ImageDownloader(ImageView image) {
mImage = image;
}
然后调用构造函数:
ImageDownloader download = new ImageDownloader((ImageView) findViewById(R.id.remote_image));
清洁的解决方案还应使用WeakReference
而不是ImageView
,因为在长时间运行的任务中保留引用可能会导致内存泄漏
使用
AsyncTask
作为非静态内部类不会防止同样的问题,因为它还会保留对活动的引用,从而导致所述内存泄漏。您需要在活动中将您的imageview
声明为字段
在创建时初始化它
private ImageView image_view;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
image_view = (ImageView) findViewById(R.id.remote_image);
ImageDownloader download = new ImageDownloader();
download.execute("http://wanderingoak.net/bridge.png");
}
您的异步任务:
public class ImageDownloader
extends AsyncTask<String, Integer, Bitmap> {
protected void onPreExecute(){
//Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
//this where i get the image using HttpURLConnection
}
protected void onProgressUpdate(Integer... params){
//Update a progress bar here, or ignore it, it's up to you
}
protected void onPostExecute(Bitmap img){
if(image_view!=null && img!=null){
image_view.setImageBitmap(img);
}
}
公共类ImageDownloader
扩展异步任务{
受保护的void onPreExecute(){
//安装在这里完成
}
@凌驾
受保护位图doInBackground(字符串…参数){
//这是我使用HttpURLConnection获取图像的地方
}
受保护的void onProgressUpdate(整数…参数){
//在这里更新进度条,或者忽略它,这取决于您
}
受保护的void onPostExecute(位图img){
如果(图像视图!=null&&img!=null){
图像视图。设置图像位图(img);
}
}
Android开发者页面提供了许多有用的示例:
我假设您在处理多个下载图像方面做得不错。但如果是这样,那么您的异步任务应该检查是否存在对imageView的引用。
你应该朝这个方向走:
public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloader(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
protected void onPreExecute() {
//Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
//this where i get the image using HttpURLConnection
}
protected void onProgressUpdate(Integer... params) {
//Update a progress bar here, or ignore it, it's up to you
}
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
remote\u image
是您当前布局中图像视图的id吗?显然asynctask没有这样的方法…显然您必须将imageview引用传递给它,或者使您的asynctask实现成为具有这样的方法的类的内部非静态类…看起来缺少java的基础知识(根本没有与android连接)不要重新发明轮子。使用。你需要向ImageDownloader
添加一个构造函数,它将活动
作为参数…或者更好的是,使用ImageView
@cricket\u 007我同意第三方库对这一点很好,特别是在开发时间非常关键的情况下。同时,使用异步任务来完成这一点self是一个很好的学习练习,并不完全是琐碎的。OP在尝试设置其映像之前,还必须注意不要破坏ImageView
。@代码学徒不会在最坏的情况下泄露活动吗?你是对的,一个WeakReference
将是一个不错的选择,但我不想过度训练OP。我不是100%满意e关于这里的生命周期问题。如果AsyncTask
启动,然后用户导航到另一个活动/片段,最后AsyncTask
完成并设置ImageView
的映像,会发生什么情况?ImageDownloader
中的引用是否有效?尝试过这个方法并确实有效,但这是正确的吗r方法?@Akis\u Tfs根据您的情况,可以有很多方法,但我认为在您的情况下,imageview应该是活动的属性,无需将其传递给AsyncTask。您应该包含封闭的类声明,以使答案更清楚。@Code peduate like?哪个类包含onCreate()
?那么ImageDownloader
如何访问image\u视图
?异步任务应该是活动的一部分,然后它可以访问活动的该字段,这当然是一个解决方案。您的答案可以通过显式显示来改进。这肯定很有效,对我帮助很大。如果我想在e图像正在下载?@Akis\u Tfs,只需使用,它更易于使用,让您轻松完成。
public class ImageDownloader extends AsyncTask<String, Integer, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
public ImageDownloader(ImageView imageView) {
imageViewReference = new WeakReference<ImageView>(imageView);
}
protected void onPreExecute() {
//Setup is done here
}
@Override
protected Bitmap doInBackground(String... params) {
//this where i get the image using HttpURLConnection
}
protected void onProgressUpdate(Integer... params) {
//Update a progress bar here, or ignore it, it's up to you
}
protected void onPostExecute(Bitmap bitmap) {
if (imageViewReference != null && bitmap != null) {
final ImageView imageView = imageViewReference.get();
if (imageView != null) {
imageView.setImageBitmap(bitmap);
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageView iv = (ImageView) findViewById(R.id.myImageView);
new ImageDownloader(iv).execute("http://wanderingoak.net/bridge.png");
}