首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从AsyncTaskLoader更新UI

从AsyncTaskLoader更新UI
EN

Stack Overflow用户
提问于 2012-04-16 10:48:21
回答 5查看 6.3K关注 0票数 5

我已经将我的AsyncTask转换为AsyncTaskLoader (主要是为了处理配置更改)。我有一个用作进度状态的TextView,并在AsyncTask中使用onProgressUpdate来更新它。看起来AsyncTaskLoader没有等价物,所以在loadInBackground (在AsyncTaskLoader中)期间,我使用了以下代码:

代码语言:javascript
复制
getActivity().runOnUiThread(new Runnable() {
    public void run() {
        ((TextView)getActivity().findViewById(R.id.status)).setText("Updating...");
    }
});

我在Fragment中使用它,这就是我使用getActivity()的原因。这种方法工作得很好,除非发生了配置更改,比如更改屏幕方向。我的AsyncTaskLoader一直在运行(这就是我使用AsyncTaskLoader的原因),但是runOnUiThread似乎被跳过了。

不确定它被跳过的原因,或者这是否是从AsyncTaskLoader更新UI的最佳方式。

更新:

我最终回到了AsyncTask,因为它似乎更适合UI更新。希望他们能将AsyncTaskAsyncTaskLoader的功能合并在一起。

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2012-04-29 17:07:31

这实际上是有可能的。实际上,您需要将AsyncTaskloader子类化并实现一个publishMessage()方法,该方法将使用Handler将进度消息传递给实现ProgressListener (或您想叫它的任何名称)接口的任何类。

下载这个示例:http://www.2shared.com/file/VW68yhZ1/SampleTaskProgressDialogFragme.html (如果离线就给我发消息)-这是基于http://habrahabr.ru/post/131560/

票数 4
EN

Stack Overflow用户

发布于 2014-01-31 18:12:58

嗯..。你不该这么做。

因为匿名类如何通过存储对父类的不可见引用来访问父类方法或字段。

例如,你有一个Activity

代码语言:javascript
复制
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.
    }
}

编译器实际上会生成类似下面这样的东西:

代码语言:javascript
复制
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()“,如下所示:

代码语言:javascript
复制
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类中

代码语言:javascript
复制
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生命周期中,加载程序可能会一直处于活动状态...)

票数 4
EN

Stack Overflow用户

发布于 2012-04-24 22:34:06

回答我自己的问题,但据我所知,如果你需要更新UI,AsyncTaskLoader不是最好的选择。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10168171

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档