Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android編程入門 >> android開發-數據存儲Ⅱ

android開發-數據存儲Ⅱ

編輯:Android編程入門

本章繼續講解在Android開發中,數據的存儲與管理。涉及知識點:SQLite,SwipeRefreshLayout控件刷新。

1.功能需求

練習使用SQLite

  •  做一個登錄界面,數據庫字段包含用戶名、密碼以及是否登錄中的狀態
  • 模擬登錄成功後,將登錄的用戶名及登錄狀態(登錄中)寫入數據庫,並跳轉新頁面,有退出按鈕
  • 當點擊退出時,將當前用戶登錄中的狀態清除
  • 下一次登錄時,顯示上一次登錄的用戶名
  • 保存所有用戶登錄的歷史,但一個用戶名只保留一條記錄

2.軟件實現

                   圖1

                   圖2

                    圖3

                    圖4

                    圖5

    簡要說明:通過左側滑動導航界面(圖5),可以選擇登陸頁面(圖1)和登陸列表頁面(圖2)。在登陸成功後,會跳轉到登錄列表界面。通過選擇退出,可清除當前用戶的登錄狀態。登錄列表,下拉界面可以刷新頁面信息(圖3)。

3.相關知識

(1)SQLite簡介

    SQLite,是一款輕型的數據庫,是遵守ACID的關系型數據庫管理系統,它包含在一個相對小的C庫中。它是D.RichardHipp建立的公有領域項目。它的設計目標是嵌入式的,而且目前已經在很多嵌入式產品中使用了它,它占用資源非常的低,在嵌入式設備中,可能只需要幾百K的內存就夠了。

    SQLite由以下幾個部分組成:SQL編譯器、內核、後端及附件。SQLite通過利用虛擬機和虛擬數據庫引擎(VDBE),是調試、修改和擴展SQLite的內核變得更加方便。所有SQL語句都被編譯成易讀的、可以在SQLite虛擬機中執行的程序集。SQLite的整體結構圖如下:

(2)SQLite性能

  • 在數據存儲方面,袖珍型的SQLite可以支持高達2TB大小的數據庫,每個數據庫都是以單個文件的形式存在,這些數據都是以B-Tree的數據結構形式存儲在磁盤上。
  • 在事務處理方面,SQLite通過數據庫級上的獨占性和共享鎖來實現獨立事務處理。這意味著多個進程可以在同一時間從同一數據庫讀取數據,但只有一個可以寫入數據。在某個進程或線程想數據庫執行寫操作之前,必須獲得獨占鎖。在獲得獨占鎖之後,其他的讀或寫操作將不會再發生。
  • SQLite采用動態數據類型,當某個值插入到數據庫時,SQLite將會檢查它的類型,如果該類型與關聯的列不匹配,SQLite則會嘗試將該值轉換成該列的類型,如果不能轉換,則該值將作為本身的類型存儲,SQLite稱這為“弱類型”。但有一個特例,如果是INTEGER PRIMARY KEY,則其他類型不會被轉換,會報一個“datatype missmatch”的錯誤。

(3)SQLite支持字段類型

    SQLite在數據類型存儲方面,目前支持如下類型字段: VARCHAR(10),NVARCHAR(15),TEXT,INTEGER,FLOAT,BOOLEAN,CLOB,BLOB,TIMESTAMP,NUMERIC(10,5),VARYING CHARACTER (24),NATIONAL VARYING CHARACTER(16)。

(4)SQLite操作數據規則

    Android項目中,數據庫生成後,存儲在/data/data/[PACKAGE_NAME]/databases目錄下。

1.添加、更新和刪除數據時,可使用如下通用語句
  • db.executeSQL(String sql);  
  • db.executeSQL(String sql, Object[] bindArgs);//sql語句中使用占位符,然後第二個參數是實際的參數集 
