首先,需要在项目清单文件中加上访问SD卡的权限: android.permission.WRITE_EXTERNAL_STORAGE
public class MainActivity extends FragmentActivity {
private String url="content://com.mma/student/";//uri
private ContentResolver resolver;//客户端
private ListView listview;//视图列表
private SimpleCursorAdapter adapter;//适配器(数据库)
private LoaderManager manager;
private EditText e1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.listview);
e1=(EditText) findViewById(R.id.e1);
resolver=getContentResolver();//创建客户端
adapter=new SimpleCursorAdapter(MainActivity.this,//创建适配器(数据库)
android.R.layout.simple_list_item_2,// 布局
null, //数据库的游标(为空)
new String[]{"name","age"}, //数据库对应的字段字符串数组
new int[]{android.R.id.text1,android.R.id.text2},//布局里面的控件id数组
0);
listview.setAdapter(adapter);//在界面显示
manager=getSupportLoaderManager();//获得LoaderManager对象
manager.initLoader(
1,//参数1:Loader唯一的id(自定义)
null,//参数2: 传递给Loader的参数(没有就写null)
new MyCallback());//参数3:泛型为Cursor的Loader的回调
}
public void mma(View view){
String str=e1.getText().toString();//获得编辑框的输入
Bundle bundle=new Bundle();
bundle.putString("str", str);
//重新加载Loader
manager.restartLoader(1, bundle, new MyCallback());
}
//Loader加载的回调接口 LoaderManager.LoaderCallbacks<T>
//因为要通过异步任务获得数据库的Cursor对象(游标),所以泛型写Cursor
class MyCallback implements LoaderManager.LoaderCallbacks<Cursor>{
@Override//回调时,会调用该方法,创建Cursor 返回Loader对象
public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) {
MyLoader loader=new MyLoader(MainActivity.this,arg1);//创建自定义的Loader
return loader;
}
@Override//如果onCreateLoader()方法返回为null,不会调用该方法
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
//此时(调用方法时),已经通过异步任务获取到了数据
adapter.swapCursor(data);
}
@Override//当Loader需要重置时(Activity退出时),会调用该方法
public void onLoaderReset(Loader<Cursor> loader) {
adapter.swapCursor(null);//此时,把适配器里面的数据重置为nulls
}
}
//定义自己的Loader的类(必须为静态修饰的类) 继承AsyncTaskLoader泛型类
static class MyLoader extends AsyncTaskLoader<Cursor>{
private Bundle bundle;
public MyLoader(Context context,Bundle bundle) {
super(context);
this.bundle=bundle;
}
@Override//开始加载时调用该方法
protected void onStartLoading() {//自己重写该方法
super.onStartLoading();
Log.i("loadInBackground", "进入onStartLoading方法........");
forceLoad();//强迫进入子线程加载操作
}
@Override//子线程执行该方法
public Cursor loadInBackground() {
Log.i("loadInBackground", "子线程来了.........");
String path="/mnt/sdcard/school.db";//文件的位置
//静态代码块中打开数据库,
SQLiteDatabase db=SQLiteDatabase.openOrCreateDatabase(path, null);
Cursor cursor=null;
if(bundle==null){
cursor=db.query("student",null,null,null,null,null,null);
}else{
String str=bundle.getString("str");
cursor=db.query("student",
null,
"name like ?",
new String[]{str+"%"},//模糊查询
null,null,null);
}
return cursor;
}
}
如果要访问手机SD上面的数据库里面的内容
* 添加访问权限android.permission.WRITE_EXTERNAL_STORAGE
*
* 总结:当程序启动时,需要加载的数据(数据库里面的内容)如果比较多时,可以使用子线程进行加载,
* 这时候就需要使用Loader异步加载类了(获得Cursor对象)
*
* 使用子类:LoaderManager,安卓提供用来管理Loader对象,可以管理多个Loaders
* 获得LoaderManager对象需要继承FragmentActivity类
* 使用getSupportLoaderManager()方法,获得LoaderManager对象(只有一个该对象实例)
*
* LoaderManager对象的initLoader()方法,对Loader进行初始化
* 其中:参数3为LoaderManager.LoaderCallbacks<T> 泛型(指定类型为Cursor)接口的实现类对象
*
* LoaderManager对象的restartLoader()方法,重启Loader
*
*
* 重写里面的方法 :
* 1、onCreateLoader 回调时,会调用该方法(创建Loader对象)
*
* 加载内存中的数据库使用:CursorLoader对象
* 加载外存中的数据库使用:自定义的Loader对象,
* 自定义Loader:继承AsyncTaskLoader<T>泛型抽象类,该类必须为static修饰
* 重写方法:
* onStartLoading 加载时会调用该方法,需要启动子线程,使用forceLoad()方法
* loadInBackground 子线程执行的方法(获取Cursor对象,并且返回)
*
* 2、onLoadFinished 上面的返回值不为空时,会调用该方法
* 3、onLoaderReset 当loader需要重置时(Activity退出时),会调用该方法
*