我有以下静态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
类前面的静态变量,则会得到:
此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);
}
}
});
}
答案 0 :(得分: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;
}
}
答案 1 :(得分: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注释以将其保存在保护措施的优化和重构中。