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

问题描述 投票:0回答:2

我有以下静态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上下文类放在静态字段中;这是内存泄漏(也打破了Instant Run)

如果我删除停留在我的MyAsyncTask类前面的静态,我得到:

此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);
            }
        }
    });
}
android android-asynctask android-progressbar
2个回答
1
投票

我之前在异步任务中遇到了这个“静态”问题,并且有一种非常好的方法可以将异步任务的输出恢复到活动状态。简单的说

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
投票

使用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注释,以保护它免受保护优化和重构。

© www.soinside.com 2019 - 2024. All rights reserved.