Как загрузить серию изображений с сервера

У меня есть собственный сервер, и я хочу автоматически загружать изображения одно за другим. Прямо сейчас я попытался загрузить и сохранить изображение на устройстве, и это работает на 100 процентов отлично. Но это работает для одного изображения, вот хорошая ссылка в теме. Но он работает, но загружает только одно изображение или, можно сказать, одно изображение по одной ссылке.

Мне пришла в голову идея: создать массив строк URL-адреса, а затем применить цикл for, а затем он загрузит и выполнит столько Asynctask.

Но это не очень хорошая практика, так как это приведет к запуску слишком большого количества асинхронных задач.

Что я хочу

  1. Я хочу, чтобы, если у меня есть 10 URL-адресов, он должен загружать изображения с первого URL-адреса на последний URL-адрес, но по одному, я имею в виду, что когда первое изображение загружено, оно должно запускать второе изображение после сохранения первого изображения на устройстве.

  2. Он должен отображать прогресс индикатора выполнения для всех изображений. и если обновить прогресс, скажем, есть 10 изображений, тогда он должен показать 10 процентов завершенных, когда первые изображения были успешно загружены, и он должен показать 20 процентов, если было загружено 2 изображения.

Пожалуйста, дайте мне исходный код или что-нибудь, что может мне помочь. Спасибо.


person Coas Mckey    schedule 03.11.2015    source источник
comment
Вы должны сделать логику на стороне сервера. Android — это просто клиентское приложение. он только загружается, сервер должен решить, сколько файлов нужно отправить клиентскому приложению.   -  person RAAAAM    schedule 03.11.2015


Ответы (2)


почему бы вам не попробовать этот цикл for внутри aysncTask, так как это не создаст несколько объектов aysncTask, меньше использует память.

 public class httpDownloadImages extends AsyncTask<Void,Void,String> {
        Bitmap myBitmap[]=new Bitmap[10];
@Override
    protected void onPreExecute() {
        super.onPreExecute();
        showProgressDialog();

    }

        @Override
        protected String doInBackground(Void... params) {
            try {

                for(int i=1; i<=10; i++){
                    String src="http://"+ip+"/images/"+i+".jpg";
                    java.net.URL url = new java.net.URL(src);
                    HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                    connection.setDoInput(true);
                    connection.connect();
                    InputStream input = connection.getInputStream();
                    myBitmap[i] = BitmapFactory.decodeStream(input);
                    if(myBitmap[i]!=null)
                        saveimagetoFile(myBitmap[i],i);
                }

            } catch (IOException e) {

                return null;
            }
            return "successful";
        }
        @Override
        protected void onPostExecute(String s) {
            super.onPostExecute(s);
            progress_dialog.hide();

        }
    }

и определите способ сохранения изображений на SD-карту, если хотите:

void saveimagetoFile(Bitmap bmp,int num){
        try {
            String path = Environment.getExternalStorageDirectory().toString();
            OutputStream fOut = null;
            File file = new File(path, "PriceChecker/pc"+num+".jpg"); // the File to save to
            fOut = new FileOutputStream(file);
            bmp.compress(Bitmap.CompressFormat.JPEG, 100, fOut); //save image to jpeg file
            fOut.flush();
            fOut.close();
        }catch (Exception e){

        }
    }

но в моем случае изображения были названы 1.jpg , 2.jpg, 3.jpg ... и т. д. Надеюсь, это поможет

EDIT: способ отображения диалогового окна прогресса:

private void showProgressDialog(){
 AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);

        View promptView;
        LayoutInflater layoutInflater = LayoutInflater.from(OrderActivity_gridstyle.this);
        promptView = layoutInflater.inflate(R.layout.progress_dialog, null);

        alertDialogBuilder.setView(promptView);
        alertDialogBuilder.setCancelable(true);
        progress_dialog=alertDialogBuilder.create();
        progress_dialog.show();}

