編輯:關於Android編程
/** * A particular {@link AsyncQueryHandler} allowing clients to be notified via a * listener. The {@link NotifyingAsyncQueryHandler} also make sure no strong * reference is kept on the given listener (as it is often a Context). * */ public class DBAsyncHandler extends AsyncQueryHandler { private WeakReferencemListener; /** * Client may use this to listen to completed query operations. run on UI * Thread */ public static class DBAsyncListener { public DBAsyncListener() { } /** * run on UI Thread
* cursor close() method needn't be called */ protected void onQueryComplete(int token, Object cookie, Cursor cursor) { } protected void onInsertComplete(int token, Object cookie, Uri uri) { } protected void onUpdateComplete(int token, Object cookie, int result) { } protected void onDeleteComplete(int token, Object cookie, int result) { } } /**instance in UI Thread*/ public DBAsyncHandler(ContentResolver resolver, DBAsyncListener listener) { super(resolver); setDBListener(listener); } /** * Assign the given {@link DBAsyncListener}. */ public void setDBListener(DBAsyncListener listener) { mListener = (listener != null) ? new WeakReference(listener) : null; } private DBAsyncListener getDBListener() { return (mListener == null) ? null : mListener.get(); } /** such as Activity-onDestory(), this method is called */ public void clearDBListener() { mListener = null; } public void startQuery(int token, Object cookie, Uri uri, String[] projection, String selection, String[] selectionArgs, String orderBy) { super.startQuery(token, cookie, uri, projection, selection, selectionArgs, orderBy); } @Override protected void onQueryComplete(int token, Object cookie, Cursor cursor) { DBAsyncListener listener = getDBListener(); if (listener != null) { listener.onQueryComplete(token, cookie, cursor); if (cursor != null && !cursor.isClosed()) cursor.close(); } else if (cursor != null) { cursor.close(); } } @Override protected void onDeleteComplete(int token, Object cookie, int result) { DBAsyncListener listener = getDBListener(); if (listener != null) { listener.onDeleteComplete(token, cookie, result); } } @Override protected void onInsertComplete(int token, Object cookie, Uri uri) { DBAsyncListener listener = getDBListener(); if (listener != null) { listener.onInsertComplete(token, cookie, uri); } } @Override protected void onUpdateComplete(int token, Object cookie, int result) { DBAsyncListener listener = getDBListener(); if (listener != null) { listener.onUpdateComplete(token, cookie, result); } } }
public class MyProvider extends ContentProvider { private final static String TAG = MyProvider.class.getSimpleName(); private final static int Person = 1; public final static String BASE = "com.baidu.my.provider"; public final static Uri URI_Person = Uri.parse("content://com.baidu.my.provider/Person"); private final static UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH); // 如果都匹配不成功,則返回構造函數中指定的參數值,默認為-1 private SQLiteDatabase db; static { MATCHER.addURI(BASE, "Person", Person); } @Override public boolean onCreate() { MyDBHelper dbHelper = new MyDBHelper(this.getContext()); db = dbHelper.getWritableDatabase(); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Cursor c = null; switch (MATCHER.match(uri)) { case Person: c = db.query(DBPerson.TableName, projection, selection, selectionArgs, null, null, sortOrder); c.setNotificationUri(getContext().getContentResolver(), URI_Person); break; default: break; } return c; } @Override public String getType(Uri uri) { switch (MATCHER.match(uri)) { case Person: return "vnd.android.cursor.dir/vnd." + BASE + ".request"; default: break; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { long id = 0; switch (MATCHER.match(uri)) { case Person: id = db.insert(DBPerson.TableName, null, values); if (id > 0) { // 數據發生改變,發出通知 getContext().getContentResolver().notifyChange(URI_Person, null); } return ContentUris.withAppendedId(uri, id); } return null; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub return 0; } }
public class MyDBHelper extends SQLiteOpenHelper { private static final String TAG = "DBHelper"; private static final String DB_NAME = "my.db"; private static final int DB_VERSION = /**/ 57 /**/;/****謹慎修改,否則將導致用戶歷史數據被刪除****/ public MyDBHelper(Context context) { super(context, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(getRequestCreateStr()); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + DBPerson.TableName); onCreate(db); } private String getRequestCreateStr() { StringBuffer sb = new StringBuffer(); sb.append("CREATE TABLE ").append(DBPerson.TableName); sb.append(" ("); sb.append(BaseColumns._ID).append(" INTEGER PRIMARY KEY,"); sb.append(DBPerson.MetaDate.Name).append(" TEXT,"); sb.append(DBPerson.MetaDate.Age).append(" TEXT)"); return sb.toString(); } }
public interface DBPerson extends BaseDB{ public interface MetaDate { String Name = "Name"; String Age = "Age"; } public String TableName = "Person"; public String[] PROJECTION = { MetaDate.Name, MetaDate.Age }; public String SORT_ORDER = MetaDate.Age + " ASC"; }
public class MainActivity extends Activity { private DBAsyncHandler dbAsyncHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // dbAsyncHandler = new DBAsyncHandler(getContentResolver(), dbListener); } private DBAsyncHandler.DBAsyncListener dbListener = new DBAsyncListener() { protected void onQueryComplete(int token, Object cookie, Cursor cursor) { Toast.makeText(getApplicationContext(), "ok = " + cursor.getCount(), 1).show(); } protected void onInsertComplete(int token, Object cookie, android.net.Uri uri) { Toast.makeText(getApplicationContext(), "插入ok!", 1).show(); } }; public void query(View view) { //query dbAsyncHandler.startQuery(100, null, MyProvider.URI_Person, DBPerson.PROJECTION, null, null, DBPerson.SORT_ORDER); } public void insert(View view) { //insert ContentValues initialValues = new ContentValues(); initialValues.put(DBPerson.MetaDate.Name, "baidu"); initialValues.put(DBPerson.MetaDate.Age, System.currentTimeMillis()); dbAsyncHandler.startInsert(100, null, MyProvider.URI_Person, initialValues); } @Override protected void onDestroy() { //clear dbAsyncHandler.clearDBListener(); super.onDestroy(); } }
源碼下載》》
前言我們知道寫出有質量的軟件是復雜而且困難的:它不僅僅在於滿足所有的需求,同時也應該是健壯的、易於維護的、方便測試的、非常靈活的(能夠靈活的改變內容,如模塊加減)。清晰的
本文接著實現“確認密碼”功能,也即是用戶以前設置過密碼,現在只需要輸入確認密碼布局文件和《Android 手機衛士--設置密碼對話框》中的布局基本類似,所有copy一下,
主要思想:將一個view設計成多層:背景層,含中獎信息等;遮蓋層,用於刮獎,使用關聯一個Bitmap的Canvas在該Bitmap上,使用它的canvas.drawPat
如果說使用dex2jar和JD-GUI獲得了一個APP反編譯後的JAVA代碼,再結合smali代碼調試器來進行調試還不夠爽,不夠暢快的話,下面將介紹一個幫助分析代碼執行流