这个 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);
}
希望对您有所帮助
我在 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);
}
希望对您有所帮助