我正在编写一个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,或类似的东西?究竟应该如何实施?
感谢您的帮助!
答案 0 :(得分:2)
对我来说没问题。只是一件事:在doInBackground()
方法中,您正在返回null
- 请注意,这是您的onPostExecute()
方法将接收的参数,所以基本上String result
将是空值。但在你的情况下,只要你不以不正确的方式使用它,就可以了。
回答你的问题:很难说出错误在哪里,但你处理AsyncTask
的方式对我来说似乎是正确的。您无需声明新的Thread
或AsyncTask
来执行extractImageURL(WHERE)
工作,毕竟AsyncTask
已经是Thread
并且会这样做在背景中。我会考虑在所有Log.d()
代码中放置几个AsyncTask
个实例,以查看错误的位置,但就结构而言,它似乎没有任何问题。
答案 1 :(得分:1)
你有一般概念,但我对这一点感到好奇:
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(ie.getImageURL()).getContent());
你在UI线程上的onPostExecute
中执行此操作,这看起来非常像网络请求。较新版本的Android只会拒绝执行此操作并抛出NetworkOnMainThreadException
。你似乎唯一不同寻常的是获取图像路径的请求。