Android 加载器 onLoadFinished() 立即调用
Android Loaders onLoadFinished() called immediately
我正在使用加载程序实现网络通信...因为大多数人都推荐它并且 "they are lifecycle aware"。
但在我的例子中,我扩展了 AsyncTaskLoader
覆盖了 loadInBackground()
etc.etc。
最后 onLoadFinished()
被正常调用。
但是我的问题出现在网络错误的情况下。如果数据为空
onLoadFinished()
被立即调用,没有网络调用。
根据 google 文档:
In either case, the given callback is associated with the loader, and
will be called as the loader state changes. If at the point of call
the caller is in its started state, and the requested loader already
exists and has generated its data, then callback
onLoadFinished(Loader, D) will be called immediately (inside of this
function), so you must be prepared for this to happen.
这是我必须要处理的事情吗,使用标志跟踪并下次在我的 activity 中调用 restartLoader()
而不是 initLoader()
。或者我做错了什么。
我在下面发布我的代码的重要部分:
In Main Activity:
protected void postJson(int loaderId, Parcelable object, boolean loadOffline) {
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.OBJ, object);
bundle.putBoolean(Constants.OFFLINE, loadOffline);
loaderManager.initLoader(loaderId, bundle, this);
}
NetworkAsyncTaskLoader
@Override
public Result loadInBackground() {
Constants.verbose("loadInBackground Called");
.....
Response tempResult;
try {
tempResult = loadFromNetwork();
........
} catch (IOException e) {
Constants.error("Network Error for loader Id: " + loaderId, e);
return null;
}
}
@Override
public void deliverResult(Result result) {
Constants.verbose("deliverResult called");
super.deliverResult(result);
}
onLoadFinished()
in Activity
@Override
public void onLoadFinished(Loader loader, NetworkAsyncTaskLoader.Result data) {
hideProgress();
Constants.debug("Load finished for: " + loader.getId());
.....
}
下面是堆栈跟踪..
07-31 10:08:02.177 27677-28061/com.sample.test D/OkHttp: <-- HTTP FAILED: java.net.ConnectException: Failed to connect to ...
07-31 10:08:02.179 27677-28061/com.sample.test E/Test: Network Error for loader Id: 101
java.net.ConnectException: Failed to connect to ...
07-31 10:08:02.192 27677-27677/com.sample.test V/Test: deliverResult called
07-31 10:08:02.193 27677-27677/com.sample.test D/Test: Load finished for: 101
07-31 10:08:08.982 27677-27677/com.sample.test D/Test: Load finished for: 101
下次调用initLoader()
或尝试发起网络调用时你会看到..它直接调用onLoadFinished()
Update:
好吧,我最后创建了一个标志,如果出现网络错误或出现问题,该标志设置为 false,然后如果标志为 true,则调用 restartLoader()
。
调用 deliverResult()
后,数据 "pushed out" 到 onLoadFinished()
回调方法,这是设计的。
如果你调用 deliverResult(null)
你基本上是说你的结果是空的,从 LoaderManager 的角度来看 - 你的 Loader 完成了他的工作,他 "doesn't care" 关于空值。
TL;DR - 是的,您需要自己处理空结果并调用 restartLoader()
再次使您的 Loader 运行。
我正在使用加载程序实现网络通信...因为大多数人都推荐它并且 "they are lifecycle aware"。
但在我的例子中,我扩展了 AsyncTaskLoader
覆盖了 loadInBackground()
etc.etc。
最后 onLoadFinished()
被正常调用。
但是我的问题出现在网络错误的情况下。如果数据为空
onLoadFinished()
被立即调用,没有网络调用。
根据 google 文档:
In either case, the given callback is associated with the loader, and will be called as the loader state changes. If at the point of call the caller is in its started state, and the requested loader already exists and has generated its data, then callback onLoadFinished(Loader, D) will be called immediately (inside of this function), so you must be prepared for this to happen.
这是我必须要处理的事情吗,使用标志跟踪并下次在我的 activity 中调用 restartLoader()
而不是 initLoader()
。或者我做错了什么。
我在下面发布我的代码的重要部分:
In Main Activity:
protected void postJson(int loaderId, Parcelable object, boolean loadOffline) {
Bundle bundle = new Bundle();
bundle.putParcelable(Constants.OBJ, object);
bundle.putBoolean(Constants.OFFLINE, loadOffline);
loaderManager.initLoader(loaderId, bundle, this);
}
NetworkAsyncTaskLoader
@Override
public Result loadInBackground() {
Constants.verbose("loadInBackground Called");
.....
Response tempResult;
try {
tempResult = loadFromNetwork();
........
} catch (IOException e) {
Constants.error("Network Error for loader Id: " + loaderId, e);
return null;
}
}
@Override
public void deliverResult(Result result) {
Constants.verbose("deliverResult called");
super.deliverResult(result);
}
onLoadFinished()
in Activity
@Override
public void onLoadFinished(Loader loader, NetworkAsyncTaskLoader.Result data) {
hideProgress();
Constants.debug("Load finished for: " + loader.getId());
.....
}
下面是堆栈跟踪..
07-31 10:08:02.177 27677-28061/com.sample.test D/OkHttp: <-- HTTP FAILED: java.net.ConnectException: Failed to connect to ...
07-31 10:08:02.179 27677-28061/com.sample.test E/Test: Network Error for loader Id: 101
java.net.ConnectException: Failed to connect to ...
07-31 10:08:02.192 27677-27677/com.sample.test V/Test: deliverResult called
07-31 10:08:02.193 27677-27677/com.sample.test D/Test: Load finished for: 101
07-31 10:08:08.982 27677-27677/com.sample.test D/Test: Load finished for: 101
下次调用initLoader()
或尝试发起网络调用时你会看到..它直接调用onLoadFinished()
Update:
好吧,我最后创建了一个标志,如果出现网络错误或出现问题,该标志设置为 false,然后如果标志为 true,则调用 restartLoader()
。
调用 deliverResult()
后,数据 "pushed out" 到 onLoadFinished()
回调方法,这是设计的。
如果你调用 deliverResult(null)
你基本上是说你的结果是空的,从 LoaderManager 的角度来看 - 你的 Loader 完成了他的工作,他 "doesn't care" 关于空值。
TL;DR - 是的,您需要自己处理空结果并调用 restartLoader()
再次使您的 Loader 运行。