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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了此Loader类应该是静态的,否则可能会发生泄漏内部类内存泄漏| AsyncTaskLoader内存泄漏 -相关的知识,希望对你有一定的参考价值。

我在android studio中的AsyncTaskLoader周围收到以下警告:

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

静态字段将泄漏上下文。非静态内部类具有对其外部类的隐式引用。如果该外部类例如是片段或活动,则此引用意味着长时间运行的处理程序/加载器/任务将保留对活动的引用,从而阻止其收集垃圾。同样,对来自这些较长时间运行的实例的活动和片段的直接字段引用可能会导致泄漏。 ViewModel类永远不应该指向视图或非应用程序上下文。“

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

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

解决方案是创建另一个类并使其静态。

然后从新的Created Static类中扩展AsynctaskLoader。 Ex - 公共静态类ExtendsAysncTaskLoader扩展了AsynctaskLoader

创建成员变量 - Cursor

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

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

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

覆盖onStartLoading和LoadInbackground,并按照todo中的说明实现它(但一定要使用在新类中创建的成员变量),这里是新创建的静态类。

在onCreateLoader方法中 - 返回带有参数Ex的新类 - 返回new 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);


        }

希望这可以帮助

以上是关于此Loader类应该是静态的,否则可能会发生泄漏内部类内存泄漏| AsyncTaskLoader内存泄漏 -的主要内容,如果未能解决你的问题,请参考以下文章

Android Threading:这个 Handler 类应该是静态的,否则可能会发生泄漏[重复]

Android中用于kotlin的静态等价物,以避免处理程序内存泄漏

静态内部类解决内存泄漏

内存泄漏和内存溢出

qthreadnew不释放

Java内存泄漏的几种可能