AsyncTaskLoader(異步裝載)對sqlite數據庫刪改操做

效果圖示例:java

 

 

 

 

 

 

 

 

 

 

一、在配置清單裏配置須要的權限android

 

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
sql

 

 

 

 

//res/layout下3個佈局activity_main.xml和dialoug_update_main.xml和item_listview.xml佈局數據庫

 

 

二、activity_main.xml佈局異步

 

代碼ide

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >函數

    <ListView
        android:id="@+id/listView_main_titlelist"
        android:layout_width="match_parent"
        android:layout_height="match_parent" >
    </ListView>工具

</LinearLayout>佈局

 

 

 

==============ui

 

 

三、dialoug_update_main.xml佈局

 

代碼

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
   
 <TextView
        android:id="@+id/text_dialog_id"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />
 
    <EditText
        android:id="@+id/editText_dialog_name"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint=""
        android:ems="10" >

        <requestFocus />
    </EditText>

   <EditText
        android:id="@+id/editText_dialog_age"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint=""
        android:ems="10" >
    </EditText>

</LinearLayout>

 

 

 


================

 

四、item_listview.xml佈局

 

代碼

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/text_item_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

    <TextView
        android:id="@+id/text_item_age"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TextView" />

</LinearLayout>

 

 


======================

 

 

 

五、res下建立一個menu菜單文件夾 菜單文件夾一個list_menu.xml菜單佈局

 

代碼

 

 

 

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/list_delete"
        android:title="刪除"/>
    <item
        android:id="@+id/list_change"
        android:title="修改"/>
    <item
        android:id="@+id/list_no"
        android:title="不操做"/>

</menu>

 

 

 

 

==================

 

 

 

//2個java源文件MainActivity.java類和對sqlite數據給操做工具類Sqlite_operate_utils.java

 

六、Sqlite_operate_utils.java工具類

 

代碼

 

 

 

public class Sqlite_operate_utils {

 private static String DB_PATH = Environment.getExternalStorageDirectory() + File.separator + "studentinfo2.db";
 private SQLiteDatabase db;
 
 //構造函數 new 該類的時候 就去找 須要找的 數據庫
 public Sqlite_operate_utils() {
  db = SQLiteDatabase.openDatabase(DB_PATH, null, SQLiteDatabase.OPEN_READWRITE);
 }
 
 //查詢 數據的 方法1
 public Cursor sqlite_select(String content, String[] condition){
  return db.rawQuery(content, condition);
 }
 
 //查詢 數據 的 方法2
 public List<Map<String, String>> sqlite_selectlist(String content, String[] condition){
  Log.i("data", "cursor:");
  Cursor cursor = db.rawQuery(content, condition);
  return cursorToList(cursor);
 }
 //返回List
 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));
   }
   list.add(map);
  }
  cursor.close();
  Log.i("data", "list:" + list.size());
  return list;
 }
 
 //增刪改 的方法
 //返回布爾型 方便 查看 數據 操做 是否成功
 public boolean executeData(String execute_content, Object[] bindArgs){
  try {
   if(bindArgs == null){//要綁定佔位符 的參數值
    db.execSQL(execute_content);
    return true;
   }else{
    db.execSQL(execute_content, bindArgs);
    return true;
   }
  } catch (SQLException e) {
   e.printStackTrace();
   return false;
  }
 }
 
 //關閉db
 public void destroy(){
  if(db != null){
   db.close();
  }
 }
}

 

 

 


==================

 

 

 

七、MainActivity.java類

 

代碼

 

 

