[sms] 02_群组-(数据库创建,内容提供者,异步数据查询,ListView-CursorAdapter数据填充,内容观察者)

Android 4.0

群组-(数据库创建,内容提供者,异步数据查询,ListView数据填充 ,内容观察者

1、数据库创建SQLiteOpenHelper 类为单例 )
package cn.zengfansheng.sms.db;
 
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
 
/**
* 群组SQLiteOpenHelper实现
*
* @author hacket
*
*/

public class GroupSQLiteOpenHelper extends SQLiteOpenHelper {
 
    private static final String DB_NAME = "mysms.db";
    private static final int DB_VERSION = 1;
    // 单例
 
    private static GroupSQLiteOpenHelper helper;
    private GroupSQLiteOpenHelper(Context context, String name,
            CursorFactory factory, int version) {
        super(context, name, factory, version);
    }
 
    // 懒汉式
    public static GroupSQLiteOpenHelper getInstance(Context context) {
 
        if (helper == null) {// 2、效率问题,防止多次判断锁
 
            synchronized (GroupSQLiteOpenHelper.class) {// 1、多线程安全问题1
 
                if (helper == null) {// 3、多线程安全问题2
                    helper = new GroupSQLiteOpenHelper(context, DB_NAME, null,DB_VERSION);
                }
            }
        }
        return helper;
    }
 
    @Override
    public void onCreate(SQLiteDatabase db) {
        String sql = "CREATE TABLE groups(_id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20));";
        db.execSQL(sql);
        sql = "CREATE TABLE thread_group(_id INTEGER PRIMARY KEY AUTOINCREMENT,group_id INTEGER,thread_id INTEGER);";
        db.execSQL(sql);
    }
 
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
 
    }
 
}
2、内容提供者 ( cursor不能关闭)
package cn.zengfansheng.sms.provider;
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 cn.zengfansheng.sms.db.GroupSQLiteOpenHelper;
/**
 * 群组内容提供者
 * @author hacket
 *
 */
public class GroupProvider extends ContentProvider {
    // 1、写好authority
    private static final String AUTHORITY = "cn.zengfansheng.sms.provider.GroupProvider";
    // 2、UriMatcher类
    private static UriMatcher uriMatcher;
    
    private static final int GROUP_INSERT = 01;
    private static final int GROUP_QUERY = 02;
    
    // 3、定义匹配的uri(content://主机/path(表名)/操作)
    private static final String GROUP_TABLE = "groups";
    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);// -1
        
        uriMatcher.addURI(AUTHORITYGROUP_TABLE + "/insert"GROUP_INSERT);
        uriMatcher.addURI(AUTHORITYGROUP_TABLE + "/query"GROUP_QUERY);
    }
    // 4、helper类
    private GroupSQLiteOpenHelper helper;
    @Override
    public boolean onCreate() {
        helper = GroupSQLiteOpenHelper.getInstance(getContext());
        return true;
    }
    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        SQLiteDatabase database = helper.getReadableDatabase();
        int queryMatch = uriMatcher.match(uri);
        switch (queryMatch) {
        case GROUP_QUERY:
            if (database.isOpen()) {
                Cursor cursor = database.query(GROUP_TABLE, projection, selection, selectionArgs, nullnull, sortOrder);
                return cursor;// 这里的cursor不能关闭
            }
            break;
        default:
            throw new IllegalArgumentException("UnKnow Uri : " + uri);
        }
        if (database.isOpen()) {
            database.close();
        }
        return null;
    }
    @Override
    public String getType(Uri uri) {
        return null;
    }
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase database = helper.getWritableDatabase();
        Uri resultInsertUri = null;
        int insertMatch = uriMatcher.match(uri);
        switch (insertMatch) {
        case GROUP_INSERT:
            if (database.isOpen()) {
                long id = database.insert(GROUP_TABLEnull, values);
                if (id != -1) {
                    resultInsertUri = ContentUris.withAppendedId(uri, id);
                    getContext().getContentResolver().notifyChange(uri, null);
                }
            }
            break;
        default:
            throw new IllegalArgumentException("UnKnow Uri : " + uri);
        }
        if (database.isOpen()) {
            database.close();
        }
        return resultInsertUri;
    }
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        return 0;
    }
    @Override
    public int update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
        return 0;
    }
}
3、异步数据查询 
AsyncQueryHandler 异步查询
// NOTES===================2、异步查询数据====================
/**
 * 异步查询
 */
private void startQuery() {
    
    MyAsyncQueryHandler queryHandler = new MyAsyncQueryHandler(getContentResolver());
    Uri uri = Sms.GROUPS_QUERY_URI;
    String[] projection = GROUP_QUERUY_PROJECTION;
    queryHandler.startQuery(0, null, uri, projection, nullnullnull);
}
/**
 * 异步查询实现类
 */
private class MyAsyncQueryHandler extends AsyncQueryHandler {
    public MyAsyncQueryHandler(ContentResolver cr) {
        super(cr);
    }
    @Override
    protected void onQueryComplete(int token, Object cookie, Cursor cursor) {
        super.onQueryComplete(token, cookie, cursor);
        cursorAdapter.changeCursor(cursor);
    }
}
4、ListView-CursorAdapter数据填充 
// NOTES=====================3、listview=====================
/**
 * 初始化ListView
 */
private void initListView() {
    cursorAdapter = new MyCursorAdapter(thisnulltrue);
    lvGroup.setAdapter(cursorAdapter);
    lvGroup.setBackgroundColor(Color.WHITE);// 背景
    lvGroup.setCacheColorHint(Color.TRANSPARENT);
}
private static class ViewHolder {
    private TextView tvGroupName;
}
/**
 * CursorAdapter数据适配器实现类
 */
private class MyCursorAdapter extends CursorAdapter {
    public MyCursorAdapter(Context context, Cursor c, boolean autoRequery) {
        super(context, c, autoRequery);
    }
    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        View view = View.inflate(context, R.layout.listview_groupnull);
        ViewHolder holder = new ViewHolder();
        holder.tvGroupName = (TextView) view.findViewById(R.id.tv_group_item_name);
        view.setTag(holder);
        return view;
    }
    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ViewHolder holder = (ViewHolder) view.getTag();
        // 获取数据
        String groupName = cursor.getString(GROUPNAME_COLUMN_INDEX);
        holder.tvGroupName.setText(groupName);
    }
}
5、内容观察者
在插入数据时,通知注册的观察者,数据更新了
getContext().getContentResolver().notifyChange(uri, null);  

// NOTES====================4、观察group表中数据的变化====================
// 注册内容观察者
@Override
protected void onStart() {
    super.onStart();
    registerGroupInsert();
}
// 取消注册内容观察者
@Override
protected void onStop() {
    super.onStop();
    if (groupObserver != null) {
        getContentResolver().unregisterContentObserver(groupObserver);
        groupObserver = null;
    }
}
/**
 * 注册内容观察者
 */
private void registerGroupInsert() {
    Uri uri = Sms.GROUPS_INSERT_URI;
    groupObserver = new GroupInsertObserver(new Handler());
    getContentResolver().registerContentObserver(uri, falsegroupObserver);
}
/**
 * 内容观察者实现类
 */
private class GroupInsertObserver extends ContentObserver {
    public GroupInsertObserver(Handler handler) {
        super(handler);
    }
    @Override
    public void onChange(boolean selfChange) {
        // super.onChange(selfChange);
        startQuery();
    }
}