如何在 Android 中以编程方式隐藏 AsyncTask 中的 ProgressBar?

How to hide a ProgressBar in AsyncTask programmatically in Android?

我有以下静态 AsyncTask class:

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);
    }
}

我想 show/hide progressBar 正如您在这两种方法中看到的那样。问题是我必须使 progressBar 静态化。这样做,我得到:

Do not place Android context classes in static fields; this is a memory leak (and also breaks Instant Run)

如果我删除留在 MyAsyncTask class 前面的静电,我得到:

This AsyncTask class should be static or leaks might occur (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);
            }
        }
    });
}

我之前在异步任务中遇到过这个 "static" 问题,有一种非常好的方法可以将异步任务的输出返回到 activity 。简单地说

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;
    }

    }

我在将 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 注释以将其从 pro-guard 优化中保存并且重构。