如何在 Android 中以编程方式隐藏 AsyncTask 中的 ProgressBar?
Posted
技术标签:
【中文标题】如何在 Android 中以编程方式隐藏 AsyncTask 中的 ProgressBar?【英文标题】:How to hide a ProgressBar in AsyncTask programmatically in Android? 【发布时间】:2019-08-02 03:30:36 【问题描述】:我有以下静态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);
);
【问题讨论】:
如果您仅从 MainActivity 调用,则 MyAsyncTask 类不需要是静态的。 如何将字符串输出发送回主类/活动? @myatmins 我只从MainActivity
中的一个方法创建了一个新对象MyAsyncTask myAsyncTask = new MyAsyncTask();
,为什么说它不需要是静态的?
@amitava 只需在TextVIew
上设置值,就是这样。如何解决?
请同时显示执行异步任务的代码。
【参考方案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;
【讨论】:
谢谢,我现在应该在哪里设置progressBar.setVisibility(View.VISIBLE);
?因为在我的代码中,我将其设置为onPreExecute()
。
正如我所说,您可以在 myAsyncTask.execute(url) 之前设置它。这会是个问题吗?
您确定在String output = myAsyncTask.execute(url).get();
之后立即调用progressBar.setVisibility(View.GONE);
会等待doInBackground
内的工作完成吗?
这是我记得的,因为我使用输出作为返回,如果没有返回输出我会得到一个空指针异常。
让我试着让你回来。【参考方案2】:
我在使用 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 优化和重构中保存。
【讨论】:
感谢您的回答。我会尽力让你回来。以上是关于如何在 Android 中以编程方式隐藏 AsyncTask 中的 ProgressBar?的主要内容,如果未能解决你的问题,请参考以下文章
以编程方式获取 Android 手机型号,如何在 android 中以编程方式获取设备名称和型号?
如何在 Android 10 中以编程方式安装任何 Android 应用