Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android編程入門 >> Android應用開發-數據存儲和界面展現(一)

Android應用開發-數據存儲和界面展現(一)

編輯:Android編程入門

常見布局

相對布局(RelativeLayout)

  • 組件默認位置都是左上角(左對齊、頂部對齊父元素),組件之間可以重疊

  • 可以相對於父元素上下左右對齊,相對於父元素,水平居中、豎直居中、水平豎直同時居中

    • 設置右對齊父元素

      android:layout_alignParentRight="true"
  • 可以相對於其他組件上下左右對齊

    • 設置與指定組件右對齊

      android:layout_alignRight="@id/tv1"
  • 可以布局於其他組件的上方、下方、左邊、右邊

    • 設置組件在指定組件的右邊

      android:layout_toRightOf="@id/tv1"
    • 設置在指定組件的下邊

      android:layout_below="@id/tv1"

線性布局(LinearLayout)

  • 有一個布局方向,水平或者豎直

    • 指定子組件按水平布局

      android:orientation="horizontal"
  • 在豎直布局下,設置左對齊、右對齊,水平居中會生效,其它無效

  • 在水平布局下,設置頂部對齊、底部對齊、豎直居中會生效,其他無效

  • 使用match_parent時注意不要把其他組件頂出去

  • 權重:按比例分配屏幕的剩余寬度或者高度

    android:layout_weight="1"

幀布局(FrameLayout)

  • 組件默認位置都是左上角(左對齊、頂部對齊父元素),組件之間可以重疊

  • 可以設置上下左右對齊,水平豎直居中,設置方式與線性布局一樣

  • 不能相對於其他組件布局

表格布局(TableLayout)

  • 每個TableRow節點是一行,它的每個子節點是一列

  • 表格布局中的節點可以不設置寬高,因為設置了也無效

    • 根節點TableLayout的子節點寬為匹配父元素,高為包裹內容

    • TableRow節點的子節點寬為包裹內容,高為包裹內容

    • 以上默認屬性無法修改

  • 根節點中可以設置以下屬性,表示讓第1列拉伸填滿屏幕寬度的剩余空間

    android:stretchColumns="1"

絕對布局(AbsoluteLayout)

  • 基本用不到

  • 直接指定組件的x、y坐標

    android:layout_x="144dp"
    android:layout_y="154dp"

Logcat

  • 日志信息總共分為5個等級

    • verbose:冗余,最低等級

    • debug:調試

    • info:正常等級的信息

    • warn:警告

    • error:錯誤

  • 定義過濾器方便查看

  • System.out.print輸出的日志級別是info,tag是System.out

  • Android提供的日志輸出api

    Log.v(TAG, "加油吧,童鞋們");
    Log.d(TAG, "加油吧,童鞋們");
    Log.i(TAG, "加油吧,童鞋們");
    Log.w(TAG, "加油吧,童鞋們");
    Log.e(TAG, "加油吧,童鞋們");

Android的存儲

內部存儲空間

  • RAM內存:運行內存,相當於電腦的內存

  • ROM內存:存儲內存,相當於電腦的硬盤(這個才是內部存儲空間,是必須有的)

外部存儲空間

  • SD卡:相當於電腦的移動硬盤(可有可無)

    • 2.2之前,SD卡路徑:sdcard

    • 4.3之前,SD卡路徑:mnt/sdcard

    • 4.3開始,SD卡路徑:storage/sdcard

    • 為了兼容低版本的程序,Android系統在原SD卡的位置都保留有一個"快捷方式"

現在買的手機,如魅族MX5 16G版,這個16G實際上指的是外部存儲空間,而廠家並沒有告訴我們手機的內部存儲空間是多少


在內部存儲讀寫數據

用API獲得內部存儲的真實路徑

  • getFilesDir()得到的file對象的路徑是data/data/[package name]/files

    • 存放在這個路徑下的文件,只要你不刪,它就一直在
  • getCacheDir()得到的file對象的路徑是data/data/[package name]/cache

    • 存放在這個路徑下的文件,當內存不足時,有可能被刪除
  • 系統管理應用界面的清除緩存,會清除cache文件夾下的東西,清除數據,會清除整個包名目錄下的東西


