我有以下静态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);
}
}
});
}
我之前在异步任务中遇到了这个“静态”问题,并且有一种非常好的方法可以将异步任务的输出恢复到活动状态。简单的说
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注释,以保护它免受保护优化和重构。