我在使用AsyncTaskLoader时遇到了问题。这是我第一次尝试使用加载程序从ListView数据库中填充SQLite数据库。
一切看起来都很好,当我旋转屏幕时,数据被缓存,不再执行查询。但是当我按下“主页”按钮并再次启动我的应用程序时,数据就会再次加载。
Note:Usuario的意思是User,所以我正在用用户列表填充ListView。
public class Main extends SherlockFragmentActivity
implements LoaderManager.LoaderCallbacks<ArrayList<Usuario>> {
UsuarioAdapter adapter;
ListView listView;
Database db;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
listView = (ListView) findViewById(R.id.lista);
db = new Database(this);
adapter = new UsuarioAdapter(this, new ArrayList<Usuario>());
listView.setAdapter(adapter);
getSupportLoaderManager().initLoader(0, null, this);
}
@Override
public Loader<ArrayList<Usuario>> onCreateLoader(int id, Bundle args) {
return new UsuariosLoader(this, db);
}
@Override
public void onLoadFinished(Loader<ArrayList<Usuario>> loader,
ArrayList<Usuario> usuarios) {
//adapter.notifyDataSetChanged();
listView.setAdapter(new UsuarioAdapter(this, usuarios));
// ((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}
@Override
public void onLoaderReset(Loader<ArrayList<Usuario>> loader) {
listView.setAdapter(null);
}
}
// THE LOADER
class UsuariosLoader extends AsyncTaskLoader<ArrayList<Usuario>> {
private ArrayList<Usuario> usuarios;
private Database db;
public UsuariosLoader(Context context, Database db) {
super(context);
this.db = db;
}
@Override
protected void onStartLoading() {
if (usuarios != null) {
deliverResult(usuarios); // Use the cache
}
forceLoad();
}
@Override
protected void onStopLoading() {
// The Loader is in a stopped state, so we should attempt to cancel the
// current load (if there is one).
cancelLoad();
}
@Override
public ArrayList<Usuario> loadInBackground() {
db.open(); // Query the database
ArrayList<Usuario> usuarios = db.getUsuarios();
db.close();
return usuarios;
}
@Override
public void deliverResult(ArrayList<Usuario> data) {
usuarios = data; // Caching
super.deliverResult(data);
}
@Override
protected void onReset() {
super.onReset();
// Stop the loader if it is currently running
onStopLoading();
// Get rid of our cache if it exists
usuarios = null;
}
@Override
public void onCanceled(ArrayList<Usuario> data) {
// Attempt to cancel the current async load
super.onCanceled(data);
usuarios = null;
}
}我觉得这个片段做得不好。我正在创建一个新的适配器,而不是更新数据。
@Override
public void onLoadFinished(Loader<ArrayList<Usuario>> loader,
ArrayList<Usuario> usuarios) {
//adapter.notifyDataSetChanged();
listView.setAdapter(new UsuarioAdapter(this, usuarios));
//((BaseAdapter) listView.getAdapter()).notifyDataSetChanged();
}为什么adapter.notifyDataSetChanged()不能工作?
因此,基本上,我的应用程序不会崩溃,但每次重新启动应用程序时,我的所有数据都会重新加载。
编辑:这是我的适配器代码:
class UsuarioAdapter extends BaseAdapter {
private ArrayList<Usuario> usuarios;
private LayoutInflater inflater;
public UsuarioAdapter(Context context, ArrayList<Usuario> usuarios) {
this.usuarios = usuarios;
this.inflater = LayoutInflater.from(context);
}
@Override
public int getCount() { return usuarios.size(); }
@Override
public Object getItem(int pos) { return usuarios.get(pos); }
@Override
public long getItemId(int pos) { return pos; }
@Override
public View getView(int pos, View convertView, ViewGroup arg) {
LinearLayout itemView;
if (convertView == null) {
itemView = (LinearLayout) inflater.inflate(R.layout.list_item, null);
} else {
itemView = (LinearLayout) convertView;
}
ImageView avatar = (ImageView) itemView.findViewById(R.id.avatar);
TextView nombre = (TextView) itemView.findViewById(R.id.nombre);
TextView edad = (TextView)itemView.findViewById(R.id.edad);
// Set the image ... TODO
nombre.setText(usuarios.get(pos).getNombre());
edad.setText(String.valueOf(usuarios.get(pos).getEdad()));
return itemView;
}
}发布于 2013-07-05 18:03:19
我找到了解决办法。onStartLoading是有罪的:
@Override
protected void onStartLoading() {
if (usuarios != null) {
deliverResult(usuarios); // Use cache
} else {
forceLoad();
}
}在我最初的帖子中,forceLoad总是被称为。它一定在else分支中。
发布于 2013-07-05 12:47:18
对notifyDataSetChanged()的调用不会更改适配器正在使用的数据。您需要更新适配器所拥有的数据,然后调用该方法。
NotifyDataSetChanged()只会告诉适配器它需要创建它的视图,但是它不会更改数据。你得自己处理。
在适配器中添加:
public void setUsuario(List<Usuario> usuarios) {
this.usuarios = usuarios;
}然后在onLoadFinished()中调用新方法,然后调用notifyDataSetChanged()。
listView.getAdapter().setUsuario(usuarios);
listView.getAdapter().notifiyDataSetChanged();https://stackoverflow.com/questions/17489145
复制相似问题