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

This Loader class should be static or leaks might occur | Inner class memory leak | AsyncTaskLoader memory leak -

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

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

静态字段会泄漏上下文。非静态内部 classes 具有对其外部 class 的隐式引用。例如,如果那个外部 class 是片段或 Activity,那么这个引用意味着 long-运行 handler/loader/task 将持有对 activity 的引用防止它被垃圾收集。同样,从这些较长的 运行 实例中直接引用活动和片段可能会导致泄漏。 ViewModel classes 永远不应指向视图或非应用程序上下文。"

这是我的应用程序的代码片段:

@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);
}

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

然后从新创建的静态扩展 AsynctaskLoader class。 例如 - public static class ExtendsAysncTaskLoader extend AsynctaskLoader

创建成员变量-游标

为 Class 创建一个带有参数(上下文上下文,游标)的构造函数

使用 super 方法调用父 class 的构造函数并传递上下文。

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

重写 onStartLoading 和 LoadInbackground 并按照 todo 中的解释实现它(但请确保您将使用在新 class 中创建的成员变量)这里是新创建的静态 class.

在onCreateLoader方法中-return新的class参数 例如 - return new ExtendsAysncTaskLoader ( this,Cursor);

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

示例 Class -

    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);


        }

希望对您有所帮助