在外部存儲讀寫數據

  • 最簡單的打開SD卡的方式

    File file = new File("sdcard/xxx.txt");
  • 使用API獲得SD卡的真實路徑,因為部分手機廠商會更改SD卡的路徑

    File file = new File(Environment.getExternalStorageDirectory(),"xxx.txt")
  • 判斷SD卡是否准備就緒

    if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
  • SD卡主要的幾種狀態

    • MEDIA_UNKNOWN:不能識別sd卡

    • MEDIA_REMOVED:沒有sd卡

    • MEDIA_UNMOUNTED:sd卡存在但是沒有掛載

    • MEDIA_CHECKING:sd卡正在准備

    • MEDIA_MOUNTED:sd卡已經掛載,可用

  • 寫SD卡需要權限

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 讀SD卡,在4.0之前不需要權限,4.0之後可以設置為需要

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>

查看源代碼查找獲取SD卡剩余容量的代碼

  • 導入Settings項目

  • 查找“可用空間”得到

     <string name="memory_available" msgid="418542433817289474">"可用空間"</string>
  • 查找"memory_available",得到

    <Preference android:key="memory_sd_avail" 
        style="?android:attr/preferenceInformationStyle" 
        android:title="@string/memory_available"
        android:summary="00"/>
  • 查找"memory_sd_avail",得到

    //這個字符串就是SD卡剩余容量
    formatSize(availableBlocks * blockSize) + readOnly
    //這兩個參數相乘,得到SD卡以字節為單位的剩余容量
    availableBlocks * blockSize
  • 存儲設備會被分為若干個區塊,每個區塊有固定的大小

  • 區塊大小 * 區塊數量 等於 存儲設備的總大小


文件訪問權限

  • 指的是誰能訪問這個文件(夾)

  • 在Android系統中,每一個應用,都是一個獨立的用戶

  • 使用10個字母來表示

  • drwxrwxrwx

  • 第一個字母:

    • d:表示文件夾

    • -:表示文件

  • 第一組rwx:表示的是文件擁有者(owner)對該文件的權限

    • r:read,讀

    • w:write,寫

    • x:execute,執行

  • 第二組rwx:表示的是跟文件擁有者屬於同一用戶組(group)的用戶對該文件的權限

  • 第三組rwx:表示的是其他用戶(other)對該文件的權限


SharedPreference

  • 非常適合用來保存零散的簡單的數據

  • 往SharedPreference裡寫數據

    //拿到一個SharedPreference對象
    SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
    //拿到編輯器
    Editor ed = sp.edit();
    //寫數據
    ed.putString("name", "eniac");
    ed.commit();
  • 從SharedPreference裡取數據

    //拿到一個SharedPreference對象
    SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
    //從SharedPreference裡取數據
    String name = sp.getString("name", "");

生成XML文件備份短信

  • 創建幾個虛擬的短信對象,存在list中

  • 備份數據通常都是備份至SD卡

使用StringBuffer拼接字符串

  • 把整個xml文件所有節點append到sb對象裡

    sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
    //添加smss的開始節點
    sb.append("<smss>");
    .......
  • 把sb寫到輸出流中

    fos.write(sb.toString().getBytes());

使用XMl序列化器生成xml文件

  • 得到xml序列化器對象

    XmlSerializer xs = Xml.newSerializer();
  • 給序列化器設置輸出流

    File file = new File(Environment.getExternalStorageDirectory(), "backupsms.xml");
    FileOutputStream fos = new FileOutputStream(file);
    //給序列化器指定好輸出流
    xs.setOutput(fos, "utf-8");
  • 開始生成xml文件

    xs.startDocument("utf-8", true);
    xs.startTag(null, "smss");
    ......

pull解析xml文件

  • 原始XML資源一般保存在/res/xml/路徑下

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

根據XML資源的ID獲取解析該資源的解析器

    XmlPullParser xp = getResources().getXml(R.xml.weather);

開始解析

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

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

    • START_DOCUMENT:xml頭的事件類型

    • END_DOCUMENT:xml尾的事件類型

    • START_TAG:開始節點的事件類型

    • END_TAG:結束節點的事件類型

    • TEXT:文本節點的事件類型

  • 如果獲取到的事件類型不是END_DOCUMENT,就說明解析還沒有完成,如果是,解析完成,while循環結束

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

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

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

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

      case XmlPullParser.START_TAG:
      //獲取當前節點的名字
          if("weather".equals(xp.getName())){
              citys = new ArrayList<City>();
          }
          else if("city".equals(xp.getName())){
              city = new City();
          }
          else if("name".equals(xp.getName())){
              //獲取當前節點的下一個節點的文本
              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的結束節點時,說明city的三個子節點已經全部解析完了,把city對象添加至list

    case XmlPullParser.END_TAG:
        if("city".equals(xp.getName())){
                citys.add(city);
        }
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved