一、整体工程图
二、activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true" >
</ListView> </RelativeLayout>
三、add_name.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="240dp"
android:layout_height="wrap_content"
android:orientation="vertical" > <TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名:" /> <EditText
android:id="@+id/username"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="4dp"
android:layout_marginLeft="4dp"
android:layout_marginRight="4dp"
android:layout_marginTop="16dp"
android:hint="username"
android:inputType="textEmailAddress" /> <Button
android:id="@+id/btnAdd"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:text="确定">
</Button> </LinearLayout>
四、contentmenu.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" > <item
android:id="@+id/menu_add"
android:orderInCategory="100"
android:showAsAction="never"
android:title="添加">
</item>
<item
android:id="@+id/menu_delete"
android:orderInCategory="100"
android:showAsAction="never"
android:title="删除">
</item>
</menu>
五、MainActivity.java
package com.example.loadermanagerdemo; import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.LoaderManager;
import android.app.LoaderManager.LoaderCallbacks;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.CursorLoader;
import android.content.Loader;
import android.database.Cursor;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView; public class MainActivity extends Activity {
private LoaderManager manager;
private ListView listview;
private AlertDialog alertDialog;
private SimpleCursorAdapter mAdapter;
private final String TAG="main"; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview = (ListView) findViewById(R.id.listView1); mAdapter = new SimpleCursorAdapter(MainActivity.this,
android.R.layout.simple_list_item_1, null,
new String[] { "name" }, new int[] { android.R.id.text1 },0);
listview.setAdapter(mAdapter);
manager = getLoaderManager();
manager.initLoader(1000, null, callbacks); registerForContextMenu(listview);
} @Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.contentmenu, menu);
} @Override
public boolean onContextItemSelected(MenuItem item) {
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo();
switch (item.getItemId()) {
case R.id.menu_add:
AlertDialog.Builder builder = new AlertDialog.Builder(
MainActivity.this);
final View view = LayoutInflater.from(MainActivity.this).inflate(
R.layout.add_name, null);
Button btnAdd = (Button) view.findViewById(R.id.btnAdd);
btnAdd.setOnClickListener(new View.OnClickListener() { @Override
public void onClick(View v) {
EditText etAdd = (EditText) view
.findViewById(R.id.username);
String name = etAdd.getText().toString();
ContentResolver contentResolver = getContentResolver();
ContentValues contentValues = new ContentValues();
contentValues.put("name", name);
Uri uri = Uri
.parse("content://com.example.loadermanagerdemo.StudentContentProvider/student");
Uri result = contentResolver.insert(uri, contentValues);
/*if (result != null) {
manager.restartLoader(1000, null, callbacks);
}*/
alertDialog.dismiss(); //Log.i(TAG, "添加数据成功,name="+name);
}
});
builder.setView(view);
alertDialog = builder.show();
return true;
case R.id.menu_delete:
TextView tv = (TextView) info.targetView;
String name = tv.getText().toString();
Uri url = Uri
.parse("content://com.example.loadermanagerdemo.StudentContentProvider/student");
ContentResolver contentResolver = getContentResolver();
String where = "name=?";
String[] selectionArgs = { name };
int count = contentResolver.delete(url, where, selectionArgs);
/*if (count == 1) {
manager.restartLoader(1000, null, callbacks);
}*/
//Log.i(TAG, "删除数据成功,name="+name);
return true;
default:
return super.onContextItemSelected(item);
} } private LoaderManager.LoaderCallbacks<Cursor> callbacks = new LoaderCallbacks<Cursor>() { @Override
public Loader<Cursor> onCreateLoader(int id, Bundle bundle) {
Uri uri = Uri
.parse("content://com.example.loadermanagerdemo.StudentContentProvider/student");
CursorLoader loader = new CursorLoader(MainActivity.this, uri,
null, null, null, null);
Log.i("jltxgcy", "onCreateLoader被执行。");
return loader;
} @Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mAdapter.swapCursor(cursor);
//listview.setAdapter(mAdapter);
Log.i("jltxgcy", "onLoadFinished被执行。");
} @Override
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
Log.i("jltxgcy", "onLoaderReset被执行。");
}
}; @Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
六、StudentContentProvider.java
package com.example.loadermanagerdemo; import com.example.loadermanagerdemo.dbhelper.DbHelper; import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.util.Log; public class StudentContentProvider extends ContentProvider {
private DbHelper helper;
private final String TAG = "main";
private final static UriMatcher URI_MATCHAR = new UriMatcher(
UriMatcher.NO_MATCH);
private final static int STUDENT = 1;
private final static int STUDENTS = 2;
static { URI_MATCHAR.addURI(
"com.example.loadermanagerdemo.StudentContentProvider",
"student", STUDENTS);
URI_MATCHAR.addURI(
"com.example.loadermanagerdemo.StudentContentProvider",
"student/#", STUDENT);
} public StudentContentProvider() {
} @Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = -1;
int flag = URI_MATCHAR.match(uri);
SQLiteDatabase database = helper.getWritableDatabase();
switch (flag) {
case STUDENT:
long stuid = ContentUris.parseId(uri);
String where_value = "_id=?";
String[] where_args = { String.valueOf(stuid) };
count = database.delete("student", where_value, where_args);
break; case STUDENTS:
count = database.delete("student", selection, selectionArgs);
break;
}
Log.i(TAG, "---->>" + count);
getContext().getContentResolver().notifyChange(uri, null);
return count;
} @Override
public String getType(Uri uri) {
int flag = URI_MATCHAR.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 values) {
int flag = URI_MATCHAR.match(uri);
SQLiteDatabase database = helper.getWritableDatabase();
Uri returnUri = null; if (STUDENTS == flag) {
long id = database.insert("student", null, values);
returnUri = ContentUris.withAppendedId(uri, id);
}
Log.i(TAG, "---->>" + returnUri.toString());
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
} @Override
public boolean onCreate() {
helper = new DbHelper(getContext());
return false;
} @Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Cursor cursor = null;
SQLiteDatabase database=helper.getReadableDatabase();
int flag = URI_MATCHAR.match(uri);
switch (flag) {
case STUDENTS:
cursor=database.query(true, "student", null, selection, selectionArgs, null, null, null, null);
break; case STUDENT:
long stuid=ContentUris.parseId(uri);
String where_value="_id=?";
String[] where_args={String.valueOf(stuid)};
cursor=database.query(true, "student", null, where_value, where_args, null, null, null, null);
break;
}
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
} @Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = -1;
int flag = URI_MATCHAR.match(uri);
SQLiteDatabase database = helper.getWritableDatabase();
switch (flag) {
case STUDENTS:
count = database
.update("student", values, selection, selectionArgs);
break; case STUDENT:
long stuid = ContentUris.parseId(uri);
String where_value = "_id=?";
String[] where_args = { String.valueOf(stuid) };
count = database.update("student", values, where_value, where_args);
break;
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
} }
七、DbHelper.java
package com.example.loadermanagerdemo.dbhelper; import android.content.ContentValues;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; 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);
} @Override
public void onCreate(SQLiteDatabase database) {
String sql="Create table student(_id integer primary key autoincrement,name varchar(64))";
database.execSQL(sql);
ContentValues values=new ContentValues();
values.put("name", "Jack");
database.insert("student", null, values);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub } }
八、详解
只要开启程序,就会调用StudentContentProvider中的onCreate方法,然后MainActivity中ContentResolver操作StudentContentProvider类,StudentContentProvider操作DbHelper类。
数据库部分内容请看http://www.w3school.com.cn/sql/sql_create_table.asp。
insert into Persons VALUES (1,'Gates', 'Bill', 'Xuanwumen 10', 'Beijing')。
主键为NULL,代表自增长。对应到Android的SQL语句就变成字符串了。
manager.initLoader(1000, null, callbacks)调用了onCreateLoader。
Loader实现了异步加载,只要想StudentContentProvider插入数据,就会调用onLoadFinished更新了Cursor,通过mAdapter.swapCursor(cursor)更新了Listview。如果不是Listview,那么此处也是进行更新UI操作,只不过不能向刚才用一句程序mAdapter.swapCursor(cursor)就搞定。
查询Cursor变化是异步的,在有数据插入,更新,删除的地方要加上getContext().getContentResolver().notifyChange(uri, null);
如果退出Activity,那么会调用onLoaderReset,清空cursor。