从AsyncTaskLoader更新UI(Update UI from an AsyncTaskLo

2019-07-29 00:22发布

我已经将我AsyncTaskAsyncTaskLoader (主要是应对配置更改)。 我有一个TextView ,我使用的进展状况,并使用了onProgressUpdateAsyncTask来更新它。 它看起来并不像AsyncTaskLoader具有等效的,所以在loadInBackground (在AsyncTaskLoader )我使用的是这样的:

getActivity().runOnUiThread(new Runnable() {
    public void run() {
        ((TextView)getActivity().findViewById(R.id.status)).setText("Updating...");
    }
});

我在使用这个Fragment ,这就是为什么我使用getActivity() 这项工作相当好,当配置发生改变,如改变屏幕方向除外。 我AsyncTaskLoader继续运行(这就是为什么我使用的是AsyncTaskLoader ),但runOnUiThread似乎得到跳过。

不知道为什么它被跳过,或者如果这是更新从用户界面的最佳方式AsyncTaskLoader

更新:

我最终回复到一个AsyncTask ,因为它似乎更适合于用户界面更新。 希望他们能合并有什么可行AsyncTaskAsyncTaskLoader

Answer 1:

它实际上是可能的。 你基本上需要继承AsyncTaskloader和实施publishMessage()方法,该方法将使用一个Handler交付进度信息到实现任何类ProgressListener (或任何你想将它命名)接口。

下载了一个例子: http://www.2shared.com/file/VW68yhZ1/SampleTaskProgressDialogFragme.html (如果它下线给我发短信) -这是基于的http://habrahabr.ru/post/131560/



Answer 2:

EMM ......你不应该这样做。

因为匿名类访问父类方法或字段如何是通过存储一个不可见的参考父类。

比如你有一个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。 (因为有人仍持有的参考。)

变成了内存泄漏,使你的APP GO LIMBO!

如果是我,我会实施“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();
    }
}

记得deleteObserver()onDestroy()是很重要的,这样一来加载器不会永远坚持活动为您提供参考。 (装载机可能您期间将举行活着Application生命周期...)



Answer 3:

回答我的问题,但我可以告诉, AsyncTaskLoader是不是最好的,如果你需要更新UI使用。



Answer 4:

在类中,你实现LoaderManager.LoaderCallback (想必你的活动),有一个onLoadFinished()您必须重写方法。 这是当返回什么AsyncTaskLoader加载完毕。



文章来源: Update UI from an AsyncTaskLoader