Android progressBar setVisibility () не работает

Может кто-нибудь помочь мне понять, почему progressBar.setVisibility() работает при использовании CountDownTimer, но не при загрузке async? На самом деле, первая Toast на async загрузке даже не отображается, хотя вторая onPostExecute() показывает. Ниже приведена работающая, вернее, НЕ работающая демонстрация. Большое спасибо.

Моя MainActivity:

public class MainActivity extends AppCompatActivity {

    ProgressBar progressBar;

    int[] items = { 12982418, 12998698, 12993549, 12995125, 12987537, 12993021, 12991986, 13008408, 12983417, 12986060, 12998395, 12985644, 13014731, 12986433, 12985074, 12994455, 12994262, 12986759, 13011932, 13005211, 12993521, 12987900, 12992623, 12981736, 12986649, 12991524, 13000035, 12989278, 13013868, 13009417, 13013327, 12981605, 12985768, 13000158, 13015035, 13002596, 13015944, 12997893, 12999767, 13010949, 12996835, 13013517, 13006555, 13013143, 13010016, 13005792, 13016948, 13007235, 12998343, 12987102 };
    int counter;

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

        progressBar = (ProgressBar) findViewById(R.id.progressBar);
        progressBar.setIndeterminate(true);
        progressBar.setKeepScreenOn(true);
        progressBar.setVisibility(View.INVISIBLE);
    }

    public void actionTimer(View view) {
        Toast.makeText(this, "starting progressBar - CountDownTimer", Toast.LENGTH_SHORT).show();
        progressBar.setVisibility(View.VISIBLE);
        new CountDownTimer(5000, 500) {
            @Override
            public void onTick(long millisUntilFinished) {
            }
            @Override
            public void onFinish() {
                progressBar.setVisibility(View.INVISIBLE);
                Toast.makeText(getApplicationContext(), "timer done", Toast.LENGTH_SHORT).show();
            }
        }.start();
    }

    public void actionJson(View view) {
        Toast.makeText(this, "starting progressBar - json fetch", Toast.LENGTH_SHORT).show();
        progressBar.setVisibility(View.VISIBLE);

        String urlTemplate = "https://hacker-news.firebaseio.com/v0/item/___ITEM_NUMBER___.json?print=pretty";
        counter = 0;

        for (int i = 0; i < items.length; i++) {
            String url = urlTemplate.replaceAll("___ITEM_NUMBER___", String.valueOf(items[i]));
            //Log.i("thisDoesNotWork", url);

            DownloadJson downloadJson = new DownloadJson();
            try {
                downloadJson.execute(url).get();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
        }
    }

    public class DownloadJson extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... params) {
            Log.i("DownloadJson", "url=" + params[0]);

            URL url;
            HttpURLConnection urlConnection = null;

            try {
                url = new URL(params[0]);
                urlConnection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = urlConnection.getInputStream();

                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuilder resultBuilder = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) {
                    resultBuilder.append(line).append("\n");
                }
                //Log.i("DownloadJson", "resultBuilder.length()=" + resultBuilder.length());
                return resultBuilder.toString();

            } catch (Exception e) {
                e.printStackTrace();
                return "{\"status\" : \"Hacker News json download failed\"}";
            }
        }

        @Override
        public void onPostExecute(String s) {
            super.onPostExecute(s);
            counter += 1;
            if (counter == items.length) {
                progressBar.setVisibility(View.INVISIBLE);
                Toast.makeText(getApplicationContext(), "download done", Toast.LENGTH_SHORT).show();
            }
        }
    }
}

Мой 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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.plaudev.progressbar.MainActivity">

    <LinearLayout
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical">

        <Button
            android:text="@string/timer"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:layout_centerHorizontal="true"
            android:id="@+id/buttonTimer"
            android:layout_weight="1"
            android:onClick="actionTimer"
            android:layout_margin="25dp" />

        <Button
            android:text="@string/json"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/buttonJson"
            android:layout_weight="1"
            android:onClick="actionJson"
            android:layout_margin="25dp" />
    </LinearLayout>

    <ProgressBar
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true"
        android:id="@+id/progressBar" />
</RelativeLayout>

person rockhammer    schedule 23.11.2016    source источник
comment
Сколько времени занимает выполнение задачи doInBackground? Возможно, он завершается, а индикатор выполнения становится невидимым еще до того, как он отображается в пользовательском интерфейсе.   -  person mWhitley    schedule 23.11.2016
comment
onPostExecute, запущенный в потоке пользовательского интерфейса, означает, что он прав. Вместо inVisible попробуйте GONE. В вашем случае вы всегда должны использовать go   -  person Jitesh Mohite    schedule 23.11.2016
comment
Спасибо вам обоим. Я уже пробовал GONE, но это не работает. Кстати, это не объясняет, почему метод CountDownTimer работает с одним и тем же INVISIBLE. Загрузка завершается за считанные секунды.   -  person rockhammer    schedule 23.11.2016
comment
Вы уверены, что `if (counter == items.length)` проходит?   -  person Vygintas B    schedule 23.11.2016
comment
просто чтобы было ясно, проблема в том, что progressBar не отображается при нажатии кнопки асинхронной загрузки   -  person rockhammer    schedule 23.11.2016
comment
где реализация кнопки загрузки?   -  person Vygintas B    schedule 23.11.2016


Ответы (1)


Ответ заключается в том, чтобы поместить весь цикл for в onClick actionJson() в рабочий поток следующим образом: отмечено здесь:

public void actionJson(View view) {
        Toast.makeText(this, "starting progressBar - json fetch", Toast.LENGTH_SHORT).show();
        progressBar.setVisibility(View.VISIBLE);

        final String urlTemplate = "https://hacker-news.firebaseio.com/v0/item/___ITEM_NUMBER___.json?print=pretty";
        counter = 0;

        // simply put it in a worker thread does the job
        new Thread(new Runnable() {
            public void run() {
                for (int i = 0; i < items.length; i++) {
                    String url = urlTemplate.replaceAll("___ITEM_NUMBER___", String.valueOf(items[i]));
                    //Log.i("actionJson", url);
                    DownloadJson downloadJson = new DownloadJson();
                    try {
                        downloadJson.execute(url).get();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (ExecutionException e) {
                        e.printStackTrace();
                    }
                }
            }
        }).start();
    }

Таким образом, несмотря на то, что цикл for, как было определено изначально, порождает целую группу asyncTasks по отдельности, он все равно каким-то образом блокирует основной поток.

person rockhammer    schedule 23.11.2016