2.專用sql操作語句
  • db.insert(String table, String nullColumnHack, ContentValues values); 
  • db.update(String table, Contentvalues values, String whereClause, String whereArgs); 
  • db.delete(String table, String whereClause, String whereArgs);
  • db.rawQuery(String sql, String[] selectionArgs); 
  • db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);
  • db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);
  • db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having);

     以上方法的第一個參數是表示要操作的表名;

     insert中的第二個參數表示如果插入的數據每一列都為空的話,需要指定此行中某一列的名稱,系統將此 列設置為NULL,不至於出現錯誤;

     insert中的第三個參數是ContentValues類型的變量,是鍵值對組成的Map,key代表列 名,value代表該列要插入的值;

     update的第二個參數也很類似,只不過它是更新該字段key為最新的value值,

    第三個參數 whereClause表示WHERE表達式,比如“age > ? and age < ?”等,最後的whereArgs參數是占位符的實際參數值;

    delete方法的參數和update一樣;

    db.query傳入各種參數表示查詢,他們同時返回一個Cursor對象,代表數據集的游標。

    除以上基本sql操作語句外,SQLite還支持事務操作,如以下操作使用:

  public void TestTransaction(List<Person> persons) {  
     db.beginTransaction();  //開始事務  
  try {  
  for (Person person : persons) {  
          db.execSQL("INSERT INTO person VALUES(null, ?, ?, ?)", new Object[]{person.name, person.age, person.info});            }            
db.setTransactionSuccessful(); //設置事務成功完成 } finally { db.endTransaction(); //結束事務 } }

(4)SQLite通用sql語句與專用模塊操作對比

  • db.executeSQL(String sql),利用這種方式,對於熟練寫sql語句的程序員,可以很快速的寫sql語句。加快開發速度。但是,這樣的sql語句耦合性太高,不靈活,一旦數據庫字段修改,對應業務也需要跟著改。
  • 利用專用的操作語句,相對來說,不是直接寫sql語句,需要傳入不同的表,字段等信息,相對來說麻煩,但它的優點是降低了系統業務模塊與數據庫之間的耦合性,在數據庫設計方面,如果規劃的好,在做數據庫字段,修改,新增時,可以不用或者只修改很少一部分業務邏輯代碼。

(5)SwipeRefreshLayout簡介

    各種下拉控件,下拉操作在Android開發中,已經是層出不窮。google終於忍不住推出了自己的下拉組件SwipeRefreshLayout,它很輕巧,很靈活,操作很簡單。

    swipeRefreshLayout這個類是在放在 android-support-v4.jar裡面的。SwipeRefreshLayout組件只接受一個子組件:即需要刷新的那個組件。它使用一個偵聽機制來通知擁有該組件的監聽器有刷新事件發生,換句話 說我們的Activity必須實現通知的接口。該Activity負責處理事件刷新和刷新相應的視圖。一旦監聽者接收到該事件,就決定了刷新過程中應處理 的地方。如果要展示一個“刷新動畫”,它必須調用setRefrshing(true),否則取消動畫就調用setRefreshing(false)

(6)SwipeRefreshLayout使用

1.布局文件中加入SwipeRefreshLayout控件,把需要刷新的視圖放在控件裡面,如刷新一個Fragment視圖:
<android.support.v4.widget.SwipeRefreshLayout
    android:id="@+id/sr"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<RelativeLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" 
    <FrameLayout
        android:id="@+id/fl_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@id/line" />
</RelativeLayout>
</android.support.v4.widget.SwipeRefreshLayout>
2.後台代碼中操作如下:
 sr = (SwipeRefreshLayout) findViewById(R.id.sr);
        sr.setColorSchemeResources(android.R.color.holo_blue_bright,
                android.R.color.holo_green_light,
                android.R.color.holo_orange_light,
                android.R.color.holo_red_light);
        sr.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                appLoginDetailFragment();  //需要刷新時的操作
                sr.setRefreshing(false);
            }
        });

 4.項目核心代碼解析

Android數據庫操作項目Demo結構圖如下所示:

(1)數據庫處理

    數據庫處理放在db包,dbhelper是建立數據庫的基本操作,包括建表語句;clssqlite表示提供數據庫查詢,打開等通用操作模板。

