// 自定義類MyOpenHelper繼承自SQLiteOpenHelper MyOpenHelper oh = new MyOpenHelper(getContext(), "school.db", null, 1); // 獲取數據庫對象,若是數據庫不存在,會自動建立數據庫,數據庫文件名爲school.db,數據庫版本爲1 SQLiteDatabase db = oh.getWritableDatabase();
getWritableDatabase():以讀寫的方式打開數據庫對應的SQLiteDatabase對象,磁盤空間不足時會報錯java
getReadableDatabase():該函數首先調用getWritableDatabase(),若是磁盤空間不足,會返回打開失敗,而後以只讀的方式打開數據庫對應的SQLiteDatabase對象sql
MyOpenHelper的代碼以下:數據庫
public class MyOpenHelper extends SQLiteOpenHelper { public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) // 數據庫建立時,此方法會調用 { db.execSQL("create table teacher(_id integer primary key autoincrement, name char(10), salary char(20), phone integer(20))"); // 通常以_id做爲主鍵 } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) // 數據庫升級時,此方法會調用 { System.out.println("數據庫升級了"); } }
insert into teacher (name, phone, money) values ('張三', '159874611', 2000); delete from teacher where name = '李四' and _id = 4; update teacher set money = 6000 where name = '李四'; select name, phone from teacher where name = '張三';
db.execSQL("insert into teacher (name, phone, money) values (?, ?, ?);", new Object[]{"張三", 15987461, 75000});// 插入 Cursor cs = db.rawQuery("select _id, name, money from teacher where name = ?;", new String[]{"張三"}); // 查找
插入數組
// 把要插入的數據以鍵值對的形式封裝至ContentValues對象 ContentValues cv = new ContentValues(); cv.put("name", "劉能"); cv.put("phone", 1651646); cv.put("money", 3500); long i = db.insert("teacher", null, cv); // 返回值是所插入行的主鍵,若是出錯返回-1
刪除緩存
int i = db.delete("teacher", "_id = ? and name = ?", new String[]{"1", "張三"}); // 返回值是刪除的行數
修改架構
ContentValues cv = new ContentValues(); cv.put("money", 25000); int i = db.update("teacher", cv, "name = ?", new String[]{"趙四"}); // 返回值是所修改行的主鍵,若是出錯返回-1
查找app
// arg2:要查詢的字段 // arg3:查詢條件 // arg4:填充查詢條件的佔位符 Cursor cs = db.query("teacher", new String[]{"name", "money"}, "name = ?", new String[]{"張三"}, null, null, null); while(cs.moveToNext()){ // 獲取指定列的索引值 String name = cs.getString(cs.getColumnIndex("name")); String money = cs.getString(cs.getColumnIndex("money")); System.out.println(name + ";" + money); }
保證多條SQL語句要麼同時成功,要麼同時失敗異步
最多見案例:銀行轉帳ide
事務API函數
try { // 開啓事務 db.beginTransaction(); ........... // 設置事務執行成功 db.setTransactionSuccessful(); } finally{ // 關閉事務 // 若是此時已經設置事務執行成功,則sql語句生效,不然不生效 db.endTransaction(); }
1. 任意插入一些數據
2. 定義業務bean:Teacher.java
3. 讀取數據庫的全部數據
Cursor cs = db.query("teacher", null, null, null, null, null, null); while(cs.moveToNext()){ String name = cs.getString(cs.getColumnIndex("name")); String phone = cs.getString(cs.getColumnIndex("phone")); String money = cs.getString(cs.getColumnIndex("money")); Teacher t = new Teacher(name, phone, money);// 把讀到的數據封裝至Teacher對象 list.add(t); // 把Teacher對象保存至集合中 }
4. 把集合中的數據顯示至屏幕
LinearLayout ll = (LinearLayout) findViewById(R.id.ll); for(Teacher t : list){ TextView tv = new TextView(this); // 建立TextView,每條數據用一個文本框顯示 tv.setText(t.toString()); ll.addView(tv); // 把文本框設置爲ll的子節點 }
分頁查詢
Cursor cs = db.query("teacher", null, null, null, null, null, null, "0, 10");
LsitView用來顯示一行一行的條目,每個條目都是一個View對象,能夠由佈局文件填充(inflate)而來
MVC架構
M:model模型層,提供要展現的數據 ———— List集合
V:view視圖層,用戶看到的界面 ———— ListView
C:control控制層,操做數據如何顯示 ———— Adapter
擴展BaseAdapter實現咱們本身的Adapter能夠對列表項進行最大限度的定製,它須要實現四個方法,其中最主要的是下面這兩個方法:
第一個
// 系統調用此方法,用來獲知模型層有多少條數據 public int getCount() { return list.size(); }
第二個
// 由系統調用,獲取一個View對象,做爲ListView的條目 // position:本次getView方法調用所返回的View對象,在ListView中位於第幾個條目,那麼position的值就是多少 @Override public View getView(int position, View convertView, ViewGroup parent){ View v = View.inflate(MainActivity.this, R.layout.item_listview, null); // 則把佈局文件填充成一個View對象 // 經過資源id查找控件,注意調用的是View對象的findViewById TextView tv_name = (TextView) v.findViewById(R.id.tv_name); TextView tv_phone = (TextView) v.findViewById(R.id.tv_phone); TextView tv_salary = (TextView) v.findViewById(R.id.tv_salary);
Teacher t = list.get(position); tv_name.setText(t.getName()); tv_phone.setText(t.getPhone()); tv_salary.setText(t.getSalary()); return v; }
一旦給ListView設置了Adapter,即 listView.setAdapter(new MyAdapter()); ,上面的方法就開始調用,屏幕上顯示多少個條目,getView方法就會被調用多少次,當向下滑動屏幕時,getView會繼續被調用,得到更多的View對象顯示至ListView
當ListView中的某條目(View)完全劃出屏幕時,系統會把該條目緩存至內存(內存充足時),這時內存中就有了條目緩存。若是此時用戶繼續滑動到新的條目,系統在調用getView時會把內存中已緩存的條目取出並做爲convertView參數傳入,可是傳入的條目不必定是咱們須要的那個條目,即系統有可能正在調用getView方法獲取第10個條目,convertView傳入的倒是第1個條目的緩存,因此即便在條目緩存存在( convertView != null )時,咱們仍須要對條目中的內容從新賦值,以達到複用緩存條目(即複用View,避免了沒必要要的inflate操做。另外,由於inflate操做耗時較長,因此Android系統使用異步操做來實現它)的目的,避免產生OOM(Out Of Memory)。
對上面的getView()進行改造,使用convertView複用緩存條目的代碼以下:
@Override public View getView(int position, View convertView, ViewGroup parent) { if (convertView == null) { // 沒有緩存,則把佈局文件填充成一個View對象 convertView = View.inflate(MainActivity.this, R.layout.item_listview, null); } TextView tv_name = (TextView) convertView.findViewById(R.id.tv_name); TextView tv_phone = (TextView) convertView.findViewById(R.id.tv_phone); TextView tv_salary = (TextView) convertView.findViewById(R.id.tv_salary); Teacher t = list.get(position); tv_name.setText(t.getName()); tv_phone.setText(t.getPhone()); tv_salary.setText(t.getSalary()); return convertView; }
findViewById()是經過在控件樹中以深度優先遍從來查找與指定資源id匹配的控件的,上面代碼儘管複用了緩存條目convertView,可是在用戶反覆滑動ListView的過程當中仍會大量的調用findViewById(),從而耗費大量的內存資源,咱們可使用ViewHolder模式對上面的代碼進行進一步的優化。使用ViewHolder模式來優化ListView很是簡單,只須要在自定義Adapter中定義一個內部類ViewHolder,並將佈局中的控件做爲ViewHolder的成員變量
final class ViewHolder { // ViewHolder優化:防止大量的findViewById操做耗費資源 // 條目的佈局文件中有哪些控件,這裏就定義什麼成員變量 TextView tv_name; TextView tv_phone; TextView tv_salary; }
接下來,只要在getView()方法中將ViewHolder封裝至條目緩存convertView,當緩存存在時直接複用convertView並從中取出所封裝的ViewHolder,便可避免沒必要要的findViewById()
@Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; if (convertView == null) { convertView = View.inflate(MainActivity.this, R.layout.item_listview, null); holder = new ViewHolder(); // 把佈局文件中全部控件封裝至ViewHolder中 holder.tv_name = (TextView) convertView.findViewById(R.id.tv_name); holder.tv_phone = (TextView) convertView.findViewById(R.id.tv_phone); holder.tv_salary = (TextView) convertView.findViewById(R.id.tv_salary); convertView.setTag(holder); // 把ViewHolder封裝至View對象,最後會封裝至條目緩存convertView } else { holder = (ViewHolder) convertView.getTag();// 緩存的View對象中攜帶着ViewHolder,能夠避免頻繁的findViewById操做 } Teacher t = list.get(position); holder.tv_name.setText(t.getName()); holder.tv_phone.setText(t.getPhone()); holder.tv_salary.setText(t.getSalary()); return convertView; }
建立對話框構建器對象,相似工廠模式
AlertDialog.Builder builder = new Builder(this);
設置標題和正文
builder.setTitle("警告");
builder.setMessage("若練此功,必先自宮");
設置肯定和取消按鈕
builder.setPositiveButton("如今自宮", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "恭喜你自宮成功,如今程序退出", 0).show(); } }); builder.setNegativeButton("下次再說", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { // TODO Auto-generated method stub Toast.makeText(MainActivity.this, "若不自宮,必定不成功", 0).show(); } });
使用構建器建立出對話框對象
AlertDialog ad = builder.create();
ad.show();
AlertDialog.Builder builder = new Builder(this); builder.setTitle("選擇你的性別");
定義單選選項
final String[] items = new String[]{ "男", "女" }; //-1表示默認誰也不選中 //點擊偵聽的導包要注意別導錯 builder.setSingleChoiceItems(items, -1, new OnClickListener() { //dialog:觸發這個方法的對話框 //which:用戶所選的條目的下標 @Override public void onClick(DialogInterface dialog, int which) { Toast.makeText(MainActivity.this, "您選擇了" + items[which], 0).show(); //關閉對話框 dialog.dismiss(); } }); //能夠直接用構建器顯示對話框 builder.show();
AlertDialog.Builder builder = new Builder(this); builder.setTitle("請選擇你以爲帥的人");
定義多選的選項,由於能夠多選,因此須要一個boolean數組來記錄哪些選項被選了
final String[] items = new String[]{ "吳彥祖", "吳亦凡", "劉德華", "古天樂" }; //默認只選中第一個條目 final boolean[] checkedItems = new boolean[]{ true, false, false, false, }; builder.setMultiChoiceItems(items, checkedItems, new OnMultiChoiceClickListener() { //which:用戶點擊條目的下標 //isChecked:用於判斷用戶點擊該條目是選中仍是取消 @Override public void onClick(DialogInterface dialog, int which, boolean isChecked) { checkedItems[which] = isChecked; } }); //設置一個肯定按鈕 builder.setPositiveButton("肯定", new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { StringBuffer sb = new StringBuffer(); for(int i = 0;i < items.length; i++){ sb.append(checkedItems[i] ? items[i] + " " : ""); } Toast.makeText(MainActivity.this, sb.toString(), 0).show(); } }); builder.show();