編輯:關於Android編程
寫這篇文章主要是網上的對sqlite的操作太多且太雜,很多時候都不能很好的運用到自己的項目中,結構不清晰,我自己寫了一篇適合剛剛接觸的人看的操作方法。
近來用android時要將一些數據保存起來,一開始用的是preferences,後來要保存的東西多了,發現用preferences明顯不能滿足要求了,而且發現用這個的話代碼就變得有點亂了,所以才開始學習使用sqlite數據庫,一開始以為不就是個數據庫麼,和平時的mysql啊或者是sqlserver都一樣,都很簡單的,但後來真正在用的時候才發現困難一個接著一個,但還是在不斷的摸索中一步一步的不斷解決困難,後來發現學習安卓的話當自己實在找不到思路時看看網上的一些教學視頻也是個不錯的選擇。這裡推薦一個視頻不錯,我就是照這個視頻學的。http://www.tudou.com/programs/view/2qH5Am_3MsM/
寫一下android操作數據庫中的一些准備。
首先,配一下adb的環境變量,因為每次都要到adb的目錄下去啟動實在太麻煩了,下面是具體步驟,當然也可以該其他文件,我習慣改這個,可以改完後可以source一下使它生效。
1、sudo gedit /etc/profile
2、將下面的兩句加到上面打開的文件裡
export ANDROID_HOME=/home/sdk文件路徑
export PATH=$PATH:$ANDROID_HOME/platform-tools
3、重啟電腦,大功告成!!
adb配好以後,我們最好還要給手機裡的數據庫訪問的權限,一般在/data/data/包名/database 裡面,用adb shell進入後su獲得手機root權限,然後給權限chmod。
要讀數據庫文件的話就用命令 sqlite3 數據庫文件 ,其中的數據庫可以直接在adb shell中運行sqlite3,但我按照網上弄的就是不能在adb shell中打開sqlite3數據庫,說命令沒有找到,我該傳的文件都傳了,沒辦法,只有在eclipse裡的ddms的file explore裡把數據庫文件到處然後在linux終端裡運行sqlite3數據庫來看了。
還有要注意的是寫sql語句時一定要注意"select * from " +TABLE_NAME 中的from和引號要留有空格,不然的話就連在一起了。
下面的有一個知識要講一下,sqlite的增加,刪除等操作都挺簡單的,麻煩的就是查詢操作,一般都借用Cursor來保存查詢數據,一開始我沒怎麼注意這是一個指針類型,指向數據庫裡的數據,而我一開始寫的時候把數據庫的關閉操作寫在了Cursor操作的前面,也就是說先把數據庫關閉了再對Cursor對象進行操作,這樣的話就造成了Cursor的空指針,也就注定杯具了好久。。。
下面就貼一些關於sqlite數據庫操作的事例,這樣對一些還在困惑中的人有一些幫助,同時有助於以後自己回顧。
SQLiteHelper.java(數據庫輔助類)
public class SQLiteHelper extends SQLiteOpenHelper{ private static final String DATABASE_NAME="fpp.db"; private static final int DATABASE_VERSION=17;//更改版本後數據庫將重新創建 private static final String TABLE_NAME="test"; /** * 在SQLiteOpenHelper的子類當中,必須有這個構造函數 * @param context 當前的Activity * @param name 表的名字(而不是數據庫的名字,這個類是用來操作數據庫的) * @param factory 用來在查詢數據庫的時候返回Cursor的子類,傳空值 * @param version 當前的數據庫的版本,整數且為遞增的數 */ public SQLitedata(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION);//繼承父類 // TODO Auto-generated constructor stub } /** * 該函數是在第一次創建數據庫時執行,只有當其調用getreadabledatebase() * 或者getwrittleabledatebase()而且是第一創建數據庫是才會執行該函數 */ public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub String sql = "CREATE TABLE " + TABLE_NAME + "(" + "id INTEGER," + "nid VARCHAR(11)," + "sid CHAR(1)," + "type INTEGER," + "stime DATETIME," + "locate_main VARCHAR(45)," + "locate_detail VARCHAR(45)," + "state INTEGER" + ")"; db.execSQL(sql); Log.e("create","數據庫創建成功"); } /** *數據庫更新函數,當數據庫更新時會執行此函數 */ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { String sql = "DROP TABLE IF EXISTS " + TABLE_NAME; db.execSQL(sql); this.onCreate(db); // TODO Auto-generated method stub System.out.println("數據庫已經更新"); /** * 在此添加更新數據庫是要執行的操作 */ } }
MyOperator.java (數據庫操作類)
public class MyOperator { private static final String TABLE_NAME = "test";//要操作的數據表的名稱 private SQLiteDatabase db=null; //數據庫操作 //構造函數 public MyOperator(SQLiteDatabase db) { this.db=db; } // //插入操作 // public void insert(int id,String nid,String sid,int type, // String stime,String etime,String desc,String locate_main,String locate_detail,int state) // { // String sql = "INSERT INTO " + TABLE_NAME + " (id,nid,sid,type,stime,etime,desc,locate_main,locate_detail,state)" // + " VALUES(?,?,?,?,?,?,?,?,?,?)"; // Object args[]=new Object[]{id,nid,sid,type,stime,etime,desc,locate_main,locate_detail,state}; // this.db.execSQL(sql, args); // this.db.close(); // } //插入重載操作 public void insert(int id,int state) { String sql = "INSERT INTO " + TABLE_NAME + " (id,state)" +" VALUES(?,?)"; Object args[]=new Object[]{id,state}; this.db.execSQL(sql, args); this.db.close(); } //更新操作 public void update(int id,int state) { String sql = "UPDATE " + TABLE_NAME + " SET state=? WHERE id=?"; Object args[]=new Object[]{state,id}; this.db.execSQL(sql, args); this.db.close(); } //刪除操作,刪除 public void delete(int id) { String sql = "DELETE FROM " + TABLE_NAME +" WHERE id=?"; Object args[]=new Object[]{id}; this.db.execSQL(sql, args); this.db.close(); } //查詢操作,查詢表中所有的記錄返回列表 public Listfind() { List all = new ArrayList (); //此時只是String String sql = "SELECT * FROM " + TABLE_NAME; Cursor result = this.db.rawQuery(sql, null); //執行查詢語句 for(result.moveToFirst();!result.isAfterLast();result.moveToNext() ) //采用循環的方式查詢數據 { all.add(result.getInt(0)+","+result.getString(1)+","+result.getString(2)+","+result.getInt(3)+"," +result.getString(4)+","+result.getString(5)+","+result.getString(6)+","+result.getString(7)+"," +result.getString(8)); } this.db.close(); return all; } //查詢操作蟲重載函數,返回指定ID的列表 public int getstatebyID(int id) { int num=-1;//錯誤狀態-1 List all = new ArrayList (); //此時只是String String sql = "SELECT state FROM " + TABLE_NAME + " where id=?" ; String args[] = new String[]{String.valueOf(id)}; Cursor result = this.db.rawQuery(sql, args); for(result.moveToFirst();!result.isAfterLast();result.moveToNext() ) { num=result.getInt(0); } Log.e("database", "圖片狀態state"+ String.valueOf(num)); this.db.close(); return num; } //判斷插入數據的ID是否已經存在數據庫中。 public boolean check_same(int id) { String sql="SELECT id from " + TABLE_NAME + " where id = ?"; String args[] =new String[]{String.valueOf(id)}; Cursor result=this.db.rawQuery(sql,args); Log.e("database", "the sql has been excuate"); Log.e("database","the hang count" + String.valueOf(result.getCount())); if(result.getCount()==0)//判斷得到的返回數據是否為空 { Log.e("database", "return false and not exist the same result" + String.valueOf(result.getCount())); this.db.close(); return false; } else { Log.e("database", "return true and exist the same result"+ String.valueOf(result.getCount())); this.db.close(); return true; } } }
隨便的一個項目中的activity(activity 類,操作打開數據庫已經在裡面)
public class MainActivity extends Activity { private static LinkedList
Android Toolbar:ToolBar是Android 5.0(API Level 21)之後用來取代ActionBar的ToolBar的優勢:Toolbar本身
所謂的嵌套布局就是在一個文件中嵌套多個布局文件 <frameLayout android:layout_width=match_parent
MVP介紹MVP模式(Model-View-Presenter)是MVC模式的一個衍生。主要目的是為了解耦,使項目易於維護。Model 依然是業務邏輯和實體模型 View
要逆向分析並修改一個Android應用,首先是對APK進行解包和打包,這一部分網上資料鋪天蓋地,不再贅述了。值得一提的一點就是,如果apktool無法解包或打包的話,可以