編輯:Android開發教程
項目源碼下載
https://github.com/Wang-Jun-Chao/AndroidProjects
常見布局
組件默認左對齊、頂部對齊
設置組件在指定組件的右邊
android:layout_toRightOf="@id/tv1"
設置在指定組件的下邊
android:layout_below="@id/tv1"
設置右對齊父元素
android:layout_alignParentRight="true"
設置與指定組件右對齊
android:layout_alignRight="@id/tv1"
指定各個節點的排列方向
android:orientation="horizontal"
設置右對齊
android:layout_gravity="right"
當豎直布局時,只能左右對齊和水平居中,頂部底部對齊豎直居中無效
當水平布局時,只能頂部底部對齊和豎直居中
使用match_parent時注意不要把其他組件頂出去
線性布局非常重要的一個屬性:權重
android:layout_weight="1"
權重設置的是按比例分配剩余的空間
默認組件都是左對齊和頂部對齊,每個組件相當於一個div
可以更改對齊方式
android:layout_gravity="bottom"
不能相對於其他組件布局
每個節點是一行,它的每個子節點是一列
表格布局中的節點可以不設置寬高,因為設置了也無效
根節點的子節點寬為匹配父元素,高為包裹內容
節點的子節點寬為包裹內容,高為包裹內容
以上默認屬性無法修改
根節點中可以設置以下屬性,表示讓第1列拉伸填滿屏幕寬度的剩余空間
android:stretchColumns="1"
直接指定組件的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, "加油吧,童鞋們");
文件讀寫操作
Ram內存:運行內存,相當於電腦的內存
Rom內存:內部存儲空間,相當於電腦的硬盤
sd卡:外部存儲空間,相當於電腦的移動硬盤
小案例:用戶輸入賬號密碼,勾選“記住賬號密碼”,點擊登錄按鈕,登錄的同時持久化保存賬號和密碼
彈土司提示用戶登錄成功
Toast.makeText(this, "登錄成功", Toast.LENGTH_SHORT).show();
判斷用戶是否勾選保存賬號密碼
CheckBox cb = (CheckBox) findViewById(R.id.cb);
if(cb.isChecked()){
}
直接開啟文件輸出流寫數據
//持久化保存數據
File file = new File("data/data/com.itheima.rwinrom/info.txt");
FileOutputStream fos = new FileOutputStream(file);
fos.write((name + "##" + pass).getBytes());
fos.close();
讀取數據前先檢測文件是否存在
if(file.exists())
讀取保存的數據,也是直接開文件輸入流讀取
File file = new File("data/data/com.itheima.rwinrom/info.txt");
FileInputStream fis = new FileInputStream(file);
//把字節流轉換成字符流
BufferedReader br = new BufferedReader(new InputStreamReader(fis));
String text = br.readLine();
String[] s = text.split("##");
讀取到數據之後,回顯至輸入框
et_name.setText(s[0]);
et_pass.setText(s[1]);
應用只能在自己的包名目錄下創建文件,不能到別人家去創建
需要改動的地方:
項目名字
應用包名
R文件重新導包
getFilesDir()得到的file對象的路徑是data/data/com.itheima.rwinrom2/files
存放在這個路徑下的文件,只要你不刪,它就一直在
getCacheDir()得到的file對象的路徑是data/data/com.itheima.rwinrom2/cache
存放在這個路徑下的文件,當內存不足時,有可能被刪除
系統管理應用界面的清除緩存,會清除cache文件夾下的東西,清除數據,會清除整個包名目錄下的東西
在外部存儲讀寫數據
sdcard:2.3之前的sd卡路徑
mnt/sdcard:4.3之前的sd卡路徑
storage/sdcard:4.3之後的sd卡路徑
最簡單的打開sd卡的方式
File file = new File("sdcard/info.txt");
寫sd卡需要權限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
讀sd卡,在4.0之前不需要權限,4.0之後可以設置為需要
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
使用api獲得sd卡的真實路徑,部分手機品牌會更改sd卡的路徑
Environment.getExternalStorageDirectory()
判斷sd卡是否准備就緒
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
查看源代碼查找獲取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
存儲設備會被分為若干個區塊,每個區塊有固定的大小
區塊大小 * 區塊數量 等於 存儲設備的總大小
Linux文件的訪問權限
在Android中,每一個應用是一個獨立的用戶
drwxrwxrwx
第1位:d表示文件夾,-表示文件
第2-4位:rwx,表示這個文件的擁有者用戶(owner)對該文件的權限
r:讀
w:寫
x:執行
第5-7位:rwx,表示跟文件擁有者用戶同組的用戶(grouper)對該文件的權限
第8-10位:rwx,表示其他用戶組的用戶(other)對該文件的權限
更多精彩內容:http://www.bianceng.cn/OS/extra/
openFileOutput的四種模式
MODE_PRIVATE:-rw-rw—-
MODE_APPEND:-rw-rw—-
MODE_WORLD_WRITEABLE:-rw-rw–w-
MODE_WORLD_READABLE:-rw-rw-r–
用SharedPreference存儲賬號密碼
往SharedPreference裡寫數據
//拿到一個SharedPreference對象
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
//拿到編輯器
Editor ed = sp.edit();
//寫數據
ed.putBoolean("name", name);
ed.commit();
從SharedPreference裡取數據
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
//從SharedPreference裡取數據
String name = sp.getBoolean("name", "");
生成XML文件備份短信
創建幾個虛擬的短信對象,存在list中
備份數據通常都是備份至sd卡
把整個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序列化器對象
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文件,存一些天氣信息
InputStream is = getClassLoader().getResourceAsStream("weather.xml");
XmlPullParser xp = Xml.newPullParser();
拿到指針所在當前節點的事件類型
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);
}
唔,之前已經想過今後不動android,沒想到還是因為比賽的原因重操舊業。android有很多問題是由於eclipse的不完善造成的,比如今天遇到的這個問題 Unable
X86架構的CPU采用的是復雜指令集(Complex Instruction Set Computer,CICS),而ARM架構的CPU使用的是精 簡指令集
Android程序中一旦加載的圖片比較多,就有可能出現Out of Memory而導致程序崩潰。這個一方面是因為Android系統本身對於每個單獨的進程有內存大小的限制(
在上一章節中,我們介紹了數據持久化的幾種方法:首選項,文件,以及數據庫。在保存復雜的數據結構 時,推薦使用SQliteDatabase。但是,共享數據就成了一種挑戰,因為