AsyncTask - 我使用它了吗?

时间:2014-01-31 22:52:27

标签: android android-asynctask

我正在编写一个Android应用程序,可以显示来自网络的随机JPG图像。如果按下按钮,应用程序会向 http://imgur.com/random 发送GET请求,并从服务器的响应中将URL保存为JPG图像(请参阅代码)。

我使用 StrictMode.setThreadPolicy 来实现此功能,但我不能使用AsyncTask来实现。

我试图在 doInBackground 中提取.JPG地址,以及在 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中,但之后没有任何反应。我到目前为止做的是否正确?我是否需要为BitmapFactory部分创建一个新的AsyncTask / Thread,或类似的东西?究竟应该如何实施?

感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

对我来说没问题。只是一件事:在doInBackground()方法中,您正在返回null - 请注意,这是您的onPostExecute()方法将接收的参数,所以基本上String result将是空值。但在你的情况下,只要你不以不正确的方式使用它,就可以了。

回答你的问题:很难说出错误在哪里,但你处理AsyncTask的方式对我来说似乎是正确的。您无需声明新的ThreadAsyncTask来执行extractImageURL(WHERE)工作,毕竟AsyncTask已经是Thread并且会这样做在背景中。我会考虑在所有Log.d()代码中放​​置几个​​AsyncTask个实例,以查看错误的位置,但就结构而言,它似乎没有任何问题。

答案 1 :(得分:1)

你有一般概念,但我对这一点感到好奇:

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

你在UI线程上的onPostExecute中执行此操作,这看起来非常像网络请求。较新版本的Android只会拒绝执行此操作并抛出NetworkOnMainThreadException。你似乎唯一不同寻常的是获取图像路径的请求。