Android: Загрузка изображений из Интернета с Asynctask
-
29-09-2019 - |
Вопрос
Как мне заменить следующие строки кода с асинктюдой? Как вы «верните» растровое изображение от асинктюз? Спасибо.
ImageView mChart = (ImageView) findViewById(R.id.Chart);
String URL = "http://www...anything ...";
mChart.setImageBitmap(download_Image(URL));
public static Bitmap download_Image(String url) {
//---------------------------------------------------
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
}
return bm;
//---------------------------------------------------
}
Я думал о чем-то вроде этого:
заменять :
mChart.setImageBitmap(download_Image(graph_URL));
Что-то вроде:
mChart.setImageBitmap(new DownloadImagesTask().execute(graph_URL));
и
public class DownloadImagesTask extends AsyncTask<String, Void, Bitmap> {
@Override
protected Bitmap doInBackground(String... urls) {
return download_Image(urls[0]);
}
@Override
protected void onPostExecute(Bitmap result) {
mChart.setImageBitmap(result); // how do I pass a reference to mChart here ?
}
private Bitmap download_Image(String url) {
//---------------------------------------------------
Bitmap bm = null;
try {
URL aURL = new URL(url);
URLConnection conn = aURL.openConnection();
conn.connect();
InputStream is = conn.getInputStream();
BufferedInputStream bis = new BufferedInputStream(is);
bm = BitmapFactory.decodeStream(bis);
bis.close();
is.close();
} catch (IOException e) {
Log.e("Hub","Error getting the image from server : " + e.getMessage().toString());
}
return bm;
//---------------------------------------------------
}
}
Но как я передаю ссылку на MCHART в OnPostexecute (результат растрового изображения) ??? Нужно ли мне в каком-то способе передать его с URL? Я хотел бы заменить все мои строки кода:
mChart1.setImageBitmap(download_Image(URL_1));
mChart2.setImageBitmap(download_Image(URL_2));
С чем-то похожим ... но в асинкт-пути!
mChart1.setImageBitmap(new DownloadImagesTask().execute(graph_URL_1));
mChart2.setImageBitmap(new DownloadImagesTask().execute(graph_URL_2));
Есть ли простое решение для этого? Здесь я что-то не так?
Решение
Если нет никаких веских причина для скачать изображение самостоятельно, то я бы порекомендовал использовать Пикассо.
Picasso спасает вас все проблемы с загрузкой, настройки и кэшированием изображений. Весь код, необходимый для простого примера:
Picasso.with(context).load(url).into(imageView);
Если вы действительно хотите сделать все, что сами используйте мой старый ответ ниже.
Если изображение не так, вы можете просто использовать анонимный класс для асинхронизации. Это хотелось бы это:
ImageView mChart = (ImageView) findViewById(R.id.imageview);
String URL = "http://www...anything ...";
mChart.setTag(URL);
new DownloadImageTask.execute(mChart);
Класс задач:
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
@Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
private Bitmap download_Image(String url) {
...
}
Сокрытие URL в теге немного сложно, но он выглядит приятнее в классе звонков, если у вас есть много imageViews, которые вы хотите заполнить таким образом. Это также помогает, если вы используете ImageView внутри ListView, и вы хотите знать, если ImageView был переработан во время загрузки изображения.
Я написал, если вы имиджеру не так много, потому что это приведет к тому, что это приведет к задаче, имеющей неявный указатель в основную активность, заставляющую сборщик мусора, чтобы удерживать всю активность в память, пока задача не будет. Если пользователь перемещается на другой экран вашего приложения, пока растровое изображение загружает, память не может быть освобождена, и она может сделать ваше приложение и всю систему медленнее.
Другие советы
Попробуйте этот код:
ImageView myFirstImage = (ImageView) findViewById(R.id.myFirstImage);
ImageView mySecondImage = (ImageView) findViewById(R.id.mySecondImage);
ImageView myThirdImage = (ImageView) findViewById(R.id.myThirdImage);
String URL1 = "http://www.google.com/logos/2013/estonia_independence_day_2013-1057005.3-hp.jpg";
String URL2 = "http://www.google.com/logos/2013/park_su-geuns_birthday-1055005-hp.jpg";
String URL3 = "http://www.google.com/logos/2013/anne_cath_vestlys_93rd_birthday-1035005-hp.jpg";
myFirstImage.setTag(URL1);
mySecondImage.setTag(URL2);
myThirdImage.setTag(URL3);
new DownloadImageTask.execute(myFirstImage);
new DownloadImageTask.execute(mySecondImage);
new DownloadImageTask.execute(myThirdImage);
public class DownloadImagesTask extends AsyncTask<ImageView, Void, Bitmap> {
ImageView imageView = null;
@Override
protected Bitmap doInBackground(ImageView... imageViews) {
this.imageView = imageViews[0];
return download_Image((String)imageView.getTag());
}
@Override
protected void onPostExecute(Bitmap result) {
imageView.setImageBitmap(result);
}
private Bitmap download_Image(String url) {
Bitmap bmp =null;
try{
URL ulrn = new URL(url);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = con.getInputStream();
bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
return bmp;
}catch(Exception e){}
return bmp;
}
}
Вы можете создать класс сказать ..bkgprocess, который содержит внутренний класс, который расширяет асинктюсс. Хотя призрак BKGPROCSES пропускает контекст своего класса активности в BKGProcess Constructor. например:
public class BkgProcess {
String path;
Context _context;
public Download(Downloader downloader, String path2){
this.path = path2;
_context = downloader;
}
public void callProgressDialog(){
new BkgProcess().execute((Void)null);
}
class Downloads extends AsyncTask<Void, Void, Boolean> {
private ProgressDialog dialog = new ProgressDialog(_context);
protected void onPreExecute(){
dialog.setMessage("Downloading image..");
dialog.show();
}
protected void onPostExecute(Boolean success) {
dialog.dismiss();
if(success)
Toast.makeText(_context, "Download complete", Toast.LENGTH_SHORT).show();
}
@Override
protected Boolean doInBackground(Void... params) {
return(startDownload(path));
}
public boolean startDownload(String img_url) {
// download img..
return true;
}
}
}
из вашего класса активности ..
BkgProcess dwn = new BkgProcess (Your_Activity_class.this, img_path);
dwn.callProgressDialog();
Это позволит вам изображения любого размера ... если вы не хотите, чтобы диалоговое окно прогресса просто комментируйте коды в OnPreexecute ();
for(int i = 0 ; i < no_of_files ; i++ )
new FetchFilesTask().execute(image_url[i]);
private class FetchFilesTask extends AsyncTask<String, Void, Bitmap> {
private ProgressDialog dialog = new ProgressDialog(FileExplorer.this);
Bitmap bitmap[];
protected void onPreExecute(){
dialog.setMessage("fetching image from the server");
dialog.show();
}
protected Bitmap doInBackground(String... args) {
bitmap = getBitmapImageFromServer();
return bitmap;
}
protected void onPostExecute(Bitmap m_bitmap) {
dialog.dismiss();
if(m_bitmap != null)
//store the images in an array or do something else with all the images.
}
}
public Bitmap getBitmapImageFromServer(){
// fetch image form the url using the URL and URLConnection class
}