Android AsyncTaskLoader第三个任务消失
我正在尝试实现一个列表/详细信息工作流,其中点击列表项会导致详细信息部分加载与新选定行相关的数据。我正试图使用Android AsyncTaskLoader第三个任务消失,android,android-loadermanager,asynctaskloader,android-loader,Android,Android Loadermanager,Asynctaskloader,Android Loader,我正在尝试实现一个列表/详细信息工作流,其中点击列表项会导致详细信息部分加载与新选定行相关的数据。我正试图使用AsyncTaskLoader来实现这一点。我遇到了一个问题,如果我在一行中足够快地点击三个列表项,实际上只有两个加载发生,第三个加载丢失 我已经编写了一个示例活动来演示这种行为。当点击按钮三次时,loadInBackground()方法只会被调用两次。我是不是错过了一个电话 public final class LoaderActivity extends Activity imple
AsyncTaskLoader
来实现这一点。我遇到了一个问题,如果我在一行中足够快地点击三个列表项,实际上只有两个加载发生,第三个加载丢失
我已经编写了一个示例活动来演示这种行为。当点击按钮三次时,loadInBackground()
方法只会被调用两次。我是不是错过了一个电话
public final class LoaderActivity extends Activity implements LoaderManager.LoaderCallbacks<Integer> {
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.loader);
button = (Button) findViewById(R.id.load_button);
getLoaderManager().initLoader(0, null, this);
}
public void onButtonClick(View source) {
Loader<Integer> loader = getLoaderManager().getLoader(0);
if (loader != null) {
loader.forceLoad();
}
}
@Override
public Loader<Integer> onCreateLoader(int id, Bundle args) {
return new IntLoader(this);
}
@Override
public void onLoadFinished(Loader<Integer> listLoader, Integer data) {
button.setText(String.valueOf(data));
}
@Override
public void onLoaderReset(Loader<Integer> listLoader) {
}
private static final class IntLoader extends AsyncTaskLoader<Integer> {
private static final AtomicInteger counter = new AtomicInteger(0);
IntLoader(Context context) {
super(context);
}
@Override
public Integer loadInBackground() {
int result = counter.getAndIncrement();
// Simulate a potentially expensive web call
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
return result;
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
onStopLoading();
}
@Override
public void deliverResult(Integer data) {
if (isStarted()) {
super.deliverResult(data);
}
}
}
}
公共最终类LoaderActivity扩展活动实现LoaderManager.LoaderCallbacks{
私人按钮;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.loader);
按钮=(按钮)findViewById(R.id.load_按钮);
getLoaderManager().initLoader(0,null,this);
}
公共作废按钮单击(查看源){
Loader Loader=getLoaderManager().getLoader(0);
if(加载程序!=null){
loader.forceLoad();
}
}
@凌驾
公共加载器onCreateLoader(int-id,Bundle-args){
返回新的IntLoader(此);
}
@凌驾
public void onLoadFinished(加载器listLoader,整数数据){
button.setText(String.valueOf(data));
}
@凌驾
public void onLoaderReset(加载程序列表加载程序){
}
私有静态最终类IntLoader扩展了AsyncTaskLoader{
私有静态最终AtomicInteger计数器=新的AtomicInteger(0);
IntLoader(上下文){
超级(上下文);
}
@凌驾
公共整数loadInBackground(){
int result=counter.getAndIncrement();
//模拟一个可能昂贵的web调用
试一试{
睡眠(5000);
}捕捉(中断异常e){
}
返回结果;
}
@凌驾
受保护的无效onStopLoading(){
取消加载();
}
@凌驾
受保护的void onReset(){
onStopLoading();
}
@凌驾
公共void deliverResult(整数数据){
如果(isStarted()){
super.deliverResult(数据);
}
}
}
}
调用restartLoader(0,null,this)
而不是onButtonClick()
方法中的getLoader(0)
似乎解决了这个问题。随着我对Loader
s的了解越来越多,调用它似乎是更合适的方法,因为我想在这一点上放弃任何旧的结果。您确定该方法只被调用了两次吗?或者消息可能被调用了3次,但只有2次用户界面被调用setText
更新<默认情况下,code>onLoadFinished未与UI线程同步,这就是我感到奇怪的原因。绝对可以肯定的是,loadInBackground()
只被调用了两次-我在loadInBackground()
的开头设置了一个断点。(好吧,事实上我不是100%确定onLoadFinished
是否在主UI线程上被调用…这似乎是一个混乱的来源,因为Commonware和Reto-Meier在他们的书中都站在相反的一边哈哈…我会就此回复你。)顺便问一句,你不应该调用forceLoad()吗
在onStartLoading
中?当活动启动时,实际上没有什么可以加载的。直到选择了列表项(或者在我设计的示例中点击了按钮),才需要进行实际加载。我还是应该从onStartLoading()
调用forceLoad()
?