android - 这个 Loader 类应该是静态的,否则可能会发生泄漏 |内部类内存泄漏 | AsyncTaskLoader 内存泄漏 -

标签 android memory-leaks asynctaskloader

我在 android studio 中收到有关 AsyncTaskLoader 的以下警告:

"This Loader class should be static or leaks might occur (anonymous android.support.v4.content.AsyncTaskLoader) less... (Ctrl+F1)

静态字段会泄漏上下文。非静态内部类具有对其外部类的隐式引用。例如,如果该外部类是 Fragment 或 Activity,则此引用意味着长时间运行的处理程序/加载程序/任务将持有对 Activity 的引用,从而防止它被垃圾收集。同样,对这些运行时间较长的实例中的 Activity 和 fragment 的直接字段引用可能会导致泄漏。 ViewModel 类永远不应指向 View 或非应用程序上下文。”

这是我的应用程序的代码 fragment :

@Override
public Loader<Cursor> onCreateLoader(int id, final Bundle loaderArgs) {

    return new AsyncTaskLoader<Cursor>(this) {

        // Initialize a Cursor, this will hold all the task data
        Cursor mTaskData = null;

        // onStartLoading() is called when a loader first starts loading data
        @Override
        protected void onStartLoading() {
            if (mTaskData != null) {
                // Delivers any previously loaded data immediately
                deliverResult(mTaskData);
            } else {
                // Force a new load
                forceLoad();
            }
        }

        // loadInBackground() performs asynchronous loading of data
        @Override
        public Cursor loadInBackground() {
            // Will implement to load data

            // Query and load all task data in the background; sort by priority
            // [Hint] use a try/catch block to catch any errors in loading data

            try {
                return getContentResolver().query(TaskContract.TaskEntry.CONTENT_URI,
                        null,
                        null,
                        null,
                        TaskContract.TaskEntry.COLUMN_PRIORITY);

            } catch (Exception e) {
                Log.e(TAG, "Failed to asynchronously load data.");
                e.printStackTrace();
                return null;
            }
        }

        // deliverResult sends the result of the load, a Cursor, to the registered listener
        public void deliverResult(Cursor data) {
            mTaskData = data;
            super.deliverResult(data);
        }
    };

}


/**
 * Called when a previously created loader has finished its load.
 *
 * @param loader The Loader that has finished.
 * @param data The data generated by the Loader.
 */
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
    // Update the data that the adapter uses to create ViewHolders
    mAdapter.swapCursor(data);
}


/**
 * Called when a previously created loader is being reset, and thus
 * making its data unavailable.
 * onLoaderReset removes any references this activity had to the loader's data.
 *
 * @param loader The Loader that is being reset.
 */
@Override
public void onLoaderReset(Loader<Cursor> loader) {
    mAdapter.swapCursor(null);
}

最佳答案

解决方案是创建一个 Another 类并将其设为静态。

然后从新创建的静态类扩展 AsynctaskLoader。 Ex - 公共(public)静态类 ExtendsAysncTaskLoader 扩展 AsynctaskLoader

创建一个成员变量——游标

使用参数(Context context, Cursor)为类创建构造函数

使用super方法调用父类的Constructor并传递context。

设置成员变量等于构造函数。

覆盖 onStartLoading 和 LoadInbackground 并按照 todo 中的解释实现它(但请确保您将使用在新类中创建的成员变量)在新创建的静态类中。

在onCreateLoader方法中——返回带参数的新类 Ex - 返回新的 ExtendsAysncTaskLoader (this,Cursor);

错误现在会消失,因为我们正在使用一个名为 ExampleAsync 的静态类,它继承了 AsyncTaskLoader 并且不会发生内存泄漏。

示例类 -

    public static class ExtendsAysncTaskLoader extends AsyncTaskLoader<Cursor>{

        Cursor mTaskData; 

    public ExtendsAysncTaskLoader(Context context, Cursor cursor) {
                super(context);
                mTaskData = cursor;
            }

     // onStartLoading() is called when a loader first starts loading data
    @Override
    protected void onStartLoading() {
        if (mTaskData != null) {
            // Delivers any previously loaded data immediately
            deliverResult(mTaskData);
        } else {
            // Force a new load
            forceLoad();
        }
    }

    // loadInBackground() performs asynchronous loading of data
    @Override
    public Cursor loadInBackground() {
        // Will implement to load data

        // Query and load all task data in the background; sort by priority
        // [Hint] use a try/catch block to catch any errors in loading data

        try {
            return getContentResolver().query(TaskContract.TaskEntry.CONTENT_URI,
                    null,
                    null,
                    null,
                    TaskContract.TaskEntry.COLUMN_PRIORITY);

        } catch (Exception e) {
            Log.e(TAG, "Failed to asynchronously load data.");
            e.printStackTrace();
            return null;
        }
    }

    // deliverResult sends the result of the load, a Cursor, to the registered listener
    public void deliverResult(Cursor data) {
        mTaskData = data;
        super.deliverResult(data);
    }
};

    OnCreateLoader() Example -

    @Override
        public Loader<String> onCreateLoader(int id, final Bundle args) {

           Cursor mTaskData = null;                

            return new ExtendsAysncTaskLoader(this,mTaskData);


        }

希望对您有所帮助

关于android - 这个 Loader 类应该是静态的,否则可能会发生泄漏 |内部类内存泄漏 | AsyncTaskLoader 内存泄漏 -,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48920568/

相关文章:

Android 从 Google Drive 获取文件的 Uri 路径

ios - 当类包含数组时,Swift 3 枚举内存泄漏

java - Android Espresso 单击 ListView 内的按钮

android - 如何在不向设备添加帐户的情况下从 Google Play 服务获取授权码?

java - 参数通过引用而不是值传递

android - fragment 中的内存泄漏

python - 带有 islice 的生成器循环中可能存在内存泄漏

android - 在没有 Fragment 的情况下使用 LoaderCallbacks

安卓加载器 : When and why would the data content in the data-source change?

android - 使用 OnQueryTextListener 刷新 AsyncTaskLoader 的查询