Android基礎知識整理
1. 虛擬機器
認知: ART是趨勢,DalVik已經慢慢在被淘汰
ART,即Android Runtime。ART 的機制與 Dalvik 不同。在Dalvik下,應用每次執行的時候,位元組碼都需要通過即時編譯器(just in time ,JIT)轉換為機器碼,這會拖慢應用的執行效率,而在ART 環境中,應用在第一次安裝的時候,位元組碼就會預先編譯成機器碼,使其成為真正的本地應用。這個過程叫做預編譯(AOT,Ahead-Of-Time)。這樣的話,應用的啟動(首次)和執行都會變得更加快速。
2. 相關資源
3. 元件
3.1 Button
3.1.1 Button點選事件觸發的兩種方法:
- 在activity中
bt.setOnClickListener(new onClickListener())
- 在layout中,bt設定一個屬性
android:onClick = "something"
,然後在activity中定義一個同名的方法public void something(View v){}
這個方法所接收的引數為一個View物件,當按鈕被按下時,系統會呼叫這個something()
方法
注意,在onClick方法中傳入的View物件是被點選的button物件,所以多個button可以共用一個點選監聽,只要在監聽裡面用
bt.getId()
來最終區分出來是哪個button就可以分別處理而不干擾。
有一個疑問就是:共用監聽or單獨監聽(每個button一個內部類)or在layout中設定onClick
這幾種方式在消耗記憶體上有啥區別?
3.1.2 設定半透明度
-
在xml檔案中:
- 半透明:
<Button android:background="#e0000000" ... />
- 透明:
<Button android:background="#00000000" ... />
- 半透明:
-
在java程式碼中:
btn.getBackground().setAlpha(100)
//0~255透明度
-
數值量:
- 顏色和不透明度 (alpha) 值以十六進位制表示法表示。任何一種顏色的值範圍都是 0 到 255(00 到 ff)。
- 對於 alpha,00 表示完全透明,ff 表示完全不透明。
- 表示式順序是
“aabbggrr”
,其中“aa=alpha”(00 到 ff);“bb=blue”(00 到 ff);“gg=green”(00 到 ff);“rr=red”(00 到 ff)。 - 例如,如果您希望對某疊加層應用不透明度為 50% 的藍色,則應指定以下值:7fff0000
4. 佈局
開發中用的最多的是linearlayout
和relativelayout
4.1 LinearLayout
單純線性佈局永遠不會發生元件的重疊
LinearLayout中的layout_weight屬性:
layout_weight
屬性用於分配LinearLayout
中的的額外空間(extra space)。
如果View不想拉伸的話,layout_weight
值設定為0。否則的話這些畫素會按比例分配到weight值大於0的所有View。
換句話說,也就是android:layout_weight
屬性告知LinearLayout
如何進行子元件的佈置安排。
4.2 RelativeLayout
在relativelayout
中預設的對齊方式是左對齊和頂部對齊,可以通過設定android:layout_align*="true"("id")
或者layout_above="id"
或者layout_toLeftOf="@id/*"
等屬性來改變,而居中等可以通過android:centerIn*
來設定
假設有兩個物件(id分別為tv1和tv2)第二個物件設定了兩個屬性alignRight="@id/tv1"
、alignLeft="@id/tv1"
,那麼第二個物件就會和第一個物件等寬
4.3 FrameLayout
幀佈局是五大布局中最簡單的佈局方式,在需要佈局中有空間重疊的情況下才使用。
frameLayout
中的所有檢視都已以層疊的方式展現的。第一個新增到佈局中的檢視顯示在最底層,最後一個被放在最頂層。上一層的檢視會覆蓋下一層的檢視,因此該佈局類似於堆疊佈局。
-
在
framelayout
中子檢視預設的對齊方式也是左對齊和頂部對齊,可以通過設定android:layout_gravity="left|buttom"
等屬性來改變 -
在
framelayout
中,空間的layout_margin
屬性需要依賴layout_gravity
屬性,否則設定無效。layout_margin
所示的邊緣值是相對於控制元件的layout_gravity
所定義的參考點而言的。 -
如果以圖片作為
linearLayout
的背景,那麼將無法控制佈局的高和寬,其尺寸會不受控制地適應圖片的大小,因此採用frameLayout
配合imageView
新增可大小可控的背景
4.4 TableLayout
<TableLayout>
<!--tableRow中有幾個子標籤就有幾列-->
<TableRow> </TableRow>
<TavleRow> </TableRow>
</TableLayout>
寬高:
在表格佈局中每個tableRow
的寬高是有個預設值的,預設的寬是match_parent
預設的高是wrap_content
,同時寬高也是不可更改的,改了也無效
可以在TableLayout
中設定stretchColumns="*"
設定拉伸列
分割線:
如果想在表格中插入一個分割線,可以在<TableLayout>
中加入一個直接子標籤<TextView>
,將其高度設為1個dp,設定下顏色就好了
兩個獨有的屬性:
可以通過layout_column=""
直接設定某個元素在第幾列,這樣就可以不必從第0列開始
可以通過layout_span=""
來設定某一個元素佔幾列
5. 讀寫檔案
儲存空間包括內部儲存空間和外部儲存空間
5.1 內部儲存空間(ROM)
內部儲存讀寫檔案不需要許可權,因為只能寫自己包內的檔案,其他包不能動,除非有root許可權
5.1.1 絕對路徑
File file = new File("data/data/com.example.*/file");
FileOutputStream fos = new FileOutStream(file);
fos.write(string.getBytes());
5.1.2 使用路徑api
可以通過getFilesDir()
來獲得data/data/com.example.*/file
資料夾的路徑.,所以可以這樣寫:
File file = new File(getFilesDir(),“name.txt”);
而通過getCacheDir()
可以獲得
data/data/com.example.*/cache
資料夾的路徑
從原始碼看,兩者的區別是:當rom空間不夠的時候,cache資料夾中的東西有可能會被系統刪除,但是不能指望系統去刪除,應該自己設定一個閾值 在設定中點選儲存,選擇相應的應用,可以選擇清除快取和清除資料,前者會清空cache資料夾中的所有檔案,而後者會刪除包內所有的使用者檔案
5.2 外部儲存讀寫(sd卡)
外部儲存寫資料需要許可權WRITE_EXTERNAL_STORAGE
,而讀資料則不一定,要看開發者選項裡面是否勾選了sd卡讀防寫
5.2.1 絕對路徑
各個廠商的sd卡的路徑差不多都不一樣,要注意
File file = new File("sdcard/file.*")
5.2.2 使用路徑api
這個api名字突出一個長啊,使用之前先判斷sd卡是否可用
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
File file = new File(Environment.getExternalStorageDirectory(),"name");
}
其中,sd卡的狀態可以有:
狀態 | 說明 |
---|---|
REMOVE |
沒有插sd卡 |
UNMOUNT |
sd卡已插,但是沒有掛載 |
CHECKING |
sd卡正在被系統遍歷 |
MOUNTED |
sd卡準備就緒,可以讀寫 |
MOUNTED_READ_ONLY |
sd卡可用,但是隻讀 |
5.2.3 獲取sd卡的剩餘空間
可以參看設定系統應用的原始碼,放在package/apps/Settings
中,具體用的時候可以google找輪子
sd卡儲存空間 = 可用的區塊數量*區塊大小(blockSize)
5.3 檔案訪問許可權
許可權的表現形式:
d rwx rwx rwx
一共十位
- 在Android中,每一個應用都是一個獨立的使用者
d
:代表資料夾,檔案是-- 第一個
rwx
:決定owner使用者對此檔案的許可權- r:讀
- w:寫
- x:執行(execute)
具體程式設計時,當我們需要在應用中寫入一個一定許可權的檔案的時候:
public void bt_click(View v){
//此api會把檔案寫到data/data/com.xxx.xxx/files資料夾下
try{
FileOutputStream fos = openFileOutput("example.txt", MODE_WORLD_READABLE);
fos.write("哈哈".getBytes());
fos.close();
}catch(Exception e){
e.printStackTrace();
}
}
其中要說明的是openFileOutput是Context提供的一個很要用的方法,但是隻能寫到本應用對應的資料夾下:
5.4 使用Shared Preference存取簡單資料
SharedPreferences的使用非常簡單,能夠輕鬆的存放資料和讀取資料。SharedPreferences只能儲存簡單型別的資料,例如,String、int等。一般會將複雜型別的資料轉換成Base64編碼,然後將轉換後的資料以字串的形式儲存在 XML檔案中,再用SharedPreferences儲存。
具體的方法參看博文: Android SharedPreferences使用以及原理詳解 **注意:**要使用Activity類的getSharedPreferences方法獲得SharedPreferences物件,而不要new一個新的物件,否則效率不高
6. 除錯時的小技巧
-
真機除錯時eclipse的file explorer打不開data資料夾: 當用真機開發Android時,連線了Eclipse後,預設在File Explorer下是達不開我們手機的data資料夾的,這裡打不開是因為許可權不足。以下有個小技巧可以解決這問題。 首先,測試機先root,然後在手機上安裝上Root Explorer 管理器(或類似軟體),再將/data/data及其子資料夾下的訪問許可權都修改為可讀可寫可執行即可。這時候再使用eclipse的File Explorer就可以展開了,這時候就可以檢視應用下的SQLite資料庫了。
-
當devices中的裝置顯示不出來的時候: 直接使用需要在cmd中cd到sdk的目錄下使用
adb start-server
指令,也可以將該目錄直接加入到系統變數的path中,這樣直接就在cmd任意位置輸入指令即可。本質是個socket。 相關的指令:
adb start-server
其實任何一條adb指令都可以重啟adbadb kill-server
殺死程序adb install apk的路徑
安裝apkadb uninstall com.tristan.something
這裡是寫的包名adb devices
顯示所有連線的android裝置adb shell
進入android系統的命令列(linux)
-
當你的手機助手佔用的系統的adb的埠(5037)怎麼辦? 首先通過
adb devices
檢視埠,然後在windows下cmd使用netstat -ano
檢視當前系統各個埠被什麼程序所佔用 -
專案組織檔案: manifeast中的package是android分辨應用的唯一標識,和gen目錄下的包名相同,與src目錄下的不同 當應用涉及到使用者許可權時,需要到manifesat中去新增許可權(可以通過視覺化操作)
-
檢視日誌: 在logcat中設定過濾器的時候最好根據
Tag
來過濾(比如System.out
輸出的日誌的tag就是System.out
,級別為Info
),而不要用Application
來過濾 logcat語句:Log.e(tag,string) Log.i(tag,string) …
-
URI和URL的區別
//舉例,撥號邏輯
public void onclick(View v){
EditText et = (EditText) findViewById(R.id.et);
String phone = et.getText().toString();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + phone));
}