Sqlite ContentProvider Loader 上下文 对话框

一、整体工程图



二、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。
        
原文地址:https://www.cnblogs.com/pangblog/p/3283609.html