安卓LoaderManager异步加载数据库
2016-03-01 11:49
232 查看
在UI的主线程中异步加载数据库,使得页面比较流畅,以防止查询数据库的记录比较多或者提取数据库记录使用的时间太长会操作UI主线程的阻塞,从而造成相应异常。Loader不能用于增删改,只能用于数据库的查询操作,可以解决阻塞UI主线程的问题。
整体思路:创建一个继承SQLiteOpenHelper的DBHelper类,在·这个类中声明一个数据库名称和版本号码,在onCreate方法中创建数据库表并执行,在onUpgrade方法中暂时不预处理。创建一个继承ContentProvider的StudentContentProvider类,在这个类中定义内容提供者的增删改查操作。在xml文件中定义一个ListView控件,在activity中声明一个LoaderManager对象,定义一个MyAdapter类,然后声明一个MyAdapter对象,定义一个LoaderManager.LoaderCallbacks<Cursor>匿名内部类对象,并在onCreate方法中实例化这个LoaderManager对象,将匿名内部类对象与这个对象关联,绑定listview。重写onMenuItemSelected这个方法,在这个方法中设置点击各个item弹出的删除和添加的操作,在这两个操作中都需要用到内容解析者来调用增删改查方法操作数据,操作完成后要使用Loader重新查询数据,即进行数据的更新,其中增加操作需要使用一个自定义对话框,用于输入添加的文字信息,这个自定义对话框自然也对应一个自定义的xml文件。另外还定义了一个继承AndroidTestCase的MyTest测试单元,在这个测试单元中定义增删改查操作完成对数据库操作的测试。注意:在清单文件AndroidManifest.xml文件中注册provider和测试单元。
activity_main.xml文件:
整体思路:创建一个继承SQLiteOpenHelper的DBHelper类,在·这个类中声明一个数据库名称和版本号码,在onCreate方法中创建数据库表并执行,在onUpgrade方法中暂时不预处理。创建一个继承ContentProvider的StudentContentProvider类,在这个类中定义内容提供者的增删改查操作。在xml文件中定义一个ListView控件,在activity中声明一个LoaderManager对象,定义一个MyAdapter类,然后声明一个MyAdapter对象,定义一个LoaderManager.LoaderCallbacks<Cursor>匿名内部类对象,并在onCreate方法中实例化这个LoaderManager对象,将匿名内部类对象与这个对象关联,绑定listview。重写onMenuItemSelected这个方法,在这个方法中设置点击各个item弹出的删除和添加的操作,在这两个操作中都需要用到内容解析者来调用增删改查方法操作数据,操作完成后要使用Loader重新查询数据,即进行数据的更新,其中增加操作需要使用一个自定义对话框,用于输入添加的文字信息,这个自定义对话框自然也对应一个自定义的xml文件。另外还定义了一个继承AndroidTestCase的MyTest测试单元,在这个测试单元中定义增删改查操作完成对数据库操作的测试。注意:在清单文件AndroidManifest.xml文件中注册provider和测试单元。
activity_main.xml文件:
<ListView android:id="@+id/listView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" > </ListView>add.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" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Add" /> <TextView android:id="@+id/textView1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="姓名:" /> <EditText android:id="@+id/editText1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ems="10" /> </LinearLayout>DBHelper.java文件:
public class DBHelper extends SQLiteOpenHelper { private static String name="mydb.db"; private static int version=1; public DBHelper(Context context) { super(context, name, null, version); // TODO Auto-generated constructor stub } @Override public void onCreate(SQLiteDatabase database) { // TODO Auto-generated method stub // 在数据库中创建一张表,有主键stuid(自增长)、name String sql="create table student (stuid integer primary key autoincrement,name varchar(64))"; database.execSQL(sql); } @Override public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) { // TODO Auto-generated method stub } }StudentContentProvider.java文件:
public class StudentContentProvider extends ContentProvider { private final static UriMatcher URI_MATCHER = new UriMatcher( UriMatcher.NO_MATCH); private final static int STUDENT = 1; private final static int STUDENTS = 2; private DBHelper helper; // 添加两条匹配规则 static { URI_MATCHER.addURI( "com.example.android_loader_manager.StudentContentProvider", "student", STUDENTS); URI_MATCHER.addURI( "com.example.android_loader_manager.StudentContentProvider", "student/#", STUDENT); } public StudentContentProvider() { // TODO Auto-generated constructor stub } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count=0;//表示影响数据库的行数 int flag=URI_MATCHER.match(uri); SQLiteDatabase database =helper.getWritableDatabase(); switch (flag) { case STUDENT: long stuid=ContentUris.parseId(uri); String where_value=" stuid= "+stuid; if(selection!=null&&!selection.equals("")){ where_value+=selection; } count=database.delete("student", where_value, selectionArgs); break; case STUDENTS: count=database.delete("student", selection, selectionArgs); break; } return count; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub int flag=URI_MATCHER.match(uri); switch (flag) { case STUDENT: return "vnd.android.cursor.item/student"; case STUDENTS: return "vnd.android.cursor.dir/students"; } return null; } @Override public Uri insert(Uri uri, ContentValues contentValues) { // TODO Auto-generated method stub int flag=URI_MATCHER.match(uri); SQLiteDatabase database=helper.getWritableDatabase(); Uri uri2=null; switch (flag) { case STUDENTS: //id就是插入该行的id的值 long id=database.insert("student", null, contentValues); uri2=ContentUris.withAppendedId(uri, id); break; } System.out.println("-->>"+uri2.toString()); return uri2; } @Override public boolean onCreate() { // TODO Auto-generated method stub helper=new DBHelper(getContext()); return false; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub Cursor cursor=null; int flag=URI_MATCHER.match(uri); SQLiteDatabase database=helper.getReadableDatabase(); switch (flag) { case STUDENT: long stuid=ContentUris.parseId(uri); String where_value=" stuid= "+stuid; if(selection!=null&&!"".equals(selection)){ where_value+=selection; } cursor=database.query("student", projection, where_value, selectionArgs, null, null, null); break; case STUDENTS: cursor=database.query("student", projection, selection, selectionArgs, null, null, null); break; } return cursor; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub int count=0; int flag=URI_MATCHER.match(uri); SQLiteDatabase database=helper.getWritableDatabase(); switch (flag) { case STUDENT: long stuid=ContentUris.parseId(uri); String where_value=" stuid = "+stuid; if (selection!=null&&!selection.equals("")) { where_value+=selection; } count=database.update("student", values, where_value, selectionArgs); break; case STUDENTS: count=database.update("student", values, selection, selectionArgs); break; } return count; } }MyTest.java文件:
public class MyTest extends AndroidTestCase { public MyTest() { // TODO Auto-generated constructor stub } public void add() { // 定义一个内容解析者 ContentResolver contentResolver = getContext().getContentResolver(); ContentValues values = new ContentValues(); values.put("name", "rose"); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); contentResolver.insert(uri, values); } public void delete() { // 定义一个内容解析者 ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student/1"); int count=contentResolver.delete(uri, null, null);//影响数据库的行数 System.out.println("--count-->"+count); } public void query() { // 定义一个内容解析者 ContentResolver contentResolver = getContext().getContentResolver(); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); // 没有这句话是查询所有记录,有这句话是查询id为2的一条记录 Uri uri2=ContentUris.withAppendedId(uri, 2); Cursor cursor=contentResolver.query(uri2, null, null, null, null); while (cursor.moveToNext()) { System.out.println("-->>"+cursor.getString(cursor.getColumnIndex("name"))); } } }MainActivity.java文件:
public class MainActivity extends Activity { private LoaderManager manager; private ListView listview; private MyAdapter adapter=null; @SuppressLint("NewApi") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); manager = getLoaderManager();// 加载LoaderManager完成异步加载数据的操作 manager.initLoader(1000, null, callbacks); listview=(ListView)findViewById(R.id.listView1); adapter=new MyAdapter(MainActivity.this); registerForContextMenu(listview); } // 处理上下文菜单 @Override public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { // TODO Auto-generated method stub getMenuInflater().inflate(R.menu.main, menu); super.onCreateContextMenu(menu, v, menuInfo); } @SuppressLint("NewApi") @Override public boolean onMenuItemSelected(int featureId, MenuItem item) { // TODO Auto-generated method stub AdapterContextMenuInfo info=(AdapterContextMenuInfo)item.getMenuInfo(); switch (item.getItemId()) { case R.id.del: // Toast.makeText(MainActivity.this, "del", 1).show(); int position=info.position; String name=adapter.getItem(position).toString(); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); ContentResolver contentResolver=getContentResolver(); // count表示删除后影响数据库的行数 int count=contentResolver.delete(uri, " name=? ", new String[]{name}); if(count>0){ // 相当于重新查询数据库 manager.restartLoader(1000, null, callbacks); } break; case R.id.add: // 添加自定义对话框,完成用户的数据录入 // Toast.makeText(MainActivity.this, "add", 1).show(); final Dialog dialog=createAddDialog(MainActivity.this); Button button=(Button)dialog.findViewById(R.id.button1); button.setOnClickListener(new View.OnClickListener() { @SuppressLint("NewApi") @Override public void onClick(View arg0) { EditText editText=(EditText)dialog.findViewById(R.id.editText1); //trim()表示去掉前后空格 String name=editText.getText().toString().trim(); ContentResolver contentResolver=getContentResolver(); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); ContentValues values=new ContentValues(); values.put("name", name); Uri result_uri=contentResolver.insert(uri, values); if(result_uri!=null){//不为空表示插入成功了 // 重新加载数据 manager.restartLoader(1000, null, callbacks); dialog.dismiss(); } } }); dialog.show(); break; } return super.onMenuItemSelected(featureId, item); } public Dialog createAddDialog(Context context){ Dialog dialog=new Dialog(context); dialog.setContentView(R.layout.add); return dialog; } public class MyAdapter extends BaseAdapter{ private List<String> list=null; private Context context; public MyAdapter(Context context){ this.context=context; } public void setList(List<String> list){ this.list=list; } @Override public int getCount() { // TODO Auto-generated method stub return list.size(); } @Override public Object getItem(int position) { // TODO Auto-generated method stub return list.get(position); } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { // TODO Auto-generated method stub TextView view=null; if(convertView==null){ view=new TextView(context);//context是上下文对象 }else{ view=(TextView)convertView; } view.setText(list.get(position).toString()); return view; } } // callbacks是一个匿名内部类 private LoaderManager.LoaderCallbacks<Cursor> callbacks = new LoaderCallbacks<Cursor>() { @Override public void onLoaderReset(Loader<Cursor> arg0) { // TODO Auto-generated method stub } // 完成对UI的数据提取,更新UI的操作 @Override public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { // TODO Auto-generated method stub // 把数据提取出来,放到适配器中完成对UI的更新操作 List<String> list=new ArrayList<String>(); while (cursor.moveToNext()) { String name=cursor.getString(cursor.getColumnIndex("name")); list.add(name); } adapter.setList(list); listview.setAdapter(adapter); adapter.notifyDataSetChanged(); } @SuppressLint("NewApi") @Override public Loader<Cursor> onCreateLoader(int arg0, Bundle arg1) { // TODO Auto-generated method stub // 第一种方式 // CursorLoader loader=new CursorLoader(MainActivity.this); // Uri uri = Uri // .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); // loader.setUri(uri); // // API提供的设置loader的方法 // // loader.setProjection(projection); // // loader.setSelection(selection); // // loader.setSelectionArgs(selectionArgs); // // loader.setSortOrder(sortOrder); Uri uri = Uri .parse("content://com.example.android_loader_manager.StudentContentProvider/student"); CursorLoader loader = new CursorLoader(MainActivity.this, uri, null, null, null, null); return loader; } }; @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
相关文章推荐
- sql 经典练习题
- redis数据类型 - Hash类型
- 解决:安装SQl 2008为SQL Server代理服务提供的凭据无效
- Java中使用Jedis操作Redis
- 欢迎使用CSDN-markdown编辑器
- mybatis3 动态sql
- oracle中避免sort操作
- 全局搜索数据库
- 【转】深入理解SQL的四种连接-左外连接、右外连接、内连接、全连接
- mysql 索引优化
- mysql 事务
- oracle监听理解 命名理解
- mongodb 、nosql、 redis、 memcached 是什么?
- mysql 基本命令
- PL/SQL之触发器谓词
- PHP操作MongoDB学习笔记
- Redis键值存储系统——基本知识点
- 在C#中,不安装Oracle客户端如何连接Oracle数据库
- 【转载】MySQL索引原理及慢查询优化
- 常用的Mysql数据库操作语句大全