2016-02-14 2 views
-1

Это код, изображение действительно загружен, но проблема в том, что я не могу показать его из-за не неоспоримым состоянии решить метод findViewByIdAndroid - Асинхронный загрузить изображение и отобразить его

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); 
    } 
} 

На мой Майне активность я называю ImageDownloader внутри OnCreate так:

ImageDownloader download = new ImageDownloader(); 
download.execute("http://wanderingoak.net/bridge.png"); 

`

+0

ли 'remote_image' идентификатор вашего зрения изображения в вашей ** текущей раскладки **? –

+0

Очевидно, что asynctask не имеет такого метода ... Очевидно, что вам нужно передать ссылку на изображение или сделать свою реализацию asynctask внутренним нестационарным классом класса, который имеет такой метод ... Похож на отсутствие основ java (не связанных с андроид вообще) – Selvin

+0

да это имя ImageView, расположенное внутри content_main.xml – Akis

ответ

3

Android страница разработчиков содержит множество полезных примеров : http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Я предполагаю, что вы справляетесь с обработкой нескольких загружаемых изображений. Но если это так, то ваш asyncTask должен проверить, существует ли ссылка на 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); 
       } 
      } 
     } 
    } 

Тогда Вы звоните, например:

@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"); 
    } 
+0

, это, безусловно, работает и очень помогло мне. Что делать, если я хочу отображать загрузчик во время загрузки изображения? – Akis

+1

@Akis_Tfs, просто используйте [Picasso] (http://square.github.io/picasso/), это намного проще в использовании и позволяет вам делать это легко. – JonasCz

3

Чтобы получить доступ к findViewById вам нужно фактический вид. Этот метод можно использовать только в классах Activity, Fragment или View.

Pass в ссылке, и не делать то, что классы не должны делать:

// add the constructor 
public ImageDownloader(ImageView image) { 
    mImage = image; 
} 

Затем вызовите конструктор:

ImageDownloader download = new ImageDownloader((ImageView) findViewById(R.id.remote_image)); 

чистый раствор следует дополнительно использовать a WeakReference<ImageView> вместо ImageView, поскольку сохранение ссылки в задачах с длительным запуском может привести к утечке памяти.

Использование AsyncTask в качестве нестатического внутреннего класса будет не предотвратить такую ​​же проблему, поскольку она также будет содержать ссылку на активность, вызывающую утечку памяти.

+0

OP также должен быть осторожным, чтобы «ImageView» не был уничтожен, прежде чем пытаться установить его образ. –

+0

@ Code-Apprentice Не худший случай просто утечка активности? Вы правы, «WeakReference» - это путь, но я не хотел перенапрягать OP. –

+0

Я не уверен на 100% о проблемах жизненного цикла. Что произойдет, если запускается 'AsyncTask', тогда пользователь переходит к другому действию/фрагменту, и, наконец,' AsyncTask' заканчивает и устанавливает изображение 'ImageView'? Будет ли ссылка в «ImageDownloader» действительной? –

1

Вы должны объявить 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); 
     } 
    } 
+0

Вы должны включить объявляющие объявления класса, чтобы сделать ваш ответ более ясным. –

+0

@ Code-Apprentice вот так? – meda

+0

В каком классе содержится 'onCreate()'? И как 'ImageDownloader' получает доступ к' image_view'? –

Смежные вопросы