自己為什麼要學android 本人作為應屆畢業生,自己進入社會前做過好多夢,可是呢,現實還是打敗了無邪!!面對社會的壓力和殘酷的競爭力自己如何生成下去??我自己對自己說:第一步 先養活自己,才能走好以後的路 開始接觸手機端android那時感覺,做android開發的工資高、android前景廣。可 ...
自己為什麼要學android
- 本人作為應屆畢業生,自己進入社會前做過好多夢,可是呢,現實還是打敗了無邪!!面對社會的壓力和殘酷的競爭力自己如何生成下去??我自己對自己說:第一步
先養活自己,才能走好以後的路 開始接觸手機端android那時感覺,做android開發的工資高、android前景廣。可是自己在學校那時自學了,最後自己沒有堅持走下去。因為開始接觸新的東西,自己要付出很多努力和時間,主要是自己那時不懂的利用好網路資源、遇到問題不知道怎麼去咨詢解決,碰了很多壁和走了彎路!自己就去學了C/C++、JavaWeb,也接觸過Python,大學生活自己過的一團遭,回想起來自己很`Loser`
- 現在2016年就不一樣了,自己拾起Android,中間經歷了好多,得到過好多人的指導、幫助.自己也在默默努力加油,一直在android的路上.......
-
Android基礎
-
Android學習路線
-
Android操作系統介紹
- android系統是由安迪魯賓團隊開發的,最初用於數位相機,2005.08被google收購 android名字是因為安迪魯賓喜歡一個游戲的人物--大瓢蟲 android圖標:上廁所的靈感--避免權種族歧視 android應用範圍:手機,平板,智能家居,穿戴設備。
-
Android系統架構---分層的架構
- application :應用層 ; java application framework :應用框架層 , java+JNI
- libraries 和 dalvik : 函數庫和虛擬機層, c/c++ linux kernel : linux 內核驅動層, c.
-
-
DDMS介紹
- ddms: dalvik debug manitor services
- devices: 列出當前電腦所連接的所有android設備,及android設備運行的進程,結束一個進程,設置程式為debug模式,截屏。
- logcat: 會列印系統運行過程中所有日誌信息。
- file explorer: 列出當前設備所有目錄。
- /data/app:安裝的第三方apk都在此目錄
- /system/app: 系統預裝應用apk在此目錄
- /data/data:應用的私有目錄,系統每安裝一個新的應用程式,都會在此目錄創建該應用包名的文件,用來存放該應用的私有數據,當應用卸載時,該包名的文件夾也會被刪除。
- /sdcard :外部存儲目錄,一般會鏈接指向到另一個目錄,用來存放大數據。
-
android工程目錄結構
- src文件夾:該文件夾是放項目的源代碼的。
- gen文件夾:該文件夾下麵有個R.java文件,R.java是在建立項目時自動生成的,這個文件是只讀模式的,不能更改。R.java文件中定義了一個類——R,R類 中包含很多靜態類,且靜態類的名字都與res中的一個名字對應,即R類定義該項目所有資源的索引。
- Android 2.1文件夾:該文件夾下包含android.jar文件,這是一個Java 歸檔文件,其中包含構建應用程式所需的所有的Android SDK 庫(如Views、Controls)和APIs。通過android.jar將自己的應用程式綁定到Android SDK和Android Emulator,這允許你使用所有Android的庫和包,且使你的應用程式在適當的環境中調試。
- assets:包含應用系統需要使用到的諸如mp3、視頻類的文件。
- res文件夾:放置應用 程式 用到的資源 文件。其包含(Drawable,layout,values等目錄)。當這個目錄下的文件發生變化時,src目錄下麵的R.java就會自動發生變化。 res/drawable:放置應用到的圖片資源。
- res/layout:放置一些與UI相應的佈局文件,都是xml文件。 res/values:放置字元串,顏色,數組等常量數據。
- default.properties:記錄項目中所需要的環境信息,比如Android的版本等
1 This file is automatically generated by Android Tools. 2 # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 # 4 # This file must be checked in Version Control Systems. 5 # 6 # To customize properties used by the Ant build system use, 7 # "build.properties", and override values to adapt the script to your 8 # project structure. 9 10 # Indicates whether an apk should be generated for each density. 11 split.density=false 12 # Project target. 13 target=android-7
- AndroidManifest.xml:相當於應用的配置文件。在此文件里必須聲明應用的名稱,應用所用到的Activity,Service ,Reveiver等。
1 <?xml version="1.0" encoding="utf-8"?> 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.intentcallphone" android:versionCode="1" android:versionName="1.0" > 3 <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="21" /> <uses-permission android:name="android.permission.CALL_PHONE" />" <!-- 代表當前應用 --> 4 <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > 5 <activity android:name=".MainActivity" android:label="@string/app_name" > 6 <!-- main主入口 --> <!-- 意圖過濾器 --> 7 <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> 8 </intent-filter> 9 </activity> 10 </application> 11 </manifest>
-
四種方法寫按鈕點擊事件
-
直接通過id查找後,綁定匿名內部類作為事件監聽類。
1 Button loginButton = (Button) findViewById(R.id.tologin1); btn1.setOnclickListener(new OnclickListener(){ 2 public void onClick(View v){ 3 // 要執行的操作 4 } }); 5 優缺點:好的是比較直觀方便,不好的是,如果按鈕多了,代碼看起來比較亂。
-
實現點擊事件的介面,然後一個個按鈕地去綁定,最後統一做處理。
1 public class ActivityLogin1 extends Activity implements View.OnClickListener 2 3 btnLogin = (Button) findViewById(R.id.btnLogin); 4 btnLogin.setOnClickListener(this); 5 6 btnBack = (Button) findViewById(R.id.back); 7 btnBack.setOnClickListener(this); 8 9 @Override 10 public void onClick(View v) { 11 switch (v.getId()) { 12 case R.id.back: 13 //對應操作 14 break; 15 case R.id.btnLogin: 16 //對應操作 17 break; 18 19 ....... 20 這種方法有點批量處理的味道。統一處理,可以讓代碼看起來更加結構化。 21 } 22 }
-
自定義監聽事件類,實現點擊事件的介面。
1 Button btn1=(Button)findViewById(R.id.myButton1); 2 Button btn2=(Button)findViewById(R.id.myButton2); 3 btn1.setOnclickListener(new Startclick()); 4 btn2.setOnclickListener(new Stopclick()); 5 6 class StartClick implements OnClickListener{ 7 public void onClick(View v){//或直接跟上要執行的動作 8 switch(v.getId()){ 9 case R.id.myButton1: 10 //要執行的動作 11 } 12 } 13 } 14 15 class StopClick implements OnClickListener{////或直接跟上要執行的動作 16 public void onClick(View v){ 17 switch(v.getId()){ 18 case R.id.myButton2: 19 //要執行的動作 20 } 21 } 22 }
- 在xml佈局里,設置onClick屬性監聽
1 android:id="@+id/pay" 2 android:layout_width="fill_parent" 3 android:layout_height="wrap_content" 4 android:layout_margin="10dp" 5 android:onClick="pay" 6 android:text="支付" 7 tools:ignore="HardcodedText" /> 8 9 public void pay(View v) { 10 //要執行的操作 11 }
-
存儲到SD卡,獲取SD的大小及可用空間
-
許可權問題: 1 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
-
硬性編碼問題:通過 Environment可以獲取sdcard的路徑: 1 Environment.getExternalStorageDirectory().getPath();
-
使用前需要判斷sdcard狀態
1 if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ 2 //sdcard狀態是沒有掛載的情況 3 Toast.makeText(mContext, "sdcard不存在或未掛載", Toast.LENGTH_SHORT).show(); 4 return ; 5 }
需要判斷sdcard剩餘空間
1 //判斷sdcard存儲空間是否滿足文件的存儲 2 File sdcard_filedir = Environment.getExternalStorageDirectory();//得到sdcard的目錄作為一個文件對象 3 long usableSpace = sdcard_filedir.getUsableSpace();//獲取文件目錄對象剩餘空間 4 long totalSpace = sdcard_filedir.getTotalSpace(); 5 //將一個long類型的文件大小格式化成用戶可以看懂的M,G字元串 6 String usableSpace_str = Formatter.formatFileSize(mContext, usableSpace); 7 tring totalSpace_str = Formatter.formatFileSize(mContext, totalSpace); 8 if(usableSpace < 1024 * 1024 * 200){//判斷剩餘空間是否小於200M 9 Toast.makeText(mContext, "sdcard剩餘空間不足,無法滿足下載;剩餘空間為:"+usableSpace_str, Toast.LENGTH_SHORT).show(); 10 return ; 11 } 12 13 /data/data: context.getFileDir().getPath(); 14 是一個應用程式的私有目錄,只有當前應用程式有許可權訪問讀寫,其他應用無許可權訪問。一些安全性要求比較高的數據存放在該目錄,一般用來存放size比較小的數據。 15 /sdcard: Enviroment.getExternalStorageDirectory().getPath(); 16 是一個外部存儲目錄,只用應用聲明瞭<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>的一個許可權,就可以訪問讀寫sdcard目錄;所以一般用來存放一些安全性不高的數據,文件size比較大的數據。
-
SharedPreferences介紹
-
用來做數據存儲 ----sharedPreferences是通過xml文件來做數據存儲的。 一般用來存放一些標記性的數據,一些設置信息。
-
*********使用sharedPreferences存儲數據*********
1 1.通過Context對象創建一個SharedPreference對象 2 //name:sharedpreference文件的名稱 mode:文件的操作模式 3 SharedPreferences sharedPreferences = context.getSharedPreferences("userinfo.txt", Context.MODE_PRIVATE); 4 5 2.通過sharedPreferences對象獲取一個Editor對象 6 Editor editor = sharedPreferences.edit(); 7 8 3.往Editor中添加數據 9 editor.putString("username", username); 10 editor.putString("password", password); 11 12 4.提交Editor對象 13 editor.commit();
*********使用sharedPreferences讀取數據數據*********
1 1.通過Context對象創建一個SharedPreference對象 2 SharedPreferences sharedPreferences = context.getSharedPreferences("userinfo.txt", Context.MODE_PRIVATE); 3 4 2.通過sharedPreference獲取存放的數據 5 //key:存放數據時的key defValue: 預設值,根據業務需求來寫 6 String username = sharedPreferences.getString("username", ""); 7 String password = sharedPreferences.getString("password", ""); 8 9 通過PreferenceManager可以獲取一個預設的sharepreferences對象 10 SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
-
生成xml的兩種方式
- DOM解析:是一種基於對象的API,它會將XML文件的所以內容以
文檔書方式
放在記憶體中,然後允許使用DOM API遍歷XML樹、檢索所需的數據,這樣便能根據樹的結構以節點(標簽)
形式進行操作優缺點:較小的XML文件可以採用這種方式解析,但較大的文件不建議採用這種方式來解析。
- SAX解析:逐漸掃描XML的文檔,當遇到標簽時出發解析處理器,採用
事件處理
的方式解析XML。它在讀取文檔的同時即可對XML進行處理,不必等到文檔載入結束,相對快捷。SAX解析不存在占用記憶體的問題,並且可以解析超大XML,但是,SAX解析只能用來讀取XML中的數據,無法進行增刪改
。 - PULL解析:這是一個開源的javascript項目,Android已經集成了PULL解析,因此,Android中最常用的解析方式就是:PULL解析。
- 常用邏輯:
1 1.寫佈局 2 3 2.業務邏輯 4 a.備份 5 1.封裝簡訊數據到list中 6 2.將list中的數據寫到xml文件中。 7 b.恢復 8 1.解析xml文件中簡訊數據,封裝到list集合中 9 2.將解析數據列印。 10 11 XmlPullParser 12 13 //使用XmlSerializer來序列化xml文件 14 public static boolean backupSms_android(Context context){ 15 16 try{ 17 18 //[0]獲取簡訊數據 19 ArrayList<SmsBean> allSms = SmsDao.getAllSms(); 20 //[1]通過Xml獲取一個XmlSerializer對象 21 XmlSerializer xs = Xml.newSerializer(); 22 //[2]設置XmlSerializer的一些參數,比如:設置xml寫入到哪個文件中 23 //os:xml文件寫入流 encoding:流的編碼 24 xs.setOutput(context.openFileOutput("backupsms2.xml", Context.MODE_PRIVATE), "utf-8"); 25 //[3]序列化一個xml的聲明頭 26 //encoding:xml文件的編碼 standalone:是否獨立 27 xs.startDocument("utf-8", true); 28 //[4]序列化一個根節點的開始節點 29 //namespace:命名空間 name: 標簽的名稱 30 xs.startTag(null, "Smss"); 31 //[5]迴圈遍歷list集合序列化一條條簡訊 32 33 for (SmsBean smsBean : allSms) { 34 xs.startTag(null, "Sms"); 35 //name:屬性的名稱 value:屬性值 36 xs.attribute(null, "id", smsBean.id+""); 37 38 xs.startTag(null, "num"); 39 //寫一個標簽的內容 40 xs.text(smsBean.num); 41 xs.endTag(null, "num"); 42 43 xs.startTag(null, "msg"); 44 xs.text(smsBean.msg); 45 xs.endTag(null, "msg"); 46 47 xs.startTag(null, "date"); 48 xs.text(smsBean.date); 49 xs.endTag(null, "date"); 50 51 xs.endTag(null, "Sms"); 52 } 53 54 //[6]序列化一個根節點的結束節點 55 xs.endTag(null, "Smss"); 56 //[7]將xml寫入到文件中,完成xml的序列化 57 xs.endDocument(); 58 return true; 59 60 }catch (Exception e) { 61 e.printStackTrace(); 62 } 63 return false; 64 }
- 使用pull解析xml格式的數據
1 dom解析:基於全文載入的解析方式 sax解析:基於事件的逐行解析方式 pull解析:同sax 2 3 生成 XmlSerializer 模板代碼 4 解析 XmlPullParser 模板代碼 5 6 7 //解析xml文件讀取簡訊內容 8 public static int restoreSms(Context context) { 9 ArrayList<SmsBean> arrayList = null; 10 SmsBean smsBean = null; 11 try{ 12 //1.通過Xml獲取一個XmlPullParser對象 13 XmlPullParser xpp = Xml.newPullParser(); 14 //2.設置XmlPullParser對象的參數,需要解析的是哪個xml文件,設置一個文件讀取流 15 16 //通過context獲取一個資產管理者對象 17 AssetManager assets = context.getAssets(); 18 //通過資產管理者對象能獲取一個文件讀取流 19 InputStream inputStream = assets.open("backupsms.xml"); 20 xpp.setInput(inputStream,"utf-8"); 21 //xpp.setInput(context.openFileInput("backupsms2.xml"), "utf-8"); 22 //3.獲取當前xml行的事件類型 23 int type = xpp.getEventType(); 24 //4.判斷事件類型是否是文檔結束的事件類型 25 while(type != XmlPullParser.END_DOCUMENT){ 26 //5.如果不是,迴圈遍歷解析每一行的數據。解析一行後,獲取下一行的事件類型 27 28 String currentTagName = xpp.getName(); 29 //判斷當前行的事件類型是開始標簽還是結束標簽 30 switch (type) { 31 case XmlPullParser.START_TAG: 32 if(currentTagName.equals("Smss")){ 33 //如果當前標簽是Smss,需要初始化一個集合 34 arrayList = new ArrayList<SmsBean>(); 35 }else if(currentTagName.equals("Sms")){ 36 37 smsBean = new SmsBean(); 38 smsBean.id = Integer.valueOf(xpp.getAttributeValue(null, "id")); 39 40 }else if(currentTagName.equals("num")){ 41 smsBean.num = xpp.nextText(); 42 }else if(currentTagName.equals("msg")){ 43 smsBean.msg = xpp.nextText(); 44 }else if(currentTagName.equals("date")){ 45 smsBean.date = xpp.nextText(); 46 } 47 break; 48 case XmlPullParser.END_TAG: 49 //當前結束標簽是Sms的話,一條簡訊數據封裝完成, 可以加入list中 50 if(currentTagName.equals("Sms")){ 51 arrayList.add(smsBean); 52 } 53 break; 54 default: 55 break; 56 } 57 58 type = xpp.next();//獲取下一行的事件類型 59 } 60 61 return arrayList.size(); 62 63 }catch (Exception e) { 64 e.printStackTrace(); 65 }