Loader监听数据源的变化

步骤:

1.新建一个继承SQLiteOpenHelper的帮助类

2.在MainActivity中定义LoaderManager和SimpleCursorAdapter

3.按顺序重写如下方法:initLoader来启动

onCreateLoader->onStartLoading(forceLoad启动时强制加载)->loadInBackground->onLoadFinished(adapter.swapCursor(data))->onLoaderReset(adapter.swapCursor(null))

*manager.restartLoader()数据改变时立刻加载

public class DBHelper extends SQLiteOpenHelper {
    public static final String USERTABLE = "usertable";
    private static final String DBNAME = "QF.DB";
    private static final int CURRENTVERSION = 1;

    public DBHelper(Context context) {
        super(context, DBNAME, null, CURRENTVERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE IF NOT EXISTS " + USERTABLE + "(_id INTEGER PRIMARY KEY AUTOINCREMENT" +
                ",USERNAME,NICKNAME);");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}
/**
 * Loader:自动监听数据源是否发生变化
 */
public class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {

    private static SQLiteDatabase db;
    private DBHelper dbHelper;
    private SimpleCursorAdapter adapter;
    private LoaderManager manager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        dbHelper = new DBHelper(this);
        db = dbHelper.getReadableDatabase();
        ListView listView = (ListView) findViewById(R.id.lv);
        // 1.获得一个Loader管理器
        manager = getSupportLoaderManager();
        //2.初始化Loader
        //1.Loader的唯一标识符
        //2.初始化Loader时传递的参数
        //3.Loader的回调
        manager.initLoader(1, null, this);
        //最后一个参数表示当数据源发生改变时,Cursor能够立马感知到数据源发生变化
        adapter = new SimpleCursorAdapter(this,
                R.layout.listview_item, null, new String[]{"USERNAME"}, new int[]{R.id.username},
                CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
        listView.setAdapter(adapter);
    }

    //当Loader创建时回调
    //1.Loader的id
    //2.初始化Loader的参数
    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
        Log.d("lenve", "onCreateLoader: " + Thread.currentThread());
        return new MyLoader(this);
    }

    //当异步加载完成时调用该方法
    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
        Log.d("lenve", "onLoadFinished: " + Thread.currentThread());
        //交换Cursor
        adapter.swapCursor(data);
    }

    //当由于Loader重置导致Cursor失效时,调用该方法
    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        Log.d("lenve", "onLoaderReset: " + Thread.currentThread());
        adapter.swapCursor(null);
    }

    public void addData(View view) {
        ContentValues values = new ContentValues();
        values.put("USERNAME", "李四i");
        db.insert(DBHelper.USERTABLE, null, values);
        //重启Loader
        manager.restartLoader(1, null, this);
    }

    static class MyLoader extends AsyncTaskLoader<Cursor> {

        public MyLoader(Context context) {
            super(context);
        }

        //在后台线程执行
        @Override
        public Cursor loadInBackground() {
            Log.d("lenve", "loadInBackground: " + Thread.currentThread());
            Cursor cursor = db.rawQuery("SELECT * FROM " + DBHelper.USERTABLE, null);
            //在这里放回一个Cursor,该Cursor最终被onLoadFinished()方法接收到
            return cursor;
        }

        //开始加载时调用
        @Override
        protected void onStartLoading() {
            super.onStartLoading();
            Log.d("lenve", "onStartLoading: " + Thread.currentThread());
            //第一次需要强制加载
            forceLoad();
        }
    }
}

 其中,适配器可以定义一个继承CursorAdapter的类,和baseAdapter的道理类似;且cursorAdapter的两个方法newView和bindView相当于BaseAdapter的getView方法的拆分

/**
 * newView和bindView相当于BaseAdapter中的getView()方法
 */
public class MyAdapter extends CursorAdapter {
    private LayoutInflater inflater;

    public MyAdapter(Context context, Cursor c, int flags) {
        super(context, c, flags);
        inflater = LayoutInflater.from(context);
    }

    //初始化View
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = inflater.inflate(R.layout.listview_item, null);
        ViewHolder holder = new ViewHolder();
        holder.username = (TextView) view.findViewById(R.id.username);
        view.setTag(holder);
        return view;
    }

    //给View上的控件绑定事件
    //cursor.getColumnIndex("USERNAME")获取USERNAME字段的下标
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();
        holder.username.setText(cursor.getString(cursor.getColumnIndex("USERNAME")));
    }

    class ViewHolder {
        TextView username;
    }
}