LoaderManager訪問SD裏面的數據庫

首先,需要在項目清單文件中加上訪問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退出時),會調用該方法
 *

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章