диалоговое окно прогресса, которое я использовал, имеет форму: колесо, конечно, вы можете использовать другую форму или тип.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:padding="10dp"
    android:id="@+id/progress_time">

    <ProgressBar
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="150dp"
        android:layout_height="150dp"
        android:id="@+id/prog_circle"
        android:max="100"
        android:progress="0"
        android:indeterminate="true"
        android:indeterminateDrawable="@drawable/progress_wheel"
        android:layout_below="@+id/textView11"
        android:layout_centerHorizontal="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:text="Please Wait"
        android:id="@+id/textView11"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:textColor="@color/blue_" />

</RelativeLayout>

который выглядит так: введите здесь описание изображения

person Nouran S. Ahmad    schedule 04.11.2015
comment
отлично, это выглядит круто, и где вы предпочитаете обновлять индикатор выполнения? - person Coas Mckey; 04.11.2015
comment
вы можете использовать 2 метода: onPreExecute и onPostExecute, чтобы показать и скрыть диалог. проверьте правку выше :D - person Nouran S. Ahmad; 04.11.2015
comment
отметьте это, если вам нужно показать прогресс в цифрах или процентах: stackoverflow.com/questions/9043683/ - person Nouran S. Ahmad; 04.11.2015

Если у вас уже есть одна загрузка, в чем проблема с цепочкой загрузок для нескольких изображений? Если вас не волнует точный прогресс (по крайней мере, это то, что я здесь понимаю), вы можете просто сделать это с помощью цикла for.

Псевдокод:

String[] urlStack = {"http://www.myimage.com/1.jpg", "http://www.myimage.com/2.jpg", "http://www.myimage.com/3.jpg"};
for(int i = 0; i < urlStack.length; i++)
{
   yourAlreadyDoneDownloadProcedure(updateProgressCallback);
}

... метод updateProgressCallback, конечно, вызывается в вашей процедуре загрузки, как только загрузка завершена. ...

private void updateProgressFallback()
{
   progressBarText += 100 / urlStack.length;
}

Это просто для того, чтобы продемонстрировать, как вы можете/должны подойти к этому.


Изменить свой первый комментарий:

В этом случае вам следует использовать FutureTask.

Объекты FutureTask могут ожидать завершения без каких-либо while()...sleep

e.g.

for(int i = 0; i < urlStack.length; i++)
{
   // fTask is an array of your download procedure objects

   // get() will wait until the Task is done, no manual sleep commands necessary
   fTask[i].get();

   // since we have a concatenation of downloads, we can update progress here
   progessBarText += 100 / urlStack.length;
}

Изменить второй комментарий:

У вас будет класс, который реализует Callable, где и происходит вся ваша магия:

public class MyCallable implements Callable<String>
{
    String url;

    public MyCallable(String s)
    {
        url = s;
    }

    @Override
    public String call() throws Exception
    {
        // Download image here, you have the URL stored in `url`
        return "I'm done";
    }
}

Затем ваша FutureTask запускает этот объект:

MyCallable img1 = new MyCallable("http://www.myimage.com/1.jpg");    
MyCallable img2 = new MyCallable("http://www.myimage.com/2.jpg");    
FutureTask<String> fTask = new FutureTask<String>(img1);
fTask.get();
fTask = new FutureTask<String>(img2);
fTask.get();

Это делает его более ясным? Вышеприведенный код можно много оптимизировать, это просто для того, чтобы передать то, что вам нужно знать о FutureTask

person LilaQ    schedule 03.11.2015
comment
а как насчет загрузки следующего изображения после завершения одного, я не хочу устанавливать цикл for, так как он запускает так много асинхронных задач - person Coas Mckey; 04.11.2015
comment
Итак, как сделать массив будущих задач, я думаю, у нас есть одна задача, и это загрузка изображения, хотя загрузка изображения - это процесс или задача, которая является множественной. так что я должен сделать будущую задачу asynctask или где? Я не понимаю, можете ли вы объяснить больше - person Coas Mckey; 04.11.2015
comment
Я обновил свой ответ, чтобы вы могли понять принцип FutureTask. После этого настоятельно рекомендуется оптимизировать, поместив все вызываемые объекты в массив, вектор и т. д., а затем перебирая их. - person LilaQ; 04.11.2015