我已经将我的AsyncTask转换为AsyncTaskLoader (主要是为了处理配置更改)。我有一个用作进度状态的TextView,并在AsyncTask中使用onProgressUpdate来更新它。看起来AsyncTaskLoader没有等价物,所以在loadInBackground (在AsyncTaskLoader中)期间,我使用了以下代码:
getActivity().runOnUiThread(new Runnable() {
public void run() {
((TextView)getActivity().findViewById(R.id.status)).setText("Updating...");
}
});我在Fragment中使用它,这就是我使用getActivity()的原因。这种方法工作得很好,除非发生了配置更改,比如更改屏幕方向。我的AsyncTaskLoader一直在运行(这就是我使用AsyncTaskLoader的原因),但是runOnUiThread似乎被跳过了。
不确定它被跳过的原因,或者这是否是从AsyncTaskLoader更新UI的最佳方式。
更新:
我最终回到了AsyncTask,因为它似乎更适合UI更新。希望他们能将AsyncTask和AsyncTaskLoader的功能合并在一起。
发布于 2012-04-29 17:07:31
这实际上是有可能的。实际上,您需要将AsyncTaskloader子类化并实现一个publishMessage()方法,该方法将使用Handler将进度消息传递给实现ProgressListener (或您想叫它的任何名称)接口的任何类。
下载这个示例:http://www.2shared.com/file/VW68yhZ1/SampleTaskProgressDialogFragme.html (如果离线就给我发消息)-这是基于http://habrahabr.ru/post/131560/的
发布于 2014-01-31 18:12:58
嗯..。你不该这么做。
因为匿名类如何通过存储对父类的不可见引用来访问父类方法或字段。
例如,你有一个Activity
public class MyActivity
extends Activity
{
public void someFunction() { /* do some work over here */ }
public void someOtherFunction() {
Runnable r = new Runnable() {
@Override
public void run() {
while (true)
someFunction();
}
};
new Thread(r).start(); // use it, for example here just make a thread to run it.
}
}编译器实际上会生成类似下面这样的东西:
private static class AnonymousRunnable {
private MyActivity parent;
public AnonymousRunnable(MyActivity parent) {
this.parent = parent;
}
@Override
public void run() {
while (true)
parent.someFunction();
}
}因此,当您的父Activity销毁(例如,由于配置更改),而您的匿名类仍然存在时,整个活动不能被gc-ed。(因为仍然有人持有引用。)
成为内存泄漏并使你的应用程序陷入困境的!
如果是我,我会为加载器实现"onProgressUpdate()“,如下所示:
public class MyLoader extends AsyncTaskLoader<Something> {
private Observable mObservable = new Observable();
synchronized void addObserver(Observer observer) {
mObservable.addObserver(observer);
}
synchronized void deleteObserver(Observer observer) {
mObservable.deleteObserver(observer);
}
@Override
public void loadInBackground(CancellationSignal signal)
{
for (int i = 0;i < 100;++i)
mObservable.notifyObservers(new Integer(i));
}
}在你的Activity类中
public class MyActivity extends Activity {
private Observer mObserver = new Observer() {
@Override
public void update(Observable observable, Object data) {
final Integer progress = (Integer) data;
mTextView.post(new Runnable() {
mTextView.setText(data.toString()); // update your progress....
});
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreated(savedInstanceState);
MyLoader loader = (MyLoader) getLoaderManager().initLoader(0, null, this);
loader.addObserver(mObserver);
}
@Override
public void onDestroy() {
MyLoader loader = (MyLoader) getLoaderManager().getLoader(0);
if (loader != null)
loader.deleteObserver(mObserver);
super.onDestroy();
}
}记住在onDestroy()期间执行deleteObserver()是很重要的,这样加载器就不会永远持有对你的活动的引用。(在您的Application生命周期中,加载程序可能会一直处于活动状态...)
发布于 2012-04-24 22:34:06
回答我自己的问题,但据我所知,如果你需要更新UI,AsyncTaskLoader不是最好的选择。
https://stackoverflow.com/questions/10168171
复制相似问题