2014-01-31 4 views
0

Я пишу приложение для Android, которое отображает случайные изображения в формате JPG из Интернета. Если нажата кнопка, приложение отправляет запрос GET на http://imgur.com/random, а из ответа сервера он сохраняет URL-адрес изображения JPG в виде строки (см. Код).AsyncTask - Я использую его правильно?

Я получил это для работы, используя StrictMode.setThreadPolicy, но я не могу сделать это с помощью AsyncTask.

Я пытался поставить добычу адрес .JPG в doInBackground, а сам процесс изменения изображения в onPostExecute, как это:

public class MainActivity extends Activity { 

    // Page "http://imgur.com/random" redirects users to a random page; 
    // After the redirect, the URL will be something like "http://imgur.com/gallery/XXXXXX"; 
    // Actual image is at "http://i.imgur.com/XXXXXX.jpg" 
    private final String WHERE = "http://imgur.com/random"; 
    private ImageExtractor ie; 

    private class ATask1 extends AsyncTask<String, Void, String> { 

     @Override 
     protected String doInBackground(String... params) { 
      // Go to WHERE and get a valid URL to a random .jpg image 
      ie = new ImageExtractor(); 
      ie.extractImageURL(WHERE); 
      return null; 
     } 

     @Override 
     protected void onPostExecute(String result) { 
      // Change the image in ImageView based on the new URL 
      ImageView i = (ImageView)findViewById(R.id.imageDisplay); 

      try { 
       Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(ie.getImageURL()).getContent()); 
       i.setImageBitmap(bitmap); 
      } catch (Exception e) { 
      } 
     } 
    } 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
    } 

    // Method called when the button is pressed 
    public void getNewImage(View v) { 
     new ATask1().execute(""); 
    } 
    .... 
} 

public class ImageExtractor { 

    private final String USER_AGENT = "Mozilla/5.0"; 
    private String imageURL; 

    public void extractImageURL(String address) { 
     String returnedURL; 

     try { 
      // Create URL object based on passed argument 
      URL url = new URL(address); 

      // Send GET request 
      HttpURLConnection conn = (HttpURLConnection)(url.openConnection()); 
      conn.setRequestMethod("GET"); 
      conn.setRequestProperty("User-Agent", USER_AGENT); 

      // Response code of the answer 
      conn.getResponseCode(); 

      // Create and save image URL as a string 
      returnedURL = conn.getURL().toString(); 
      imageURL = returnedURL.replace("http://imgur.com/gallery/", "http://i.imgur.com/") + ".jpg"; 
     } 
     catch (IOException e) { 

     } 
    } 

    // Return image URL as a string; 
    // http://i.imgur.com/XXXXXX.jpg 
    public String getImageURL() { 
     return imageURL; 
    } 
} 

Прямо сейчас, если я нажимаю кнопку, адрес случайного .JPG сохраняется правильно в imageURL, но после этого ничего не происходит. Правильно ли, что я сделал до сих пор? Нужно ли мне создавать новую AsyncTask/Thread для части BitmapFactory или что-то в этом роде? Как именно это должно быть реализовано?

Благодарим за помощь!

ответ

1

Вы получили общую концепцию, но мне очень интересно об этом немного:

Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(ie.getImageURL()).getContent()); 

Вы делаете это в onPostExecute, которая в потоке пользовательского интерфейса, и это выглядит ужасно, как запрос сети. Более новые версии Android будут просто отказываться от этого и бросают NetworkOnMainThreadException. Кажется, единственное, что вы делаете асинхронно, это запрос на получение пути к изображению.

+0

Спасибо! Это было глупо со мной. Я переместил эту линию в метод doInBackground и работает как шарм! – Eduard

2

Это выглядит нормально для меня. Просто вещь: в методе doInBackground() вы возвращаетесь null - Имейте в виду, что это параметр, который получит ваш метод onPostExecute(), поэтому в основном String result будет null. Но в вашем случае, если вы не используете его неправильно, все в порядке.

Ответ на ваш вопрос: трудно сказать, где ошибка, но способ, которым вы управляете своим AsyncTask, кажется мне прав. Вам не нужно объявлять новый Thread или AsyncTask, чтобы выполнить extractImageURL(WHERE), в конце концов, AsyncTask уже является Thread и сделает это в фоновом режиме. Я бы поставил несколько экземпляров Log.d() на весь ваш код AsyncTask, чтобы увидеть, где ошибка, но, насколько касается структуры, у нее, похоже, нет никаких проблем.

+0

Я не думаю, что «AsyncTask' является« Thread », справедливо. Это компонент, который создает базовую «Thread» для тяжелой атлетики, но также предлагает методы для запуска вещей в «UI Thread» – codeMagic

+0

. Вы правы, я, вероятно, описал это очень «грубым» способом. – nKn

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