3

我有一系列文件要上传。这些作为条目存储在 Content Provider 中。每个条目还包含上传的百分比。

一个活动显示上传列表,每个文件都是一个带有进度条的项目,用于显示上传进度。

我更新进度条的方式是通过 ContentObserver。在 CursorAdaptor 中,我为每个项目定义了一个 ContentObserver 并将其保存为相应视图的标签。

我现在的问题是我不知道何时取消注册此类 ContentObservers。我发现的唯一方法是在包含活动的onDestroy()

    for (int i = 0; i < mListView.getChildCount(); i++) {
        final View v = mListView.getChildAt(i);
        final ContentObserver obs = (ContentObserver) v.getTag();
        if (obs != null) {
            getContentResolver().unregisterContentObserver(obs);
        }
    }

这真的,真的太可怕了。它引入了适配器和父活动之间的依赖关系。另一方面,未注册的 ContentObservers 可以防止 Activity 被破坏,从而引入内存泄漏。

你看到更好的方法了吗?

4

1 回答 1

0

如果您有内容提供者,则可以使用 CursorLoader 代替。

https://developer.android.com/training/load-data-background/setup-loader.html

public class PhotoThumbnailFragment extends FragmentActivity implements
        LoaderManager.LoaderCallbacks<Cursor> {
...
}

/*
* Callback that's invoked when the system has initialized the Loader and
* is ready to start the query. This usually happens when initLoader() is
* called. The loaderID argument contains the ID value passed to the
* initLoader() call.
*/
@Override
public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle)
{
    /*
     * Takes action based on the ID of the Loader that's being created
     */
    switch (loaderID) {
        case URL_LOADER:
            // Returns a new CursorLoader
            return new CursorLoader(
                        getActivity(),   // Parent activity context
                        mDataUrl,        // Table to query
                        mProjection,     // Projection to return
                        null,            // No selection clause
                        null,            // No selection arguments
                        null             // Default sort order
        );
        default:
            // An invalid id was passed in
            return null;
    }
}

您只需定义一个游标加载器并实现回调,就不需要内容观察器。效果更好。

于 2014-01-15T00:34:40.263 回答