Как скрыть ProgressBar в AsyncTask программно в Android? - PullRequest
0 голосов
/ 11 марта 2019

У меня есть следующий статический AsyncTask класс:

public static class MyAsyncTask extends AsyncTask<String, Void, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    protected String doInBackground(String... params) {
        //Do heavy stuff
    }

    @Override
    protected void onPostExecute(String string) {
        super.onPostExecute(string);
        progressBar.setVisibility(View.GONE);
    }
}

Я хочу показать / скрыть progressBar, как вы видите в этих двух методах.Проблема в том, что я должен сделать progressBar статическим.При этом я получаю:

Не размещать классы контекста Android в статических полях;это утечка памяти (которая также нарушает мгновенный запуск)

Если я удаляю статический элемент, который остается перед моим MyAsyncTask классом, я получаю:

This AsyncTaskкласс должен быть статическим или могут возникнуть утечки (MainActivity.MyAsyncTask)

Как решить эту проблему?

Редактировать:

private void checkUser() {
    uidRef.get().addOnCompleteListener(task -> {
        if (task.isSuccessful()) {
            DocumentSnapshot document = task.getResult();
            User user = document.toObject(User.class);
            if (user == null) {
                MyAsyncTask myAsyncTask = new MyAsyncTask();
                myAsyncTask.execute(url);
            }
        }
    });
}

Ответы [ 2 ]

1 голос
/ 11 марта 2019

Я сталкивался с этой «статической» проблемой в асинхронной задаче ранее, и есть действительно хороший способ вернуть вывод асинхронной задачи в действие. Проще говоря

String output = myAsyncTask.execute(url).get();

Вы получите вывод, окончательный код.

progressBar.setVisibility(View.VISIBLE);                                  
String output = myAsyncTask.execute(url).get();
progressBar.setVisibility(View.GONE);

Пока вы не получите вывод, следующая строка не будет выполнена. Я добавляю пример кода для дальнейшей демонстрации.

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Button exe = findViewById(R.id.async);
    exe.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                updateAsyncTask up = new updateAsyncTask();

                long l = up.execute().get();
                System.out.println("inside main "+l);                    
            } catch (ExecutionException e) {
                e.printStackTrace();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    });


}

 private static class updateAsyncTask extends AsyncTask<Void, Void, Long> {

    @Override
    protected Long doInBackground(Void... voids) {

        long l = 0;
        for(int i=0;i<2000;i++)
        {
            l = l+i;
            System.out.println(l);              

        }
        return l;
    }

    }
0 голосов
/ 12 марта 2019

У меня была такая же проблема при использовании asyncTask в качестве статического подкласса, и для его решения я использовал метод отражения.это может быть немного сложно, но это работает для меня:

public class MainClass{
 @keep
 public void AfterLoad(String value) {

  }
 public void callAsync() {
   Class[] parameterTypes = new Class[1];
    parameterTypes[0] = String.class;
    try {
        Method method1 = MainClass.class.getMethod("AfterLoad", 
  parameterTypes);
        MyAsyncTask task = new MyAsyncTask(this, method1);
        task.execute(link);
    } catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
  }

public static class MyAsyncTask extends AsyncTask<String, String, Void> {
    private final Method mAfterLoad;
    private final Object mOwner;

    public MyAsyncTask(Object owner, Method afterLoad) {
        this.mAfterLoad = afterLoad;
        this.mOwner = owner;
    }  
   @Override
    protected Void doInBackground(String... requests) {
     // do what you want
    }

    @Override
    protected void onProgressUpdate(String... values) {
        super.onProgressUpdate(values);
        if (mAfterLoad != null) {
            try {
                Object[] parameters = new Object[1];
                parameters[0] = values[0];
                mAfterLoad.invoke(mOwner, parameters);
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
 }

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

...