AsycTaskLoader:數據庫是從外面寫好拖進SD卡的(17)

public class MainActivity extends FragmentActivity implements
		LoaderCallbacks<Cursor> {
	private ListView listview;
	private static SimpleCursorAdapter adapter;
	private LoaderManager loaderManager;// 加載管理器
	private static MySQLiteDatabaseUtils databaseUtils;// 數據庫工具類對象聲明

	// private static Cursor cursor;//不定義去全局,適配器開始給個null,由於下面異步加載能夠返回一cursor

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		listview = (ListView) this.findViewById(R.id.listView_main_titlelist);
		databaseUtils = new MySQLiteDatabaseUtils();

		// 加載管理器用getSupportLoaderManager()方法時要將Activity改成繼承FragmentActivity,版本兼容額問題
		loaderManager = getSupportLoaderManager();

		// initLoader(arg0, arg1, arg2);
		// 第一個參數:加載器標誌,能夠隨便寫如1..第二個是:Bundle,用來傳數據,沒有就寫null
		// 第三個參數是:實現的LoaderCallbacks接口對象,即this
		// 初始化加載器,若是當前沒有加載器,調用onCreateLoader()方法進行建立
		loaderManager.initLoader(1, null, this);

		adapter = new SimpleCursorAdapter(this, R.layout.item_listview, null,
				new String[] { "sname", "score" }, new int[] {
						R.id.text_item_sname, R.id.text_item_score },
				CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
		listview.setAdapter(adapter);
		registerForContextMenu(listview);
	}

	// 上下文菜單
	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		menu.add(menu.NONE, 1, menu.NONE, "刪除");
		menu.add(menu.NONE, 2, menu.NONE, "修改");
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
		long id = adapter.getItemId(info.position);
		menu.setHeaderTitle(id + "");
		menu.setHeaderIcon(R.drawable.ic_launcher);
		super.onCreateContextMenu(menu, v, menuInfo);
	}
//上下文事件
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		final long id = adapter.getItemId(info.position);
		switch (item.getItemId()) {
		case 1:
			String sql = "delete from studentinfo where sid=?";
			boolean result = databaseUtils.executeData(sql, new String[] { id
					+ "" });
			if (result) {
				// 更新數據用異步管理器進行數據更新
				Toast.makeText(this, "刪除成功!", 100).show();
				loaderManager.restartLoader(1, null, this);
			} else {
				Toast.makeText(this, "刪除失敗!", 100).show();
			}
			break;
		case 2:
			AlertDialog.Builder builder = new AlertDialog.Builder(this);
			builder.setTitle("修改數據");
			builder.setIcon(R.drawable.ic_launcher);
			View view = getLayoutInflater().inflate(
					R.layout.dialoug_update_main, null);
			TextView text_id = (TextView) view
					.findViewById(R.id.text_dialog_id);
			final EditText edit_name = (EditText) view
					.findViewById(R.id.editText_dialog_name);
			final EditText edit_score = (EditText) view
					.findViewById(R.id.editText_dialog_score);
			builder.setView(view);
			String sql2 = "select * from studentinfo where sid=?";
			Cursor cursor = databaseUtils.selectCursor(sql2, new String[] { id
					+ "" });
			cursor.moveToFirst();
			text_id.setText(id + "");
			edit_name.setText(cursor.getString(cursor.getColumnIndex("sname")));
			edit_score
					.setText(cursor.getString(cursor.getColumnIndex("score")));
			cursor.close();
			builder.setPositiveButton("肯定", new OnClickListener() {

				@Override
				public void onClick(DialogInterface dialog, int which) {
					String sname = edit_name.getText().toString();
					String score = edit_score.getText().toString();
					String sql = "update studentinfo set sname=?,score=?where sid=?";
					boolean result = databaseUtils.executeData(sql,
							new Object[] { sname, score, id });
					if (result) {
						// 更新數據用異步管理器進行數據更新
						Toast.makeText(MainActivity.this, "修改爲功!", 100).show();
						loaderManager.restartLoader(1, null, MainActivity.this);
					} else {
						Toast.makeText(MainActivity.this, "修改失敗!", 100).show();
					}
				}
			});
			builder.setNegativeButton("取消", null);
			builder.show();
			break;
		}
		return super.onContextItemSelected(item);
	}

	// 注意:若是異步加載是一個內部類,則要定義爲靜態類,不然會報錯,固然在外部定義就不會錯,裏面用到的也要變爲靜態
	// 使用異步加載要繼承AsyncTaskLoader這個類,重寫裏面的方法
	static class MyAsyncTaskLoader extends AsyncTaskLoader<Cursor> {
		// AsyncTaskLoader<Object>裏面的參數能夠是Cursor或list集合等,通常是Cursor
		// 它沒有無參構造方法,因此要一個構造方法,傳入上下文
		public MyAsyncTaskLoader(Context context) {
			super(context);
		}

		@Override
		protected void onStartLoading() {
			// 開始加載,在主線程運行
			super.onStartLoading();
			Log.i("MainActivity", "onStartLoading測試在那個線程運行"
					+ Thread.currentThread().getName());
			forceLoad();// 這裏開始加載什麼都沒有作,可是建議寫上forceLoad()這個方法
			// 即一次調用下一個即將調用的方法(強制加載)
		}

		@Override
		// 加載器開啓後,開啓子線程進行數據加載操做
		public Cursor loadInBackground() {
			// 記得若是是用遊標適配器的時候查詢語句的id要把本身的sid轉換成下劃線的_id至關於(sid as _id)
			String sql = "select sid _id,sname,score from studentinfo";
			Cursor cursor = databaseUtils.selectCursor(sql, null);
			Log.i("MainActivity", "loadInBackground測試在那個線程運行"
					+ Thread.currentThread().getName());
			return cursor;
		}

		@Override
		public void deliverResult(Cursor data) {
			// 在主線程運行
			super.deliverResult(data);
			Log.i("MainActivity", "deliverResult測試在那個線程運行"
					+ Thread.currentThread().getName());
			// 交換新舊cursor交換後實際還有調用notifyDataSetChanged()
			adapter.swapCursor(data);// 這個方法沒有關閉遊標,要想關閉就要返回一個遊標才能關閉
			// adapter.changeCursor(data);// 這個方法比上面的那個好:有兩個好處,實際調用一下方法:
			// 一、調用swapCursor(data)並進行notifyDataSetChanged()2.關閉舊遊標old_cursor.close();
		}
	}

	// AsyncTaskLoader第一步:要實現 LoaderCallbacks<Cursor>接口,並重寫裏面的三個方法

	@Override
	// 返回的是Loader因此要自定義loader類,有兩種:AsyncTaskLoader和CursorLoader,這裏選擇前一種建立
	// 在主線程運行
	public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
		return new MyAsyncTaskLoader(this);

	}

	@Override
	// 在主線程運行
	public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
		// adapter.swapCursor(cursor);// 執行完後能夠再交換,即執行完更新數據,這裏寫交換也行
	}

	@Override
	// 在主線程運行
	public void onLoaderReset(Loader<Cursor> loader) {
		adapter.swapCursor(null);// 執行完後能夠賦空,替換掉
	}
}

//數據庫操做的封裝類
public class MySQLiteDatabaseUtils {
	private static final String dbPtah = Environment
			.getExternalStorageDirectory() + File.separator + "student.db";//數據庫名稱,這個是用第三方軟件手動建的數據庫,而後拖進SD卡的形式
	private SQLiteDatabase db;

	/**
	 * 創建數據庫鏈接的構造方法
	 */
	public MySQLiteDatabaseUtils() {
		db = SQLiteDatabase.openDatabase(dbPtah, null,
				SQLiteDatabase.OPEN_READWRITE);
	}

	/**
	 * 查詢方法一:返回的是遊標
	 * 
	 * @param sql
	 * @param selectionArgs
	 * @return
	 */
	public Cursor selectCursor(String sql, String[] selectionArgs) {
		Cursor cursor = db.rawQuery(sql, selectionArgs);
		return cursor;
	}

	/**
	 * 查詢方法二:返回的是lsit集合
	 * 
	 * @param sql
	 * @param selectionArgs
	 * @return
	 */
	public List<Map<String, String>> selectList(String sql,
			String[] selectionArgs) {
		Cursor cursor = db.rawQuery(sql, selectionArgs);
		return cursorToList(cursor);
	}

	/**
	 * 封裝遊標數據到List
	 * 
	 * @param cursor
	 * @return
	 */
	public List<Map<String, String>> cursorToList(Cursor cursor) {
		List<Map<String, String>> list = new ArrayList<Map<String, String>>();
		while (cursor.moveToNext()) {// 循環的是每一行數據
			Map<String, String> map = new HashMap<String, String>();
			for (int i = 0; i < cursor.getColumnCount(); i++) {// 這個循環的是每一行的列數
				map.put(cursor.getColumnName(i), cursor.getString(i));// 鍵:key:存儲每一行的字段,value:值就是內容
			}
			list.add(map);
		}
		cursor.close();
		return list;
	}

	/**
	 * 增刪查的方法
	 * 
	 * @param sql
	 * @param bindArgs
	 *            :是 sql語句中要綁定(佔位符)的參數值
	 * @return
	 */
	public boolean executeData(String sql, Object[] bindArgs) {
		try {
			if (bindArgs == null) {
				db.execSQL(sql);
			} else {
				db.execSQL(sql, bindArgs);
			}
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
			Log.i("MainActivity", "數據錯誤!!");
			return false;
		}
	}

	// 關閉時銷燬db
	public void destroy() {
		if (db != null) {
			db.close();
		}
	}
}

//主佈局
    <ListView
        android:id="@+id/listView_main_titlelist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>
    
//listview中的自定義佈局
 <TextView
        android:id="@+id/text_item_sname"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <TextView
        android:id="@+id/text_item_score"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
相關文章
相關標籤/搜索