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

 

常見佈局

 

相對佈局(RelativeLayout)

 

  相對佈局下控件默認位置都是左上角(左對齊、頂部對齊父元素),控件之間能夠重疊android

 

  能夠相對於父元素上下左右對齊,相對於父元素水平居中、豎直居中、水平豎直同時居中數據庫

android:layout_alignParentRight="true"    <!-- 設置右對齊父元素 -->
android:layout_centerHorizontal="true"   <!-- 設置相對父元素水平居中 -->

 

  能夠相對於其餘控件上下左右對齊緩存

android:layout_alignRight="@id/tv1"     <!--設置與指定控件右對齊-->

 

  能夠佈局於其餘控件的上方、下方、左邊、右邊app

android:layout_toRightOf="@id/tv1"    <!-- 設置控件在指定控件的右邊 -->
android:layout_below="@id/tv1"      <!-- 設置控件在指定控件的下邊 -->

 

線性佈局(LinearLayout)

 

  線性佈局有一個佈局方向,水平(horizontal)或者豎直(vertical)編輯器

android:orientation="horizontal"      <!-- 指定子控件按水平佈局 -->

 

  在豎直佈局下,設置左對齊、右對齊,水平居中會生效,其它無效;在水平佈局下,設置頂部對齊、底部對齊、豎直居中會生效,其餘無效工具

  當控件的寬度或高度使用match_parent時有可能把其餘控件頂出屏幕佈局

 

  權重:按比例分配屏幕的剩餘寬度或高度,相應的寬度或高度屬性一般設置爲0dp(不佔用所謂的剩餘寬度或高度)
spa

android:layout_weight="1"          <!-- 佔滿剩餘寬度或高度 -->

 

幀佈局(FrameLayout)

 

  幀佈局下控件的默認位置也是左上角(左對齊、頂部對齊父元素),控件之間能夠重疊 —— 同相對佈局debug

  能夠設置上下左右對齊,水平豎直居中,但不能相對於其餘控件佈局 —— 同線性佈局指針

 

表格佈局(TableLayout)

 

  表格佈局中的節點能夠不設置寬高,由於設置了也無效。根節點TableLayout的子節點寬爲匹配父元素,高爲包裹內容,TableRow節點的子節點寬爲包裹內容,高爲包裹內容。每一個TableRow節點是一行,它的每一個子節點是一列

  根節點中能夠設置如下屬性,表示讓第1列拉伸填滿屏幕寬度的剩餘空間

android:stretchColumns="1"

 

絕對佈局(AbsoluteLayout)

 

  直接指定控件的x、y座標,基本用不到

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

 

 

Logcat

 

   日誌(Log)信息總共分爲5個等級

    verbose:冗餘,最低等級

    debug:調試

    info:正常等級的信息,System.out.print輸出的日誌級別就是是info

    warn:警告

    error:錯誤,最高等級

 

  Android中的日誌工具類是Log(android.util.Log),Android提供以下的日誌輸出API來供咱們打印日誌。其中第一個參數是Tag,一般傳入當前的類名,主要用於對打印信息進行過濾,咱們能夠定義過濾器方便查看日誌信息;第二個參數是咱們想要打印的具體內容

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

 

 

Android手機的存儲

 

  RAM:運行內存,功能至關於電腦的內存

 
  ROM:內部存儲空間,功能至關於電腦的硬盤

 

  SD卡:外部存儲空間,功能至關於電腦的移動硬盤,無關緊要

    Android 2.2以前,SD卡路徑:sdcard

    Android 4.3以前,SD卡路徑:mnt/sdcard

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

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

 

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

 

 

在內部存儲空間讀寫數據

 

用API得到內部存儲空間上app私有目錄的路徑

 

  內部存儲空間上app私有目錄的路徑:data/data/[package name],該目錄會隨着app卸載而被刪除,SharedPreference以及數據庫都保存在該目錄下。

  該目錄下還有兩個子目錄files和cache:

    getFilesDir()獲得的File對象的路徑是data/data/[package name]/files,存放在這個路徑下的文件,只要你不卸載應用或手動刪除這個文件,就會一直存在

    getCacheDir()獲得的File對象的路徑是data/data/[package name]/cache,存放在這個路徑下的文件,當內部存儲空間不足時,也有可能被刪除

  在系統的應用管理頁面點擊清除緩存,會清空cache文件夾下的數據;點擊清除數據,會清除整個[package name]目錄下的數據

 

 

在外部存儲空間讀寫數據

 

最簡單的打開SD卡的方式

 

File file = new File("sdcard/xxx.txt");  // sdcard至關與一個快捷方式

 

使用API得到SD卡的真實路徑,由於部分手機廠商會更改SD卡的路徑

 

File file = new File(Environment.getExternalStorageDirectory(),"xxx.txt")

 

用API得到SD卡上app私有目錄的路徑

 

  外部存儲空間上app私有目錄的路徑:sdcard/Android/data/[package name],該目錄也會隨着app卸載而被刪除,一般將頭像緩存以及只有本應用能打開的文件放在該目錄下。

  該目錄下也有兩個子目錄files和cache:

    getExternalFilesDir()獲得的File對象的路徑是sdcard/Android/data/[package name]/files,存放在這個路徑下的文件,只要你不卸載應用或手動刪除這個文件,就會一直存在

    getExternalCacheDir()獲得的File對象的路徑是sdcard/Android/data/[package name]/cache,存放在這個路徑下的文件,當外部存儲空間不足時,也有可能被刪除

 

判斷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卡須要權限

 

<!-- 配置在SD卡中建立與刪除文件的權限 -->
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<!-- 配置向SD卡寫入數據的權限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 

讀SD卡,在4.0以前不須要權限,4.0以後能夠設置爲須要,若是設置了須要權限

 

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

 

 

從Android源碼中查找獲取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); // 拿到一個SharedPreference對象
Editor ed = sp.edit();          // 拿到編輯器
ed.putString("name", "eniac");     // 寫數據
ed.commit();

 

  從SharedPreference裏取數據

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

 

   上面的SharedPreference會在data/data/[package name]/shared_prefs下生成一個config.xml來保存這些配置信息

 

生成xml文件備份短信

 

  建立幾個虛擬的短信對象,存在List中

  備份數據一般都是備份至SD卡

 

使用StringBuffer拼接字符串生成xml文件(不推薦)

 

  把整個xml文件全部節點append到sb對象裏

sb.append("<?xml version='1.0' encoding='utf-8' standalone='yes' ?>");
sb.append("<smss>");    // 添加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();

 

  pull解析的事件類型主要有五種

  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);
}
相關文章
相關標籤/搜索