(2)登錄處理

    登錄處理要求:模擬登錄成功後,將登錄的用戶名及登錄狀態(登錄中)寫入數據庫,保存所有用戶登錄的歷史,但一個用戶名只保留一條記錄。所以在登錄處理時,需要先檢查數據表中是否含該登錄賬戶的信息,核心代碼如下:

  private void init()
     {
         try {
             db = new clssqlite();
             db.openDB(getActivity());
             login_on.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View arg0) {
                     SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 這裡的格式可以自己設置
                     // format()方法是用來格式化時間的方法
                     Date datenow = new Date();
                      String returnTime = format.format(datenow);
                      String account = operator.getText().toString();
                      String passwords = password.getText().toString();
                     //檢測是否含有該賬戶
                     int loginstatus = db.checklogin("select count(*) as data from LoginData where account='"+account+"' ");
                     try {Thread.sleep(400);
                     } catch (InterruptedException e) {
                         e.printStackTrace();}
                     String sql = "insert into LoginData (account,password,loginstatus,logintime) values ('" + account + "','" + passwords + "',1,'" + returnTime + "') ";
                     if (loginstatus > 0)
                         sql = "update LoginData set loginstatus=1 , logintime='" + returnTime + "' where account='"+account+"' ";
                         db.openDB(getActivity());
                      if(db.executeSQL(sql)>=0)
                      {
                          //保存登錄名
                          result.setText("登錄成功");
                          account_save.edit().putString("account", account).commit();
                          ((MainActivity) mContext).appLoginDetailFragment();
                          ((MainActivity) mContext).setToolbarTitle("登錄列表");
                      }else {
                          result.setText("登錄失敗");
                      }}
             });
         }catch (Exception ex)
         {
             result.setText("登錄異常");}
     }

(3)顯示上一次登錄的用戶名

    這個知識利用上一章的SharedPreferences存儲即可,在登錄成功後,根據代碼account_save.edit().putString("account", account).commit();完成用戶名保存。

(4)退出清空登錄狀態

    在退出操作時,需要先驗證用戶是否已經登錄了,若登錄了,更新數據表中的登錄狀態字段即可。核心代碼如下:

  public boolean onOptionsItemSelected(MenuItem item) {
         int id = item.getItemId();
         //退出處理
         if (id == R.id.action_loginoutmode) {
             db.openDB(this);
             String account=LoginFragment.account_save.getString("account","00000");
             int loginstatus = db.checklogin("select count(*) as data from LoginData where account='"+account+"' and loginstatus=1 ");
             if(loginstatus>0)
               {
                   String sql="update  LoginData set loginstatus=0 where account='"+account+"' ";
                   db.openDB(this);
                   db.executeSQL(sql);
                   appLoginDetailFragment();
                   Toast.makeText(getApplicationContext(), "退出登錄成功", Toast.LENGTH_SHORT).show();
               }
             else
               {
                   Toast.makeText(getApplicationContext(), "還未登錄", Toast.LENGTH_SHORT).show();
               }
         }
         return super.onOptionsItemSelected(item);
     }

(5)登錄信息展示

    登錄狀態展示是把數據表中存儲的字段信息,展示在界面上。其中,對於頁面刷新操作,當listview拉動到頂部時,觸發刷新事件,相關代碼如下:

 listView.setOnScrollListener(new AbsListView.OnScrollListener() {
             @Override
             public void onScrollStateChanged(AbsListView view, int scrollState) {
             }
             @Override
             public void onScroll(AbsListView view, int firstVisibleItem,
                                  int visibleItemCount, int totalItemCount) {
                 if (listView != null && listView.getChildCount() > 0) {
                     boolean enable = (firstVisibleItem == 0) && (view.getChildAt(firstVisibleItem).getTop() == 0);
                     //調用刷新控件
                     ((MainActivity) mContext).setSwipeRefreshEnable(enable);
                 }
             }
         });

5.項目源代碼下載

本項目源代碼在360雲盤上,開發環境為 Android Studio 2.0 beta 7。

https://yunpan.cn/cYamkZG3sq9jf  訪問密碼 f3d5。文件名稱:android數據庫存儲操作demo。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved