android筆記-數(shù)據(jù)儲存與界面2

Pull解析xml文件(掌握)

  • 先自己寫一個xml文件,存一些天氣信息

拿到xml文件

    InputStream is = getClassLoader().getResourceAsStream("weather.xml");

拿到pull解析器

    XmlPullParser xp = Xml.newPullParser();

開始解析

  • 拿到指針所在當前節(jié)點的事件類型

      int type = xp.getEventType();
    
  • 事件類型主要有五種

    • START_DOCUMENT:xml頭的事件類型
    • END_DOCUMENT:xml尾的事件類型
    • START_TAG:開始節(jié)點的事件類型
    • END_TAG:結(jié)束節(jié)點的事件類型
    • TEXT:文本節(jié)點的事件類型
  • 如果獲取到的事件類型不是END_DOCUMENT,就說明解析還沒有完成,如果是,解析完成,while循環(huán)結(jié)束

      while(type != XmlPullParser.END_DOCUMENT)
    
  • 當我們解析到不同節(jié)點時,需要進行不同的操作,所以判斷一下當前節(jié)點的name

    • 當解析到weather的開始節(jié)點時,new出list

    • 當解析到city的開始節(jié)點時,創(chuàng)建city對象,創(chuàng)建對象是為了更方便的保存即將解析到的文本

    • 當解析到name開始節(jié)點時,獲取下一個節(jié)點的文本內(nèi)容,temp、pm也是一樣

        case XmlPullParser.START_TAG:
        //獲取當前節(jié)點的名字
            if("weather".equals(xp.getName())){
                citys = new ArrayList<City>();
            }
            else if("city".equals(xp.getName())){
                city = new City();
            }
            else if("name".equals(xp.getName())){
                //獲取當前節(jié)點的下一個節(jié)點的文本
                String name = xp.nextText();
                city.setName(name);
            }
            else if("temp".equals(xp.getName())){
                String temp = xp.nextText();
                city.setTemp(temp);
            }
            else if("pm".equals(xp.getName())){
                String pm = xp.nextText();
                city.setPm(pm);
            }
            break;
      
  • 當解析到city的結(jié)束節(jié)點時,說明city的三個子節(jié)點已經(jīng)全部解析完了,把city對象添加至list

      case XmlPullParser.END_TAG:
          if("city".equals(xp.getName())){
                  citys.add(city);
          }
    

測試(了解)

  • 黑盒測試

    • 測試邏輯業(yè)務(wù)
  • 白盒測試

    • 測試邏輯方法
  • 根據(jù)測試粒度

    • 方法測試:function test
    • 單元測試:unit test
    • 集成測試:integration test
    • 系統(tǒng)測試:system test
  • 根據(jù)測試暴力程度

    • 冒煙測試:smoke test
    • 壓力測試:pressure test

單元測試junit(熟悉)

  • 定義一個類繼承AndroidTestCase,在類中定義方法,即可測試該方法

  • 在指定指令集時,targetPackage指定你要測試的應(yīng)用的包名

      <instrumentation 
      android:name="android.test.InstrumentationTestRunner"
      android:targetPackage="com.itheima.junit"
      ></instrumentation>
    
  • 定義使用的類庫

      <uses-library android:name="android.test.runner"></uses-library>
    
  • 斷言的作用,檢測運行結(jié)果和預(yù)期是否一致

  • 如果應(yīng)用出現(xiàn)異常,會拋給測試框架


SQLite數(shù)據(jù)庫(掌握)

  • 輕量級關(guān)系型數(shù)據(jù)庫
  • 創(chuàng)建數(shù)據(jù)庫需要使用的api:SQLiteOpenHelper
    • 必須定義一個構(gòu)造方法:

        //arg1:數(shù)據(jù)庫文件的名字
        //arg2:游標工廠
        //arg3:數(shù)據(jù)庫版本
        public MyOpenHelper(Context context, String name, CursorFactory factory, int version){
      
        }
      
    • 數(shù)據(jù)庫被創(chuàng)建時會調(diào)用:onCreate方法

    • 數(shù)據(jù)庫升級時會調(diào)用:onUpgrade方法

創(chuàng)建數(shù)據(jù)庫

//創(chuàng)建OpenHelper對象
MyOpenHelper oh = new MyOpenHelper(getContext(), "person.db", null, 1);
//獲得數(shù)據(jù)庫對象,如果數(shù)據(jù)庫不存在,先創(chuàng)建數(shù)據(jù)庫,后獲得,如果存在,則直接獲得
SQLiteDatabase db = oh.getWritableDatabase();
  • getWritableDatabase():打開可讀寫的數(shù)據(jù)庫

  • getReadableDatabase():在磁盤空間不足時打開只讀數(shù)據(jù)庫,否則打開可讀寫數(shù)據(jù)庫

  • 在創(chuàng)建數(shù)據(jù)庫時創(chuàng)建表

      public void onCreate(SQLiteDatabase db) {
          // TODO Auto-generated method stub
          db.execSQL("create table person (_id integer primary key autoincrement, name char(10), phone char(20), money integer(20))");
      }
    

數(shù)據(jù)庫的增刪改查(掌握)

SQL語句

  • insert into person (name, phone, money) values ('張三', '159874611', 2000);
  • delete from person where name = '李四' and _id = 4;
  • update person set money = 6000 where name = '李四';
  • select name, phone from person where name = '張三';

執(zhí)行SQL語句實現(xiàn)增刪改查

    //插入
    db.execSQL("insert into person (name, phone, money) values (?, ?, ?);", new Object[]{"張三", 15987461, 75000});
    //查找
    Cursor cs = db.rawQuery("select _id, name, money from person where name = ?;", new String[]{"張三"});
  • 測試方法執(zhí)行前會調(diào)用此方法

      protected void setUp() throws Exception {
          super.setUp();
          //                    獲取虛擬上下文對象
          oh = new MyOpenHelper(getContext(), "people.db", null, 1);
      }
    

使用api實現(xiàn)增刪改查

  • 插入

      //以鍵值對的形式保存要存入數(shù)據(jù)庫的數(shù)據(jù)
      ContentValues cv = new ContentValues();
      cv.put("name", "劉能");
      cv.put("phone", 1651646);
      cv.put("money", 3500);
      //返回值是改行的主鍵,如果出錯返回-1
      long i = db.insert("person", null, cv);
    
  • 刪除

      //返回值是刪除的行數(shù)
      int i = db.delete("person", "_id = ? and name = ?", new String[]{"1", "張三"});
    
  • 修改

      ContentValues cv = new ContentValues();
      cv.put("money", 25000);
      int i = db.update("person", cv, "name = ?", new String[]{"趙四"});
    
  • 查詢

      //arg1:要查詢的字段
      //arg2:查詢條件
      //arg3:填充查詢條件的占位符
      Cursor cs = db.query("person", 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);
      }
    

事務(wù)

  • 保證多條SQL語句要么同時成功,要么同時失敗

  • 最常見案例:銀行轉(zhuǎn)賬

  • 事務(wù)api

      try {
          //開啟事務(wù)
          db.beginTransaction();
          ...........
          //設(shè)置事務(wù)執(zhí)行成功
          db.setTransactionSuccessful();
      } finally{
          //關(guān)閉事務(wù)
          //如果此時已經(jīng)設(shè)置事務(wù)執(zhí)行成功,則sql語句生效,否則不生效
          db.endTransaction();
      }
    

把數(shù)據(jù)庫的數(shù)據(jù)顯示至屏幕(了解)

  1. 任意插入一些數(shù)據(jù)
  • 定義業(yè)務(wù)bean:Person.java

  • 讀取數(shù)據(jù)庫的所有數(shù)據(jù)

     Cursor cs = db.query("person", 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"));
         //把讀到的數(shù)據(jù)封裝至Person對象
         Person p = new Person(name, phone, money);
         //把person對象保存至集合中
         people.add(p);
     }
    
  • 把集合中的數(shù)據(jù)顯示至屏幕

       LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
       for(Person p : people){
           //創(chuàng)建TextView,每條數(shù)據(jù)用一個文本框顯示
           TextView tv = new TextView(this);
           tv.setText(p.toString());
           //把文本框設(shè)置為ll的子節(jié)點
           ll.addView(tv);
       }
    
  • 分頁查詢

      Cursor cs = db.query("person", null, null, null, null, null, null, "0, 10");
    

ListView(掌握)

  • 用于顯示列表
  • MVC結(jié)構(gòu)
    • M:model模型層,要顯示的數(shù)據(jù) ————people集合
    • V:view視圖層,用戶看到的界面 ————ListView
    • c:control控制層,操作數(shù)據(jù)如何顯示 ————adapter對象
  • 每一個條目都是一個View對象

BaseAdapter

  • 必須實現(xiàn)的兩個方法

    • 第一個

        //系統(tǒng)調(diào)用此方法,用來獲知模型層有多少條數(shù)據(jù)
        @Override
        public int getCount() {
            return people.size();
        }
      
    • 第二個

        //系統(tǒng)調(diào)用此方法,獲取要顯示至ListView的View對象
        //position:是return的View對象所對應(yīng)的數(shù)據(jù)在集合中的位置
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            System.out.println("getView方法調(diào)用" + position);
            TextView tv = new TextView(MainActivity.this);
            //拿到集合中的元素
            Person p = people.get(position);
            tv.setText(p.toString());
            
            //把TextView的對象返回出去,它會變成ListView的條目
            return tv;
        }
      
  • 屏幕上能顯示多少個條目,getView方法就會被調(diào)用多少次,屏幕向下滑動時,getView會繼續(xù)被調(diào)用,創(chuàng)建更多的View對象顯示至屏幕

條目的緩存

  • 當條目劃出屏幕時,系統(tǒng)會把該條目緩存至內(nèi)存,當該條目再次進入屏幕,系統(tǒng)在重新調(diào)用getView時會把緩存的條目作為convertView參數(shù)傳入,但是傳入的條目不一定是之前被緩存的該條目,即系統(tǒng)有可能在調(diào)用getView方法獲取第一個條目時,傳入任意一個條目的緩存

ArrayAdapter(熟悉)

  • 在條目中顯示一個字符串

      String[] objects = new String[]{
              "張三",
              "李四",
              "王五"
      };
      
      ListView lv = (ListView) findViewById(R.id.lv);
      //arg1:指定要填充的布局文件
      //arg2:指定文本顯示至哪一個文本框內(nèi)
      lv.setAdapter(new ArrayAdapter<String>(this, R.layout.item_array, R.id.tv_name, objects));
    

SimpleAdapter(熟悉)

  • 可在條目中顯示多種數(shù)據(jù)

  • 要顯示的數(shù)據(jù)封裝在List中,集合的每一個元素存放的是一個條目會顯示的數(shù)據(jù),因為可能會有多種數(shù)據(jù),而集合的泛型只能指定一種數(shù)據(jù),所以把數(shù)據(jù)先存放在Map中,在把Map放入List中

       List<Map<String, Object>> data = new ArrayList<Map<String,Object>>();
       
       //張三的頭像和名字是兩種類型的數(shù)據(jù),先封裝至Map
       Map<String, Object> map1 = new HashMap<String, Object>();
       map1.put("name", "張三");
       map1.put("image", R.drawable.photo1);
       //把Map封裝至List
       data.add(map1);
       ...
    
  • 通過兩個數(shù)組的下標對應(yīng)指定數(shù)據(jù)存放入對應(yīng)的控件中
    lv.setAdapter(new SimpleAdapter(this, data, R.layout.item_array,
    new String[]{"name", "image"}, new int[]{R.id.tv_name, R.id.iv_photo}));

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容