正如标题所说的那样,我在点击按钮时开始Loader
,然后我正在进行方向更改。在重新创建的活动中,onLoadFinished
在启动时不会自动调用。我怀疑LoaderManager
不知道这个新创建的活动实例,因为我不认为它与活动生命周期紧密相关。但我可能错了......
这是加载器,提供一个字符串数组并模拟它延迟数据结果3秒。实施是AsyncTaskLoader
sample code的简化版。
import android.content.Context;
import android.support.v4.content.AsyncTaskLoader;
public class ContentAsyncLoader extends AsyncTaskLoader<String[]> {
private String[] data;
public ContentAsyncLoader(Context context) {
super(context);
}
@Override
protected void onStartLoading() {
if (data != null) {
deliverResult(data);
} else {
forceLoad();
}
}
@Override
public String[] loadInBackground() {
synchronized (this) {
try {
wait(3000);
} catch (InterruptedException e) {
}
}
final String[] result = { "Dell Inspiron", "HTC One X", "HTC Wildfire S", "HTC Sense", "HTC Sensation XE", "iPhone 4S", "Samsung Galaxy Note 800", "Samsung Galaxy S3", "MacBook Air",
"Mac Mini", "MacBook Pro" };
return result;
}
@Override
protected void onStopLoading() {
cancelLoad();
}
@Override
protected void onReset() {
super.onReset();
onStopLoading();
data = null;
}
@Override
public void deliverResult(String[] data) {
if (isReset()) {
return;
}
this.data = data;
if (isStarted()) {
super.deliverResult(data);
}
}
}
以下是按钮点击启动加载程序的活动 - ListView
和Button
:
public class MainActivity extends FragmentActivity implements OnClickListener, LoaderCallbacks<String[]> {
private static final int LOADER_ID = 1;
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.list_view);
findViewById(R.id.btnSomeAction).setOnClickListener(this);
}
@Override
public void onClick(View v) {
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
@Override
public Loader<String[]> onCreateLoader(int id, Bundle bundle) {
ContentAsyncLoader loader = new ContentAsyncLoader(this);
return loader;
}
@Override
public void onLoaderReset(Loader<String[]> loader) {
}
@Override
public void onLoadFinished(Loader<String[]> loader, String[] data) {
if (data != null) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1, data);
lv.setAdapter(adapter);
}
}
}
如果有人想要一个明确的问题:如何正确使用按钮点击启动的Loader
,以便在重新创建活动时自动重新提供数据?
我有一些肮脏的解决方法,通过在单击按钮时将标志设置为true来解决此问题,在调用onSaveInstanceState
时将其保存,然后在onCreate
中检查它是否存在,如果存在则致电initLoader
;但我讨厌在这种情况下有这个,当我从一个活动开始不同的加载器时,我需要为每个这样的加载器保留一个标志,因为我倾向于懒惰...例如:
private boolean loaderCreated;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.list_view);
findViewById(R.id.btnSomeAction).setOnClickListener(this);
if (savedInstanceState != null) {
loaderCreated = savedInstanceState.getBoolean("TEMP", false);
if(loaderCreated) {
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putBoolean("TEMP", loaderCreated);
}
@Override
public void onClick(View v) {
loaderCreated = true;
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
}
有没有更好的方法呢?
答案 0 :(得分:3)
getSupportLoaderManager().initLoader(LOADER_ID, null, this);
都应调用onCreate
。
因为现在在方向savedInstanceState
不为空并且您没有向加载程序询问数据之后。
我看到你做到了......;)而这只是唯一的方式。
此致