AsyncTaskLoader(异步装载)对sqlite数据库删改操作

原创
2016/02/15 21:10
阅读数 422

效果图示例:

 

 

 

 

 

 

 

 

 

 

1、在配置清单里配置需要的权限

 

 <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"/>

 

 

 

 

//res/layout下3个布局activity_main.xml和dialoug_update_main.xml和item_listview.xml布局

 

 

2、activity_main.xml布局

 

代码

 

<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>

 

 

 

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

 

 

3、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>

 

 

 


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

 

4、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>

 

 


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

 

 

 

5、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

 

6、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();
  }
 }
}

 

 

 


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

 

 

 

7、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);
 }
}



展开阅读全文
打赏
1
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
1
分享
返回顶部
顶部