public class MainActivity extends FragmentActivity implements
  LoaderCallbacks<Cursor> {

 private ListView listView;
 private static Cursor cursor;
 private static SimpleCursorAdapter adapter;// 自定義遊標適配器
 private LoaderManager loaderManager;// 裝載管理器對象聲明
 private static Sqlite_operate_utils sql;// 對數據庫操做的工具類對象

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  this.listView = (ListView) this
    .findViewById(R.id.listView_main_titlelist);

  sql = new Sqlite_operate_utils();
  loaderManager = getSupportLoaderManager();// 獲取裝載管理器
  // 用裝載管理器來獲取數據初始化加載器
  // initLoader -- 若是當前沒有加載器就調用onCreateLoader建立一個 有就根據第一個參數標誌重複利用
  // 第一個參數 -- 加載器的標誌 隨便寫
  // 第二個參數 -- Bundle -- 用來傳遞數據 沒有能夠寫null
  // 第三個參數 -- LoaderCallbacks 對象
  loaderManager.initLoader(1, null, this);
  // 最後一個參數 標誌 能夠用CursorAdapter.出來
  //若是是FLAG_REGISTER_CONTENT_OBSERVER標誌 則適配器會在Cursor上註冊一個內容觀察者
  ///該觀察者會時時刻刻觀察內容的變更 若是通知到達時就調用onContentChanged()方法
  adapter = new SimpleCursorAdapter(this, R.layout.item_listview, cursor,
    new String[] { "s_name", "s_age" }, new int[] {
      R.id.text_item_name, R.id.text_item_age },
    CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
  listView.setAdapter(adapter);
  // 註冊上下文菜單
  registerForContextMenu(listView);
 }

 // 建立一個上下文菜單
 @Override
 public void onCreateContextMenu(ContextMenu menu, View v,
   ContextMenuInfo menuInfo) {
  super.onCreateContextMenu(menu, v, menuInfo);
  AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
  long id = adapter.getItemId(info.position);
  menu.setHeaderIcon(R.drawable.ic_launcher);
  menu.setHeaderTitle(id + "");

  getMenuInflater().inflate(R.menu.list_menu, menu);
 }

 // 上下文菜單監聽
 @Override
 public boolean onContextItemSelected(MenuItem item) {
  AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
    .getMenuInfo();
  final long item_id = adapter.getItemId(info.position);
  switch (item.getItemId()) {
  case R.id.list_delete:
   // 彈出一個警告框提示用戶是否刪除
   AlertDialog.Builder builder = new AlertDialog.Builder(this);
   builder.setTitle(item_id + "");
   builder.setIcon(R.drawable.ic_launcher);
   builder.setMessage("肯定刪除" + item_id + "信息?");
   builder.setNegativeButton("取消", null);
   builder.setPositiveButton("肯定", new OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
     // 若是肯定就去數據庫刪除數據
     boolean result = sql.executeData(
       "delete from student where s_id = ?",
       new String[] { item_id + "" });
     if (result) {
      // 若是刪除成功就用LoaderManager調用restartLoader方法從新加載數據
      loaderManager.restartLoader(1, null, MainActivity.this);
     }
    }
   });
   builder.show();
   break;
  case R.id.list_change:
   AlertDialog.Builder builder2 = new AlertDialog.Builder(this);
   builder2.setIcon(R.drawable.ic_launcher);
   builder2.setTitle("修改數據");
   View view = LayoutInflater.from(this).inflate(R.layout.dialoug_update_main, null);
   final TextView id = (TextView) view
     .findViewById(R.id.text_dialog_id);
   Log.i("data", "0000000");
   final EditText name = (EditText) view
     .findViewById(R.id.editText_dialog_name);
   final EditText age = (EditText) view
     .findViewById(R.id.editText_dialog_age);
   builder2.setView(view);
   // 獲取用戶選擇的數據填充到修改框
   // 查詢數據庫
   cursor = sql.sqlite_select(
     "select s_id _id,s_name,s_age from student where s_id = ?",
     new String[] { item_id + "" });
   cursor.moveToFirst();

   id.setText(item_id + "");
   name.setText(cursor.getString(cursor.getColumnIndex("s_name")));
   age.setText(cursor.getString(cursor.getColumnIndex("s_age")));
   cursor.close();
   // 肯定按鈕的事件監聽
   builder2.setPositiveButton("肯定", new OnClickListener() {
    @Override
    public void onClick(DialogInterface dialog, int which) {
     // 獲取修改框的信息
     String update_id = id.getText().toString();
     String update_name = name.getText().toString();
     String update_age = age.getText().toString();
     String execute_content = "update student set s_name = ?,s_age = ? where s_id = ?";
     Object[] bindArgs = { update_name, update_age, update_id };
     // 更新數據庫
     boolean result = sql.executeData(execute_content, bindArgs);
     if (result) {
      // 修改數據成功就用加載管理器調用restartLoader方法從新查詢數據
      loaderManager.restartLoader(1, null, MainActivity.this);
     }
    }
   });
   builder2.show();
   break;
  }
  return super.onContextItemSelected(item);
 }

 // --------------------繼承AsyncTaskLoader類要重寫的方法--------------------------------
 // 繼承了異步裝載類 若是是內部類 就必需要靜態 否則 會報錯
 static class MyAsynTaskLoader extends AsyncTaskLoader<Cursor> {
  // 繼承AsyncTaskLoader類 的類 沒有無慘構造函數
  public MyAsynTaskLoader(Context context) {
   super(context);
  }

  @Override
  protected void onStartLoading() {
   super.onStartLoading();
   // 調用forceLoad()方法 能夠依次調用下一次 即將要執行的方法
   forceLoad();
  }

  @Override
  // 子線程進行
  public Cursor loadInBackground() {
   // 查找數據庫 須要的數據
   // 注意:用SimpleCursorAdapter適配器 查詢必需要有_id
   cursor = sql.sqlite_select(
     "select s_id _id,s_name,s_age from student", null);
   return cursor;
  }

  @Override//執行跟適配器的交換操做
  public void deliverResult(Cursor data) {
   super.deliverResult(data);
   // 新舊cursor交換
   adapter.swapCursor(data);
  }
 }

 // ----------繼承LoaderCallbacks接口要重寫的方法---------------
 @Override
 // 建立一個Loader
 public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
  return new MyAsynTaskLoader(this);
 }

 @Override
 // Loader建立完成
 public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
                 adapter.swapCursor(cursor);
 }

 @Override // 當一個加載器給重置時 調用 public void onLoaderReset(Loader<Cursor> loader) {  adapter.swapCursor(null); }}

相關文章
相關標籤/搜索