Невидимый индикатор выполнения не отображается через код - PullRequest
0 голосов
/ 05 июля 2018

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

Java-код:

public class MainActivity extends AppCompatActivity {

    ImageView downloadedImg;
    ProgressBar progressBar;
    Handler handler;


    public void downloadImage(View view){

        progressBar.setVisibility(View.VISIBLE);

        ImageDownloader task = new ImageDownloader();
        Bitmap myimage;
        try {
            myimage = task.execute("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg").get();
            downloadedImg.setImageBitmap(myimage);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }

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

        downloadedImg = (ImageView)findViewById(R.id.imageView);
        progressBar = (ProgressBar)findViewById(R.id.pbar);
        handler = new Handler();

    }

    public class ImageDownloader extends AsyncTask<String,Void,Bitmap>{

        protected void onPreExecute(){
            super.onPreExecute();
            //progressBar.setVisibility(View.VISIBLE);
        }

        @Override
        protected Bitmap doInBackground(String... urls) {
            try {
                URL url = new URL(urls[0]);
                HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                Bitmap mybitmap = BitmapFactory.decodeStream(inputStream);
                return mybitmap;
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            handler.post(new Runnable() {
                @Override
                public void run() {
                    progressBar.setVisibility(View.GONE);
                    downloadedImg.setVisibility(View.VISIBLE);
                }
            });
        }

    }

    public void reset(View view){
        downloadedImg.setVisibility(View.GONE);
        progressBar.setVisibility(View.INVISIBLE);
    }
}

XML-код:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="match_parent"
    tools:context="com.example.syeddanish.downloadingimages.MainActivity">

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:onClick="downloadImage"
        android:text="Download Image" />

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button"
        android:onClick="reset"
        android:text="Reset" />

    <ProgressBar
        android:id="@+id/pbar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:indeterminate="true"
        android:visibility="invisible" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:visibility="gone"
        android:layout_below="@+id/button1" />


</RelativeLayout>

Проблема, с которой я сталкиваюсь, заключается в том, что я хочу, чтобы индикатор выполнения отображался при запуске загрузки (т. Е. При нажатии кнопки «Загрузить изображение»). Я пытаюсь сделать это двумя способами, т.е.

  1. Используя progressbar.setVisibility(View.VISIBLE); в начале метод onClick кнопки «Загрузить изображение». или
  2. При использовании progressbar.setVisibility(View.VISIBLE); в методе onPreExecute () ASyncTask, но прогресс не отображается при использовании любого из вышеупомянутых способов.

Может кто-нибудь указать, что я делаю не так?

Ответы [ 3 ]

0 голосов
/ 05 июля 2018

попробуйте поместить downloadedImg.setImageBitmap(myimage); в обработчик onPostExecute(Bitmap bitmap) и измените:

myimage = task.execute("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg").get();

до:

task.execute("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg");

также поместите Bitmap myimage; в качестве глобальной переменной в свой класс Asynctask и измените:

Bitmap mybitmap = BitmapFactory.decodeStream(inputStream);
            return mybitmap;

до:

myimage= BitmapFactory.decodeStream(inputStream);

на doInBackground

0 голосов
/ 05 июля 2018

Рассмотрите возможность использования pBar.setAlpha(1f);

Помогло, когда я застрял на подобной проблеме.

0 голосов
/ 05 июля 2018

Этот код компилируется и запускается без NetworkOnMainThreadException? Ваша проблема - использование get()

В этой части:

        Bitmap myimage;
    try {
        myimage = task.execute("http://wallpaperswide.com/download/high_tech_earth-wallpaper-2880x1800.jpg").get();
        downloadedImg.setImageBitmap(myimage);
    }

вы пытаетесь получить изображение от task.execute(...), но task.get() согласно документу:

   [...]Waits if necessary for the computation to complete, and then retrieves its result.[...]

Итак, вы ждете, пока ваша «задача» будет выполнена в главном потоке, и заблокируете ее, пока не закончите. Из-за этого, ваш прогресс никогда не виден, потому что UI-поток заблокирован. И как только твоя задача закончится, прогресс настроен обратно, чтобы быть невидимым.

Более того, не изобретай велосипед. Используйте одну из доступных библиотек для загрузки и кэширования изображений.

Например: Пикассо , Скольжение

Оба также предоставляют функциональность для использования (1) запасного варианта и (2) загрузки изображения.


Если вы все еще хотите попробовать это самостоятельно, не используйте Pokémon - "должен поймать всех" способ перехвата ваших исключений, но вместо этого обрабатывайте определенные Exceptions, которые могут появляться и отображать сообщение для пользователя, отправлять его на трекер и т. д. Поймать только те исключения, которые вы ожидаете получить, в противном случае ... дать сбой.

Я не понимаю, почему вы должны ловить исключение там.

AsyncTask, Действия и утечки памяти

Далее, AsyncTasks не аккуратно связаны с Activities. жизненный цикл. Когда вы запускаете свою задачу, и она выполняется в фоновом режиме, но ваша деятельность заканчивается, эта задача будет по-прежнему жива и будет содержать ссылку на вашу деятельность. Это приводит к утечке памяти, потому что ГХ не может правильно выполнять свою работу, чтобы очистить после вас.

Сделайте свою AsyncTask как минимум статическим классом и остановите / убейте задачу, как только ваша деятельность закончится.

Несколько задач

Далее, проверьте, загрузили ли вы уже изображение, как только пользователь нажал кнопку или вы собираетесь создать несколько задач.

Итак, сделайте ваш ImageDownloader участником вашей деятельности и проверьте, выполняется ли он уже или уже выполнен. (Выньте это из вашего метода и поместите ниже заголовка класса активности). Когда ваша активность вызывает onPause() или onDestroy(), убейте задачу огнем.

Имейте в виду изменения ориентации тоже.

API задач Android вместо AsyncTask

Я настоятельно рекомендую использовать Android Task API. (com.google.android.gms.tasks)

Он очень хорошо работает для задач, выполняемых как на основных, так и на рабочих нитях. Включает продолжения, обеспечивает Future функциональность и может быть связан с деятельностью.

Ссылки: gms Task API Doc

...