1.隱藏標題欄html
在onCreate()方法中添加:
requestWindowFeature(Window.FEATURE_NO_TITLE);//不在活動中顯示標題欄。
須要在setContentView()以前執行。
2.Intent是Android程序中各組件之間進行交互的一種重要方式,它不只能夠指明當前組件想要執行的動做,還能夠在不一樣組件之間傳遞數據。Intent通常可被用於啓動活動、啓動服務、以及發送廣播等場景。
3.<data>標籤中主要能夠配置如下內容:
(1)android:scheme
用於指定數據的協議部分,如http。
(2)android:host
用於指定數據的主機名部分,如www.baidu.com。
(3)android:port
用於指定數據的端口部分,通常緊隨在主機名以後。
(4)android:path
用於指定主機名和端口以後的部分,如一段網址中跟在域名以後的內容。
(5)android:mimiType
用於指定能夠處理的數據類型,容許使用通配符的方式進行指定。
4.onStop()和onPause()方法的主要區別在於:若是啓動的新活動是一個對話框式的活動,那麼onPause()方法就會獲得執行,而onStop()方法並不會執行。java
1.ProgressDialog使用setCancelable()中傳入了false,表示ProgressDialog是不能經過Back鍵取消掉的,
2.TableLayout佈局可使用android:stretchColumns屬性容許將TableLayout中的某一列進行拉伸,以達到自動適應屏幕寬度的做用。
3.ArrayAdapter能夠經過泛型來指定要適配的數據類型,而後在構造函數中把要適配的數據傳入便可。
4.android.R.layout.simple_list_item_1是Android內置的佈局文件,裏面只有一個TextView,可用於簡單地顯示一段文本。
5.dp是密度無關像素的意思,在不一樣密度的屏幕中顯示比例將保持一致。sp是可伸縮像素的意思,解決文字大小的適配問題。
6.Android中的密度就是屏幕每英寸所包含的像素數,一般以dpi爲單位。
7.Nine-Patch圖片是一種被特殊處理過的png圖片,可以指定哪些區域能夠被拉伸而哪些區域不能夠。android
1.碎片(Frgament)是一種能夠嵌入在活動當中的UI片斷,它能讓程序更加合理和充分地利用大屏幕的空間,於是在平板上應用的很是普遍。
2.FragmentTransaction中提供了一個addToBackStack()方法,能夠用於將一個事務添加到返回棧中。
3.爲了方便碎片和活動之間進行通訊,FragmentManager提供了一個相似於findViewById()的方法,專門用於從佈局文件中獲取碎片的實例。
RightFragment rightFragment = (RightFragment) getFragmentManager().findFragmentById(R.id.right_fragment);
4.Android中一些常見的限定符:
大小: small ---提供給小屏幕設備的資源
normal ---提供給中等屏幕設備的資源
large ---提供給大屏幕設備的資源
xlarge ---提供給超大屏幕設備的資源
分辨率: ldpi ---提供給低分辨率設備的資源(120dpi如下)
mdpi ---提供給中等分辨率設備的資源(120dpi到160dpi)
hdpi ---提供給高分辨率設備的資源(160dpi到240dpi)
xhdpi ---提供給超高分辨率設備的資源(240dpi到320dpi)
方向: land ---提供給橫屏設備的資源
port ---提供給豎屏設備的資源
5.最小寬度限定符容許咱們對屏幕的寬度指定一個最小指(以dp爲單位),而後以這個最小值爲臨界值,屏幕寬度大於這個值的設備就加載一個佈局,屏幕寬度小於這個值的設備就加載另外一個佈局。
如layout-sw600dp文件夾中的佈局,當屏幕運行在屏幕寬度大於600dp的設備上時,會加載layout-sw600dp中的佈局,當程序運行在屏幕寬度小於600dp的設備上時,則仍然加載默認的layout中的佈局。
最小寬度限定符是在Android3.2版本引入的。
6.TextView的屬性
android:singleLine設置爲true表示讓這個TextView只能單行顯示。
android:ellipsize用於設定文本內容超出控件寬度時,文本的縮略方式,設置爲"end"表示在尾部進行縮略。
7.ImageView的屬性
android:scaleType屬性設置爲fitXY,表示讓這張圖片填充滿整個控件的大小。git
1.Android中的廣播主要能夠分爲兩種類型,標準廣播和有序廣播。
標準廣播(Normal broadcasts)是一種徹底異步執行的廣播,在廣播發出以後,全部的廣播接收器幾乎都會在同一時刻接收到這條廣播消息,所以它們之間沒有任何前後順序可言。這種廣播的效率會比較高,單同事也意味着它是沒法被截斷的。
有序廣播(Ordered broadcasts)則是一種同步執行的廣播,在廣播發出以後,同一時刻只會有一個廣播接收器可以收到這條廣播消息,當這個廣播接收器中的邏輯執行完畢後,廣播纔會繼續傳遞。因此此時的廣播接收器是有前後順序的,優先級高的廣播接收器就能夠先收到廣播消息,而且前面的廣播接收器還能夠截斷正在傳遞的廣播,這樣後面的廣播接收器就餓沒法收到廣播消息了。
2.註冊廣播的方式通常有兩種,在代碼中註冊和在AndroidManifest.xml中註冊,其中前者也被稱爲動態註冊,厚澤也被稱爲靜態註冊。
3.當網絡狀態發生變化時,系統發出的正是一條值爲android.net,.conn.CONNECTIVITY_CHANGE的廣播,監聽須要權限<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>。
4.訪問http://developer.android.com/reference/android/Manifext.permission.html能夠查看Android系統全部可聲明的權限。
5.Android系統啓動完成後會發出一條值爲android.intent.action.BOOT_COMPLETED的廣播,監聽須要權限<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>。
6.不要在onReceive()方法中添加過多的邏輯或者進行任何的耗時操做,由於在廣播接收器中是不容許開啓線程的,當onReceive()方法運行了較長時間而沒有結束時,程序就會出錯。
7.廣播是一種能夠跨進程的通訊方式。
8.發送有序廣播:
sendOrderedBroadcast(intent,null);
接受廣播AndroidManifest.xml:<intent-filter android:priority="100">
onReceive(){... abortBroadcast();//截斷這條廣播}
9.本地廣播機制,使用這個機制發出的廣播只可以在應用程序的內部進行傳遞,而且廣播接收器只能接收來自本應用程序發出的廣播。
本地廣播主要就是使用了一個LocalBroadcastManager來對廣播繼續寧管理,並提供了發送廣播和註冊廣播接收器的方法。
private LocalBroadcastManager localBroadcastManager;
localBroadcastManager = LocalBroadcastManager.getInstance(this);//獲取實例
localBroadcastManager.sendBroadcast(intent);//發送本地廣播
localBroadcastManager.registerReceiver(localReceiver, intentFilter);//註冊本地廣播監聽器
本地廣播是沒法經過靜態註冊的方式來接受的。其實這也是徹底能夠理解,由於靜態註冊主要就是爲了讓程序在未啓動的狀況下也能收到廣播,而發送本地廣播時,咱們的程序是已經啓動了,所以也徹底不須要使用靜態註冊的功能。
本地廣播的幾點優點:
(1)能夠明確地知道正在發送的廣播不會離開咱們的程序,所以不須要擔憂機密數據泄露的問題。
(2)其餘的程序沒法將廣播發送到咱們程序的內部,所以不須要貪心會有安全漏洞的隱患。
(3)發送本地廣播比起發送系統全局廣播將會更高效。
10.在廣播接收器裏啓動活動,所以必定要給Intent加入FLAG_ACTIVITY_NEW_TASK這個標誌。須要把對話框的類型設爲TYPE_SYSTEM_ALERT,這樣對話框在廣播接收器裏能夠彈出。
11.彈出系統級別的對話框,必需要聲明android.permission.SYSTEM_ALERT_WINDOW權限。數據庫
1.瞬時數據指那些存儲在內存當中,有可能會由於程序關閉或其餘緣由致使內存被回收而丟失的數據,好比登陸界面的帳號和密碼。
2.數據持久化就是指將那些內存中的瞬時數據保存到存儲設備中,保證即便在手機或電話關閉的狀況下,這些數據仍然不會丟失。保存在內存中的數據是處於瞬時狀態的,而保存在存儲設備中的數據是處於持久狀態的,持久化技術則是提供一種機制可讓數據在瞬時狀態和持久狀態之間進行轉換。
Android系統中主要提供了三種方式用於簡單地實現數據持久化功能,即文件存儲、SharedPreference存儲以及數據庫存儲。除了這三種方式以外,還能夠將數據保存在手機的SD卡中,不過使用文件、SharedPreference或數據庫來保存數據會相對更簡單一些,並且比起將數據保存在SD卡中會更加的安全。
3.文件存儲是Android中最基本的一種數據存儲方式,它不對存儲的內容進行任何的格式化處理,全部數據都是原封不動地保存到文件當中的,於是它比較適合用於存儲一些簡單的文本數據或二進制數據。若是你想使用文件存儲的方式來保存一些較爲複雜的文本數據,就須要定義一套本身的格式規範,這樣方便於以後將數據從文件中從新解析出來。
Context類中提供了一個openFileOutput()方法,能夠用於將數據存儲到指定的文件中。這個方法接收兩個參數,第一個參數是文件名,在文件建立的時候使用的就是這個名稱,注意這裏指定的文件名不能夠包含路徑,由於全部的文件都默認存儲到/data/data/<packagename>/files/目錄下的。第二個參數是文件的操做模式,主要有兩種模式可選,MODE_PRIVATE和MODE_APPEND。其中MODE_PRIVATE是默認的操做模式,表示當指定一樣文件名的手,所寫的內容將會覆蓋原文件中的內容,而MODE_APPEND則表示若是該文件已存在就往文件裏面追加內容,不存在就建立新文件。其實文件的操做模式原本還有另外兩種,MODE_WORLD_READABLE和MODE_WORLD_WRITEABLE,這兩種模式表示容許其餘的應用程序對咱們程序中的文件進行讀寫操做,不過因爲這兩種模式過於危險,很容易引發應用的安全性漏洞,現已在Android 4.2版本中被廢棄。
openFileOutput()方法返回的是一個FileOutputStream對象,獲得了這個對象以後就可使用Java六的方式將數據寫入到文件中了。
相似於將數據存儲到文件中,Context類中還提供了一個openFileInput()方法,用於從文件中讀取數據。這個方法要比openFileOutput()簡單一些,它只接收一個參數,即要讀取的文件名,而後系統會自動到/data/data/<package name>/files/目錄下去加載這個文件,並返回一個FileInputStream對象,獲得了這個對象以後再經過java流的方式就能夠將數據讀取出來了。
對字符串進行非空判斷的實收使用了TextUtils.isEmpty()方法,這是一個很是好用的方法,它能夠一次性進行兩種空值的判斷。當傳入的字符串等於null或者等於空字符串的時候,這個方法都會返回true,從而使得咱們不須要單獨去判斷這兩種空值,再使用邏輯運算符鏈接起來。
4.SharedPreferences是使用鍵值對的方式來存儲數據的。也就是說當保存一條數據的時候,須要給這條數據提供一個對應的鍵,這樣在讀取數據的時候就能夠經過這個鍵把相應的值取出來。並且SharedPreferences還支持多種不一樣的數據類型存儲。
Android中主要提供了三種方式用於獲得SharedPreferences對象。
(1)Context類中的getSharedPreferences()方法
此方法接收兩個參數,第一個參數用於指定SharedPreferences文件的名稱,若是指定的文件不存在則會建立一個,SharedPreferences文件都是存放在/data/data/<package name>/shared_prefs/目錄下的。第二個參數用於指定操做模式,主要有兩種模式能夠選擇。MODE_PRIVATE和MODE_MULIT_PROCESS。MODE_PRIVATE仍然是默認的操做模式。和直接傳入0的效果是相同的,表示只有當前的應用程序才能夠對這個SharedPreferences文件進行讀寫。MODE_MULIT_PROCESS則通常是用於會有多個進程中。
(2)Activity類中的getPreferences()方法
這個方法和Context中的getSharedPreferences()方法很類似,不過它只接收一個操做模式參數,由於使用這個方法時會自動將當前活動的類名做爲SharedPreferences的文件名。
(3)PreferenceManager類中的getDefaultSharedPreferences()方法
這是一個靜態方法,它接收一個Context參數,並自動使用當前應用程序的包名做爲前綴來命名SharedPreferences文件。
獲得了SharedPreferences對象以後,就能夠開始向SharedPreferences文件中存儲數據了,主要能夠分爲三步實現:
(1)調用SharedPreferences隨想的edit()方法來獲取一個SharedPreferences.Editor對象。
(2)向SharedPreferences.Editor對象中添加數據,好比添加布爾型數據就是用putBoolean方法,
(3)調用commit()方法將添加的數據提交,從而完成數據存儲操做。
SharedPreferences對象中提供了一系列的get方法用於對存儲的數據進行讀取,每種get方法都對應了SharedPreferences.Editor中的一種put方法,好比讀取一個布爾型數據就是用getBoolean()方法。這些get方法都接收兩個參數,第一個參數是鍵,傳入存儲數據時是用的鍵就能夠獲得相應的值了,第二個參數是默認值,即表示傳入的鍵找不到對應的值時,會以什麼樣的默認值進行返回。
5.SQLite是一款輕量級的關係型數據庫,它的運算速度很是快,佔用資源不多,一般只須要幾百K的內存就足夠了,於是特別適合在移動設備上使用。
SQLite不只支持標準的SQL語法,還遵循了數據庫的ACID事務。
SQLite比通常的數據庫要簡單得多,它甚至不用設置用戶名和密碼就可使用。
Android爲了讓咱們可以更加方便地管理數據庫,專門提供了一個SQLiteOpenHelper幫助類,藉助這個類就能夠很是簡單地對數據庫進行建立和升級。
SQLiteOpenHelper是一個抽象類,這意味着若是咱們想要使用它的話,就須要建立一個本身的幫助類去繼承它。
SQLiteOpenHelper中有兩個抽象方法,分別是onCreate()和onUpgrade(),必須在本身的幫助類裏面重寫這兩個方法,而後分別在這兩個方法中去實現建立、升級數據庫的邏輯。
SQLiteOpenHelper中海油兩個很是重要的實例方法,getReadableDatabase()和getWritableDatabase()。這兩個方法均可以建立或打開一個現有的數據庫(若是數據庫已存在則直接打開,不然建立一個新的數據庫),並返回一個可對數據庫進行讀寫操做的對象。不一樣的是,當數據庫不可寫入的時候(如磁盤空間已滿)getReadableDatabase()方法返回的對象將以只讀的方式去打開數據庫,而getWriteableDatabase()方法則將出現異常。
SQLiteOpenHelper中有兩個構造方法可供重寫,通常使用參數少一點的那個構造方法便可。這個構造方法中接受四個參數,第一個參數是Context,必需要有它才能對數據庫進行操做。第二個參數是數據庫名,建立數據庫時使用的就是這裏指定的名稱。第三個參數容許我麼在查詢數據的時候返回一個自定義的Cursor,通常都是傳入null。第三個參數表示當前數據庫的版本號,可用於對數據庫進行升級操做。構建出SQLiteOpenHelper的實例以後,再調用它的getReadableDatabase()或getWritableDatabase()方法就可以建立數據庫了,數據庫文件會存放在/data/data/<package name>/databases/目錄下。此時,重寫的onCreate()方法也會獲得執行,因此一般會在這裏處理一些建立表的邏輯。
SQLiteDatabase中提供了一個insert()方法,這個方法就是專門用於添加數據的。它接收三個參數,第一個參數是表名,咱們但願向哪張表裏添加數據,這裏就傳入該表的名字。第二個參數用於在未指定添加數據的狀況下給某些可爲空的列自動賦值NULL,通常咱們用不到這個功能,直接傳入null便可。第三個參數是一個ContentValues對象,它提供了一系列的put()方法重載,用於向ContentValues中添加數據,只須要將表中的每一個列名以及相應的待添加數據傳入便可。
SQLiteDatabase中也是提供了一個很是好用的uodate()方法用於對數據進行更新,這個方法接收四個參數,第一個參數和insert()方法同樣,也是表名,在這裏指定去更新哪張表裏的數據。第二個參數是ContentValues對象,要把更新數據在這裏組裝進去。第三第四個參數用於約束更新某一行或某幾行中的數據,不指定的話默認就是更新全部行。
SQLiteDatabase中提供了一個delete()方法專門用於刪除數據,這個方法接收三個參數,第一個參數仍然是表名,第2、三個參數又是用於去約束刪除某一行或某幾行的數據,不指定的話默認就是刪除全部行。
SQLiteDatabase中提供了一個query()方法用於對數據進行查新。這個方法的參數很是複雜,最短的一個方法重載也須要傳入七個參數。第一個參數是表名,表示咱們但願從哪張表中查詢數據。第二個參數用於指定去哪查詢哪幾列,若是不指定則默認查詢全部列。第3、第四個參數用於約束查詢某一行或某幾行的數據,不指定則默認是查詢全部行的數據。第五個參數用於指定須要去group by的列,不指定則表示不會查詢結果進行group bu操做。第六個參數用於對group by以後的數據進行進一步的過濾,不指定則表示不進行過濾。第七個參數用於指定查詢結果的排序方法,不指定則表示使用默認的排序方式。
query()方法參數 對應SQL部分 描述
table from table_name 指定查詢的表名
columns select column1,column2 指定查詢的列明
selection where column = value 指定where的約束條件
selectionArgs - 爲where中的佔位符提供具體的值
groupBy group by column 指定須要group by的列
having having column = value 爲group by 後的結果進一步約束
orderBy order by column1,column2 指定查詢結果的排序方式
調用query()方法後會返回一個Cursor對象,查詢到的全部數據都將從這個對象中取出。
除了查詢數據的時候調用的是SQLiteDatabase的rawQuery()方法,其餘的操做都是調用的execSQL()方法。
SQLite數據庫是支持事務的,事務的特性能夠保證讓某一系列的操做要麼所有完成,要麼一個都不會完成。
Android中事務的標準用法,首先調用SQLiteDatabase的beginTransaction()方法來開啓一個事務,而後在一個異常捕獲的代碼塊中去執行具體的數據庫操做,當全部的操做都完成以後,調用setTransactionSuccessful()表示事務已經執行成功了,最後在finally代碼塊中調用endTransaction()來結束事務。json
1.使用臼齒化技術所保存的數據都只能在當前程序中訪問。
2.內容提供器(Content Provider)主要用於在不一樣的應用程序之間實現數據共享的功能,它提供了一套完整的機制,容許一個程序訪問另外一個程序中的數據,同時還能保證被訪數據的安全性。目前,使用內容提供器是Android實現跨程序共享數據的標準方式。
不一樣於文件存儲和SharedPreferences存儲中的兩種全局可讀寫操做模式,內容提供器能夠選擇只對哪一部分數據進行共享,從而保證咱們程序中的隱私數據不會有泄漏的風險。
內容提供器的用法通常有兩種,一種是使用現有的內容提供器來讀取和操做相應程序中的數據,另外一種是建立本身的內容提供器給咱們程序的數據提供外部訪問接口。
3.當一個應用程序經過內容提供器對其數據提供了外部訪問接口,任何其餘的應用程序就均可以對這部分數據進行訪問。Android系統中自帶的電話簿、短信、媒體庫等程序都提供了相似的訪問接口,這就使得第三方應用程序能夠充分地利用這部分數據來實現更好的功能。
對於每個應用程序來講,若是想要訪問內容提供器中共享的數據,就必定要藉助ContentResolve類,能夠經過Context中的getContentResolver()方法獲取到該類的實例。ContentResolver中提供了一系列的方法用於對數據進行CRUD操做,其中insert()方法用於添加數據,update()方法用於更新數據,delete()方法用於刪除數據,query()方法用於查詢數據。
不一樣於SQLiteDatabase,ContentResolver中的增刪改查方法都是不接收表名參數的,而是使用一個Uri參數代替,這個參數被稱爲內容URI。內容URI給內容提供器中的數據創建了惟一標識符,它主要由兩部分組成,權限(authority)和路徑(path)。權限是用於對不一樣的應用程序作區分的,通常爲了不衝突,都會採用程序包名的方式來進行命名。路徑則是用於對同一應用程序中不一樣的表作區分的,一般都會添加到權限的後面。
調用Uri.parse()方法,就能夠將內容URL字符串解析成Uri對象了。
可使用Uri對象來查詢table表中的數據,代碼以下所示:
Cursor cursor = getContentResolver().query(
uri,
projection,
selection,
selectionArgs,
sortOrder
)
query()方法參數 對應SQL部分 描述
uri from table_name 指定查詢某個應用程序下的某一張表
projection select column1,column2 指定查詢的列名
selection where column = value 指定where的約束條件
selectionArgs - 爲where中的佔位符提供具體的值
orderBy order by column1,column2 指定查詢結果的排序方式
查詢完成後返回的仍然是一個Cursor對象,這時咱們就能夠將數據從Cursor對象中逐個讀取出來了。讀物的思路仍然是經過移動遊標的位置來遍歷Cursor的全部行,而後再取出每一行中相應列的數據。
4.建立本身的內容提供器須要繼承ContentProvider,ContentProvider類中有六個抽象方法。
(1)onCreate()
初始化內容提供器的時候調用。一般會在這裏完成對數據庫的建立和升級等操做,返回true表示內容提供器初始化成功,返回false則表示失敗。注意,只有當存在ContentResolver嘗試訪問咱們程序中的數據時,內容提供器纔會被初始化。
(2)query()
從內容提供器中查詢數據。使用uri參數來肯定查詢哪張表,projection參數用於肯定查詢哪些列,selection和selectionArgs參數用於約束查詢哪些行,sortOrder參數用於對結果進行排序,查詢的結果存放在Cursor對象中返回。
(3)insert()
更新內容提供器中添加一條數據。使用uri參數來肯定要添加到的表,待添加的數據保存在values參數中,selection和selectionArgs參數用於約束更新哪些行,瘦影響的行數將做爲返回值返回。
(4)update()
更新內容提供器中已有的數據。使用uri參數來肯定更新哪一張表中的數據,新數據保存在values參數中,selection和selectionArgs參數用於約束更新哪些行,受影響的行數將做爲返回值返回。
(5)delete()
從內容提供器中刪除數據。使用uri參數來肯定刪除哪一張表中的數據,selection和selectionArgs參數用於約束刪除哪些行,被刪除的行數將做爲返回值返回。
(6)getType()
根據傳入的內容URI來返回相應的MIME類型。
5.一個標準的內容URI寫法是這樣的:
content://com.example.app.provider/table1
這就表示調用方指望訪問的是com.example.app這個應用的table1表中的數據。除此以外,咱們還能夠在這跟人URI的後面加上一個id,以下所示:
content://com.example.app.provider/table1/1
內容URI的格式主要就只有以上兩種,以路徑結尾就表示指望訪問該表中全部的數據,以id結尾就表示指望訪問該表中擁有相應id的數據。咱們可使用通配符的方式來分別匹配這兩種格式的內容URI,規則以下:
(1)*:表示匹配任意長度的任意字符
(2)#:表示匹配任意長度的數據
因此:一個可以匹配任意表的內容URI格式就能夠寫成:content://com.example.app.provider/*
而一個可以匹配table1表中任意一行數據的內容URI格式就能夠寫成:content://com.example.app.provider/table1/#
咱們再借助UriMatcher這個類就能夠輕鬆地實現匹配內容URI的功能。UriMatcher中提供了一個addURI()方法,這個方法接收三個參數,能夠分別把權限、路徑和一個自定義代碼傳進去。這樣,當調用UriMatcher的match()方法時,就能夠將一個Uri對象傳入,返回值是某個可以匹配這個Uri隨想所對應的自定義代碼,利用這個代碼,咱們 就能夠判斷出調用方指望訪問的是哪張表中的數據了。
6.一個內容URI所對應的MIME字符串主要由三部分組成,Android對這三個部分作了以下格式規格:
(1)必須以vnd開頭。
(2)若是內容URI以路徑結尾,則後接android.cursor:dir/,若是內容URI以id結尾,則後接android.cursor.item/。
(3)最後接上vnd.<authority>.<path>。
因此,對於content://com.example.app.provider/table1這個內容URL,它所對應的MIME類型就能夠寫成:vnd.android.cursor.dir/vnd.com.example.app.provider.table1
對於content://com.example.app.provider/table1/1這個內容URI,它所對應的MIME類型就能夠寫成:vnd.android.cursor.item/vnd.com.example.app.provider.table1
7.Git提供了一種可配性很強的機制來容許用戶將指定的文件或目錄排除在版本控制以外,它會檢查代碼倉庫的根目錄下是否存在一個名爲.gitignore的文件,若是存在的話就去一行行讀取這個文件中的內容,並把每一行指定的文件或目錄排除在版本控制以外。注意.gitignore中指定的文件或目錄是可使用「*」通配符的。
查看文件修改狀況使用status命令。
git diff 能夠查看到全部文件的更改內容。
想要撤銷修改可使用checkout命令。這種撤銷方式只適用於那些尚未執行過add命令的文件。執行過add命令的文件取消添加使用的是reset命令(get reaset HEAD <fileName>)。
使用git log命令查看歷史提交信息。
使用git log commit-id 查看其中一條記錄,加-1參數表示咱們只想看到一行記錄,加-p參數,查看這條提交記錄具體修改了什麼內容。api
1.通知(Notification)是Android系統中比較有特點的一個功能,當某個應用程序但願向用戶發出一些提示信息,而該應用程序又不在前臺運行時,就能夠藉助通知來實現。發出一條通知後,手機最上方的狀態欄中會顯示一個通知的圖標,下拉狀態欄後能夠看到通知的詳細內容。
2.建立通知的詳細步驟:首先須要一個NotificationManager來對通知進行管理,能夠調用Context的getSystemService()方法獲取到。getSystemService()方法接收一個字符串參數用於肯定獲取系統的哪一個服務,這裏咱們傳入Context.NOTIFICATION_SERVICE便可。所以,獲取NotificationManager的實例就能夠寫成:
NotificationManager manager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
接下來須要建立一個Notification對象,這個對象用於存儲通知所需的各類信息,咱們可使用它的有參構造函數來進行建立。Notification的有參構造函數接收三個參數,第一個參數用於指定通知的圖標,第二個參數用於指定通知的ticker內容,當通知剛被建立的時候,它會在系統的狀態欄一閃而過,屬於一種瞬時的提示信息。第三個參數用於指定通知被建立的時間,以毫秒爲單位,當下拉系統狀態欄時,這裏指定的時間會顯示在相應的通知上。所以,建立一個Notification對象就能夠寫成:
Notification notification = new Notification(R.drawable.icon,"This is ticker text",System.currentTimeMillis());(已經不推薦使用,可使用Builder)
建立好了Notification對象後,咱們還須要對通知的佈局進行設定,這裏只須要調用Notification的setLatestEvenInfo()方法就能夠給通知設置一個標準的佈局。這個方法接收四個參數,第一個參數是Context,第二個參數用於指定通知的標題內容,下拉系統狀態欄就能夠看到這部份內容。第三個參數用於指定通知的正文內容,一樣下拉系統狀態欄就能夠看到這部份內容。第四個參數暫時用不到,能夠先傳入null。所以,對通知的佈局進行設定就能夠寫成:
notification.setLatestEventInfo(context, "This is content title", "This is content text", null);(已經不推薦使用,可使用Builder)
以上工做完成以後,只須要調用NotificationManager的notify()方法就可讓通知顯示出來了。notify()方法接收兩個參數,第一個參數是id,要保證爲每一個通知所指定的id都是不一樣的。第二個參數則是Notification對象,這裏直接將咱們剛剛建立好的Notification對象傳入便可。所以,顯示一個通知就能夠寫成:
manager.notify(1, notification);
3.PendingIntent從名字上看起來就和Intent有些相似,它們之間也確實存在着很多共同點。好比它們均可以去指明某一個「意圖」,均可以用於啓動活動、啓動服務以及發送廣播等。不一樣的是,Intent更加傾向於去當即執行某個動做,而PendgingIntent更加傾向於在某個合適的時機去執行某個動做。因此,也能夠吧PendingIntent簡單地理解爲延遲執行的Intent。
PendingIntent的用法很簡單,它主要提供了幾個靜態方法用於獲取PendingIntent的實例,能夠根據需求來選擇是使用getActivity()方法、getBroadcast()方法、仍是getService()方法。這幾個方法所接收的參數都是相同的。第一個參數是Context,第二個參數通常用不到,同創都是傳入0便可。第三個參數是一個Intent獨享,能夠經過這個對象構建出PendingIntent的「意圖」。第四個參數用於肯定PendingIntent的行爲,有FLAG_ONE_SHOT、FLAG_NO_CREATE、FLAG_CANCEL_CURRENT和FLAG_UPDATE_CURRENT這四種值可選。
4.接收短信的權限:android.permission.RECEIVE_SMS
接收短信的廣播的action:android.provider.Telephony.SMS_RECEIVED
發送短信的權限:android.permission.SEND_SMS
5.啓動相機的intent:Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
裁剪程序的intent:Intent intent = new Intent("com.android.camera.action.CROP");
向SD卡中寫數據須要聲明的權限:android.permission.WRITE_EXTERNAL_STORAGE
打開相冊獲取圖片的intent:Intent intent = new Intent("android.intent.action.GET_CONTENT");
intent.setType("image/*");
intent.putExtra("crop",true);//是否容許裁剪
intent.putExtra("scale",true);//是否容許縮放
intent.putExtra(MediaStore.EXTRA_OUTPUT,image);//圖片的輸出位置
6.在Android中播放音頻文件通常都是使用MediaPlayer來來實現的,它對多種格式的音頻文件提供了很是全面的控制方法,從而使得播放音樂的工做變得很是簡單。
MediaPlayer類中一些較爲經常使用的控制方法:
方法名 功能描述
setDataSource() 設置要播放的音頻文件的位置。
prepare() 在開始播放以前調用這個方法完成準備工做。
start() 開始或繼續播放音頻。
pause() 暫停播放音頻。
reset() 將MediaPlayer對象重置到剛剛建立的狀態。
seekTo() 從指定的位置開始播放音頻。
stop() 中止播放音頻。調用這個方法後的MediaPlayer對象沒法再播放音頻。
release() 釋放掉與MediaPlayer對象相關的資源。
isPlaying() 判斷當前MediaPlayer是否正在播放音頻。
getDuration() 獲取載入的音頻文件的時長。
MediaPlayer的工做流程:首先須要建立出一個MediaPlayer對象,而後調用setDataSource()方法來設置音頻文件的路徑,再調用prepare()方法使MediaPlayer進入到準備狀態,接下來調用start()方法就能夠開始播放音頻,調用pause()方法就會暫停播放,調用reset()方法就會中止播放。
7.播放視頻文件主要是使用VideoView類來實現的。這個類將視頻的顯示和控制集於一身,使得咱們僅僅藉助它就能夠完成一個簡易的視頻播放器。
VideoView的經常使用方法:
方法名 功能描述
setVideoPath() 設置要播放的視頻文件的位置 。
start() 開始或繼續播放視頻。
pause() 暫停播放視頻。
resume() 將視頻重頭開始播放。
seekTo() 從指定的位置開始播放視頻。
isPlaying() 判斷當前時候正在播放視頻。
getDuration() 獲取載入的視頻文件的時長。
VideoView並非一個萬能的視頻播放工具類。它在視頻格式的支持以及播放效率方面都存在着較大的不足。因此,若是想要僅僅使用VideoView就編寫一個功能很是強大的視頻播放器是不太現實的。可是若是隻是用於播放一些遊戲的片頭訂花,或者某個應用的視頻宣傳,使用VideoView仍是綽綽有餘的。數組
1.服務(Service)是Android中實現程序後臺運行的解決方案,它很是適合用於去執行那些不須要和用戶交互並且還要求長期運行的任務。服務的運行以依賴於任何用戶界面,即便當程序被切換到後臺,或者用戶打開了另一個應用程序,服務仍然可以保持正常運行。
不過須要注意的是,服務並非運行在一個獨立的進程當中的,而是依賴於建立服務時所在的應用程序進程。當某個應用程序進程被殺掉時,全部依賴於該進程的服務也會中止運行。
另外,也不要被服務的後臺概念所迷惑,實際上服務並不會自動開啓線程,全部的代碼都是默認運行在主線程當中的。也就是說,咱們須要在服務的內部手動建立子線程,並在這裏執行具體的任務,不然就有可能出現主線程被組塞住的狀況。
2.Android中的異步消息處理主要由四個部分組成,Message、Handler、MessageQueue和Looper。
(1)Message
Message是在線程之間傳遞的消息,它能夠在內部攜帶少許的信息,用於在不一樣線程之間交換數據。
(2)Handler
Hnadler顧名思義也就是處理者的意思,它主要是用於發送和處理消息的。發送消息通常都是使用Handler的sendMessage()方法,而發出的消息通過一系列地展轉處理後,最終會傳遞到Handler的handleMessage()方法中。
(3)MessageQueue
MessageQueue是消息隊列的意思,呀主要用於存放全部經過Handler發送的消息。這部分消息會一直存在於消息隊列中,等待被處理。每一個線程中只會有一個MessageQueue對象。
(4)Looper
Looper是每一個線程中的MessageQueue的管家,調用Looper的loop()方法後,就會進入到一個無限循環當中,而後每當發現MessageQueue中存在一條消息,就會將它取出,並傳遞到Handler的handleMessage()方法中。每一個線程中也只會有一個Looper對象。
3.異步消息處理的整個流程:首先須要在主線程當中建立一個Handler對象,並重寫handleMessage()方法。而後當子線程中須要進行UI操做時,就建立一個Message對象,並經過Handler將這條消息發送出去。以後這條消息會被添加到MessageQueue的隊列中等待被處理,而Looper則會一直嘗試從MessageQueue中取出待處理消息,最後分發回Handler的handleMessage()方法中。因爲Handler是在主線程中建立的。因此此時handleMessage()方法中的代碼也會在主線程中運行,因而咱們在這裏就能夠安心地進行UI操做了。
4.AsyncTask背後的實現原理也是基於異步消息處理機制的。
AsyncTask是一個抽象類,若是想要使用它沒救必須建立一個子類去繼承它。在繼承時咱們能夠爲AsyncTask類指定三個泛型參數,這三個參數的用途以下:
(1)Params
在執行AsyncTask時須要傳入的參數,可用於在後臺任務中使用。
(2)Progress
後臺任務執行時,若是須要在界面上顯示當前的速度,則使用這裏指定的泛型做爲進度單位。
(3)Result
當任務執行完畢後,若是須要對結果進行返回,則使用這裏指定的泛型做爲返回值類型。
AsyncTask須要常常重寫的方法:
(1)onPreExecute()
這個方法會在後臺任務開始執行以前調用,用於進行一些界面上的初始化操做,必須顯示一個進度條對話框等。
(2)doInBackfround(Params...)
這個方法中的全部代碼都會在子線程中運行,咱們應該在這裏去處理全部的耗時任務。任務一旦完成就能夠經過return語句來將任務的執行結果返回,若是AsyncTask的第三個泛型參數指定的是Void,就能夠不返回任務執行結果。注意,在這個方法中是不能夠進行UI操做的,若是須要更新UI元素,若是須要更新UI元素,好比說反饋當前任務的執行進度,能夠調用publishProgress(Progress...)
(3)onProgressUpdate(Progress...)
當在後臺任務中調用了publishProgress(Progress...)方法後,這個方法就會很快被調用,方法中攜帶的參數就是在後臺任務中傳遞過來的。在這個方法中能夠對UI進行操做,利用參數中的數值就能夠對界面元素進行相應地更新。
(4)onPostExecute(Result)
當後臺任務執行完畢並經過return語句進行返回時,這個方法就很快會被調用。返回的數據會做爲參數傳遞到此方法中,能夠利用返回的數據進行一些UI操做。
使用AsyncTask的訣竅是,在doInBackground()方法中去執行具體的耗時任務,在onProgressUpdate()方法中進行UI操做,在onPostExecute()方法中執行一些任務的收尾工做。安全
5.服務的經常使用到的單個方法,其中onCreate()方法會在服務建立的時候調用,onStartCommand()方法會在每次服務啓動的時候調用,onDestory()方法會在服務銷燬的時候調用。
6.一旦在項目的任何位置調用了Context的startService()方法,相應的服務就會啓動起來,並回調onStartCommand()方法。若是這個服務以前尚未建立過,onCreate()方法會先於onStartCommand()方法執行。服務啓動了以後會一直保持運行狀態,直到stopService()或stopService()方法被調用。注意雖然每調用一次startService()方法,onStartCommand()就會執行一次,實際上每一個服務都只會存在一個實例。因此無論你調用多少次startService()方法,只需調用一次stopService()或stopSelf()方法,服務就會中止下來了。
還能夠調用Context的bindService()來獲取一次服務的持久鏈接,這時就會回調服務中的onBind()方法。相似地,若是這個服務以前尚未建立過,onCreate()方法會先於onBind()方法執行。以後,調用方能夠獲取到onBind()方法裏返回的IBinder對象的實例,這樣就能自由地和服務進行通訊了。只要調用方和服務之間的鏈接沒有斷開,服務就會一直保持運行狀態。
當調用startService()方法後,又去調用stopService()方法,這時服務中的onDestroy()方法就會執行,表示服務以及銷燬了。相似地,當調用了bindService()方法後,又去調用unbindService()方法,onDestroy()方法也會執行。可是須要注意,咱們是徹底有可能對一個服務即調用了startService()方法,又調用了bindService()方法的,根據Android系統的機制,一個服務只要被啓動或者被綁定了以後,就會一直處於運行狀態,必需要讓以上兩種條件同時不知足,服務才能被銷燬。因此,要同時調用stopService()和unbindService()方法,onDestroy()方法纔會執行。
7.服務幾乎都是在後臺運行的,一直以來它都是默默地作着辛苦的工做。可是服務的系統優先級仍是比較低的,當系統出現內存不足的狀況下,就可能會回收掉正在後臺運行的服務。若是你但願服務能夠一直保持運行狀態,而不會因爲系統內存不足的緣由致使被回收,就能夠考慮使用前臺服務。前臺服務和普通服務最大的區別就在於,它會一直有一個正在運行的圖標在系統的狀態欄顯示,下拉狀態欄後能夠看到更加詳細的信息,很是相似於通知的效果。固然有時候你也可能不只僅是爲了防止服務被回收掉纔是用前臺服務的,有些項目因爲特殊的需求必須使用前臺服務。
8.IntentService類,能夠在onHandleIntent()抽象方法中處理一些具體邏輯,並且不用擔憂ARN的問題,由於這個方法已是在子線程中運行了,任務完成服務會自動中止。
9.Android中的定時任務通常有兩種實現方式,一種是使用Java API裏提供的Timer類,一種是使用Android的Alarm機制。這兩種方式在多數狀況下都能實現相似的效果,但Timer有一個明顯的短板,它並不太適合於那些須要長期在後臺運行的定時任務。咱們知道,爲了能讓電池更加耐用,每種手機都會有本身的休眠策略,Android手機就會在長時間不操做的狀況下自動讓CPU進入到睡眠狀態,這就有可能致使Timer中的定時任務沒法正常運行。而Alarm機制則不存在這種狀況,它具備喚醒CPU的功能,既能夠保證每次須要執行定時任務的時候CPU都能正常工做。須要注意,這裏喚醒CPU和喚醒屏幕徹底不是同一個概念。
10.AlarmManager主要就是藉助了AlarmManager類來實現的,經過調用Context的getSystemService()方法來獲取實例的,須要傳入參數是Context.ALARM_SERVICE。獲取實例就能夠寫成:
AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
接下來調用AlarmManager的set()方法就能夠設置一個定時任務了,好比設置一個任務在10分鐘後執行:
long triggerAtTime = SystemClock.elapsedRealtime() + 10 * 1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggAtTime, pendingIntent);
set()方法的三個參數,第一個參數是一個整型參數,用於指定AlarmManager的工做類型,有四種值可選,分別是ELAPSED_REALTIME、ELAPSED_REALTIME_WAKEUP、RTC和RTC_WAKEUP。其中ELAPSED_REALTIME表示讓定時器表示讓定時任務的出發時間從系統開機開始算起,但不會喚醒CPU。ELAPSED_REALTIME_WAKEUP一樣表示讓定時任務的出發時間從系統開始開始算起,但會喚醒CPU。RTC表示定時任務的觸發時間從1970年1月1日0時開始算起,但不會喚醒CPU。RTC_WAKEUP一樣表示讓定時任務的觸發時間從1970年1月1日0時開始算起,但會喚醒CPU。
使用SystemClock.elapsedRealtiome()方法能夠獲取到系統開機至今所經歷時間的毫秒數,使用System.curretnTimeMillis()方法能夠獲取到1970年1月1日0點至今所經歷時間的毫秒數。
第二個參數就是定時任務觸發的時間,以毫秒爲單位。若是第一個參數使用的是ELAPSED_REALTIME或ELAPSED_REALTIME_WAKEUP,則這裏傳入開機至今在加上延遲執行的時間。若是第一個參數使用的是RTC或RTC_WAKEUP,則這裏傳入1970年1月1日0點至今的時間再加上延遲執行的時間。
第三個參數是一個PendingIntent,這裏咱們通常會調用getBroadcast()方法來獲取一個可以執行廣播的PendingIntent。這樣當定時任務唄出發的時候,廣播接收器的onReceiver()方法就能夠獲得執行。
11.從Android 4.4版本開始,Alarm任務的觸發時間將會變得不許確,有可能會延遲一段時間後任務才能獲得執行。這不是個bug,而是系統在好點性方面進行的優化。系統會自動檢測目前有多敲Alarm任務存在,而後將觸發時間將近的幾個任務放在一塊兒執行,這就能夠大幅度地減小CPU被喚醒的次數,從而有效延長電池的使用時間。
若是你要求Alarm任務的執行時間必須準確無誤,Android仍然提供瞭解決方案。使用AlarmManager的setExact()方法來代替set()方法,就能夠抱枕任務準時執行了。服務器
1.HTTP協議的工做原理就是客戶端向服務器發出一條HTTP請求,,服務器收到請求以後會返回一些數據給客戶端,而後客戶端再對這些數據進行解析和處理就能夠了。
2.在Android上發送HTTP請求的方式通常有兩種,HttpURLConnection和HttpClient。
3.HttpURLConnection的用法:
首先須要獲取到HttpURLConnection的實例,通常只需new出一個URL對象,並傳入目標的網絡地址,而後調用一下openConnection()方法便可,以下所示:
URL url = new URL("http://www.baidu.com");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
獲得了HttpURLConnection的實例以後,咱們能夠設置一下HTTP請求所使用的方法。經常使用的方法主要有兩個,GET和POST。GET表示但願從服務器那裏獲取數據,而POST則表示但願提交數據給服務器。寫法以下:
connection.setRequestMethod("GET");
接下來就能夠進行一些自由地定製了,好比設置鏈接超時,讀取超時的毫秒數,以及服務器但願獲得的一些消息頭等。這部份內容根據本身的實際狀況進行編寫,示例寫法以下:
connection.setConnectionTimeout(8000);
connection.setReadTimeout(8000);
以後再調用getInputStream()方法就能夠獲取到服務器返回的輸入流了,剩下的任務就是對輸入流進行讀取,以下所示:
InoutStream in = connection.getInputStream();
最後能夠調用disconnect()方法將這個HTTP鏈接關閉掉,以下所示:
connection.disconnection();
提交數據費服務器,只須要將HTTP請求的方法改爲POST,並在獲取輸入流以前把要提交的數據寫出便可。注意每條數據都要以鍵值對的形式存在,數據與數據之間用&符號隔開,好比說咱們想要向服務器提交用戶名和密碼,就能夠這樣寫:
connection.setRequestMethod("POST");
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.writeBytes("username=admin&password=123456");
4.HttpClient是Apache提供的HTTP網絡訪問接口,從一開始的時候就被引入到了Android API中。它能夠完成和HttpURLcONNECTION幾乎如出一轍的效果,但二者之間的用法卻又較大的差異。
5.HttpClient的用法:
首先你須要知道,HttpClient是一個接口,所以沒法建立它的實例,一般狀況下都會建立一個DefaultHttpClient的實例,以下所示:
HttpClient httpClient = new DefaultHttpClient();
接下來若是想要發起一條GET請求,就能夠建立一個HttpGet對象,並傳入目標的網絡地址,而後調用HttpClient的execute()方法便可。
HttpGet httpGet = new HttpGet("http://www.baidu.com");
httpClient.execute(httpGet);
若是是發起一條POSY請求會比GET稍微複雜一點,咱們須要建立一個HttpPost對象,並傳入目標的網絡地址,以下所示:
HttpPost httpPost = new HttpPost("http://www.baidu.com");
而後經過一個NameValuePair集合來存放待提交的參數,並將這個參數集合傳入到一個UrlEncodedFormEntity中,而後調用HttpPost的setEntity()方法將構建好的UrlEncodeFormEntity傳入,以下所示:
List<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("username","admin"));
params.add(new BasicNameValuePair("password","123456"));
UrlEncodedFromEntity entity = new UrlEncodedFormEntity(params, "utf-8");
httpPost.setEntity(entity);
接下來的操做就和HttpGet同樣了,調用HttpClient的execute()方法,並將HttpPost對象傳入便可:
httpClient.execute(httpPost);
執行execute()方法以後會返回一個HttpResponse對象,服務器所返回的全部信息就會包含在這裏面。一般狀況下咱們都會先取出服務器返回的狀態碼,若是等於200就說明請求和響應都成功了,以下所示:
if (httpResponse.getStatusLine().getStatusCode == 200) {
//請求和響應都成功了
}
接下來在這個if判斷的內部取出服務返回的具體內容,能夠調用getEntity()方法獲取到一個HttpEntity實例,而後再用EntityUtils.toString()這個靜態方法將HttpEntity轉換成字符串便可,以下所示:
HttpEntity entity = httpResponse.getEntity();
String response = EntityUtils.toString(entity);
注意若是服務器返回的數據是帶有中文的,直接調用EntityUtils.toString()方法進行轉換會有亂碼的狀況出現,這個時候只須要在轉換的時候講字符集指定成utf-8就能夠了,以下所示:
String response = EntityUtil.toString(entity, "utf-8");
6.比起XML,JSON的主要優點在於它的體積更小,在網絡上傳輸的時候能夠更省流量。單缺點在於,它的與異性較差,看起來不如XML直觀。
1.基於位置的服務簡稱LBS,主要的工做原理就是利用無線電通信網絡或GPS等定位方式來肯定出移動設備所在的位置。
2.基於位置的服務在Android中主要藉助LocationManager這個類實現。
3.要想使用LocationManager就必需要先獲取到它的實例,咱們能夠調用Context的getSystemService()方法獲取到。getSysytemService()方法接收一個字符串參數用於肯定獲取系統的哪一個服務,這裏傳入Context.LOCATION_SERVICE便可。所以,獲取 LocationManager餓實例就能夠寫成:
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
接着咱們須要選擇一個位置提供器來肯定設備當前的位置。Android中通常有三種位置提供器可供選擇,GPS_PROVIDER、NETWORK_PROVIDER和PASSIVE_PROVIDER。其中前兩種使用的比較多,分貝表示勇士GPS定位和使用網絡定位。這兩種定位方式各有特色,GPS定位的精確度比較高,可是很是耗電,而網絡定位的精準度較差,但耗電量比較少、咱們應該根據本身的實際狀況來選擇使用哪種位置提供器,當位置精度要求很是高的時候,最好使用GPS_PROVIDER,二一班狀況下,使用NETWORK_PROVIDER會更加得划算。
須要注意的是,定位功能必要要由用戶主動去啓動才行,否則任何應用程序都沒法獲取到手機當前的位置信息。
將選擇好的位置提供器傳入到getLastKnownLocation()方法中,就能夠獲得一個Location對象,以下所示:
String provider = LocationManager.NETWORK_PROVIDER;
Location location = locationManager.getLastKnownLocation(provider);
這個Location對象中包含了經度、緯度、海拔等一系列的位置信息,而後從中取出咱們所關係的那部分數據便可。
判斷有哪些位置提供器可用,以下所示:
List<String> providerList = locationManager.getProviders(true);
getProviders()方法接收一個布爾值參數,傳入truw就表示只有啓用的位置提供器纔會被返回。以後再從providerList中判斷是否包含GPS定位的功能就好了。
調用getLastKnownLocation()方法雖然能夠獲取到設備當前的位置信息,可是用戶是徹底有可能帶有移動設備隨時移動的,那麼怎樣才能在設備位置發生改變的時候獲取到最新的位置信息呢?LocationManager還提供了一個requestLocationUpdates()方法,只要傳入一個LocationListener的實例,並簡單配置幾個參數就能夠實現上述功能了,寫法以下:
locationManager.requestLocationUpdates(LocationManager.GPS_PRIVIDER, 5000, 10, new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras){}
@Override
public void onProviderEnabled(String provider) {}
@Override
public void onProviderDisabled(String provider) {}
@Override
public void onLocationChanged(Location location) {}
});
這裏requestLocationUpdates()方法接收四個參數,第一個採納數是位置提供器的類型,第二個參數是監聽位置變化的時間間隔,以毫秒爲單位,第三個參數是監聽位置變化的距離間隔,以米爲單位,第四個參數則是LocationListener監聽器。
4.其實Android自己就提供了地理編碼的API,主要是使用GeoCoder這個類來實現的。他能夠很是簡單地完成正向和反向的地理編碼功能,從而輕鬆地將一個經緯值轉換成看得懂的位置信息。
GeoCoder長期存在着一些較爲嚴重的bug,在反向地理編碼的時候會有必定的機率不能解析出位置的信息,這樣就沒法保證位置解析的穩定性。
谷歌又提供了一套Geocoding API,使用它的話也能夠完成反向地理編碼的工做,只不過它的用法稍微複雜了一些,但穩定性要比GeoCoder強得多。
Geocoding API的工做原理並不神祕,其實就是利用HTTP協議。在手機端咱們能夠向谷歌的服務器發起一條HTTP請求,並將經緯度的值做爲參數異同傳遞過去,而後服務端會幫咱們將這個經緯值轉換成看得懂的位置信息,再將這些信息返回給手機端,最後手機端去解析服務器返回的信息,並進行處理就能夠了。
Geocoding API中規定了不少藉口,其中反向地理編碼的接口以下:
http://maps.googleapis.com/maps/api/geocode/json?latlng=40.714224,-73.96145&sensor=true_or_false
其中http://maps.googleapis.com/maps/api/geocode/是固定的,表示接口的鏈接地址。json表示但願服務器可以返回JSON格式的數據,這裏也能夠指定成xml。latlng=40.714224,-73.96145表示傳遞給服務器去解碼的經緯值是北緯40.714224度,西經73.96145度,sensor=true_or_false表示這條請求是否來自於某個設備的位置傳感器,一般指定成false便可。
5.分支是版本控制工具中比較高級且比較重要的一個概念,它主要的做用就是在現有代碼的基礎上開闢一個分叉口,使得代碼能夠在主幹線和分支線上同時進行開發,且相互之間不會影響。
查看當前的版本庫當中有哪些分支,可使用git branch -a 命令.
建立分支命令: git branch 分支名
切換分支命令: git checkout 分支名
合併分支代碼命令:git checkout 分支名(先切換分支) git merge 分支名(合併哪一個分支的代碼)
刪除分支命令: git branch -D 分支名
將本地修改的內容同步到遠程版本庫上:git push origin master,其中origin部分指定的是遠程版本庫的Git地址,master部分指定的是同步哪個分支上。上述命令就完成了將本地代碼同步到版本庫的master分支上的功能。
將遠程版本庫上的修改同步到本地。Git提供了兩種命令來完成此功能,分別是fetch和pull,fetch的語法規則和push是差很少的,以下所示:
git fetch origin master
執行命令後,就會將遠程版本庫上的代碼同步到本地,不過同步下來的代碼並不會合併到任何分支上,而是會存放在一個origin/master分支上,這是咱們能夠經過diff命令來查看遠程版本庫上待敵修改了哪些東西:
git diff origin/master
以後再調用merge命令將origin/master分支上的修改合併到主分支上便可,以下所示:
git merge origin/master
而pull命令則是至關於將fetch和merge這兩個命令放在一塊兒在執行了,它能夠從遠程版本庫上獲取最新的代碼而且合併到本地,用法以下:
git pull origin master
第12章 Android特點開發,使用傳感器
1.手機內置的傳感器是一種微型的物理設備,它呢可以探測、感覺到外界的信號,並按必定規律轉換成咱們所須要的信息。Android手機一般都會支持多種類型的傳感器,如光照傳感器、加速度傳感器、地磁傳感器、壓力傳感器、溫蒂傳感器等。
2.光照傳感器在Android中的應用仍是比較常見的,好比系統就有個自動調整屏幕亮度的功能。它會檢測手機周圍環境的光照強度,而後對手機屏幕的亮度進行相應地調整,一次保證無論在強光仍是弱光下,手機屏幕都可以看得清。
3.Android中每一個傳感器的用法其實都比較相似。首先第一步要獲取到SensorManager的實例,方法以下:
SensorManager sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
SensorManager是系統全部傳感器的管理器,有了它的實例以後就能夠調用getDefaultSensor()方法來獲得任意的傳感器類型了,以下所示:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
這裏使用Sensor.TYPE_LIGHT常量來指定傳感器類型,此時的Sensor實例就表明着一個光照傳感器。
接下來須要對傳感器輸出的信號進行監聽,這就要藉助SensorEventListener來實現了。SensorEventListener是一個接口,其中定義了onSensorChanged()和onAccuracyChanged()這兩個方法。當傳感器的精度發生變化時就會調用onAccuracyChanged()方法,當傳感器監測到的數值發生變化時就會調用onSensorChanged()方法。onSensorChanged()方法中傳入了一個SensorEvent參數,這個參數裏又包含了一個values數組,全部傳感器輸出的信息都是存放在這裏的。
下來還須要調用SensorManager的registerListener()方法來註冊SensorEventListener才能使其生效,registerListener()方法來註冊SensorEventListener才能使其生效,registerListener()方法接收三個參數,第一個參數就是SensorEventListener的實例,第二個參數是Sensor的實例。第三個參數是用於表示傳感器輸出信息的更新速率,共有SENSOR_DELAY_UI、SENSOR_DELAY_NORMAL、SENSOR_DELAY_GAME和SENSOR_DELAY_FASTEST這四個值可選,它們的更新速率是一次遞增的。
始終要記得,當程序退出或傳感器使用完畢時,必定要調用unregisterListener()方法將使用的資源釋放掉。
4.獲取Sensor實例的時候要指定一個加速度傳感器的常量,以下所示:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
加速度傳感器輸出的信息一樣也是存放在SensorEvent的values數組中的,只不過此時的values數組中會有三個值,分別表明手機在X軸、Y軸、Z軸方向上的加速度。
5.獲取到一個用於表示方向傳感器的Sensor實例,以下所示:
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
以後再onSensorChanged()方法中經過SensorEvent的values數組,就能夠獲得傳喚器輸出的全部值了。方向傳感器會記錄手機在全部方向上的旋轉角度。其中,values[0]記錄着手機圍繞Z軸的旋轉角度,values[1]記錄着手機圍繞X軸的旋轉角度,values[2]記錄着手機圍繞Y軸的旋轉角度。
但遺憾的是,Android早就廢棄了Sensor.TYPE_ORIENTATION這種傳感器類型,雖然代碼仍是有效的,但已經再也不推薦這麼寫了。事實上,Android獲取手機旋轉的方向和角度是經過加速度傳感器和地磁傳感器共同計算得出的,這也是Android目前推薦使用的方式。
首先咱們須要分別獲取到加速度傳感器和地磁傳感器的實例,並給它們註冊監聽器,以下所示:
Sensor accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor magneticSensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
sensorManager.registerListener(listener, accelerometerSensor,SensorManager.SENSOR_DELAY_GAME);
sensorManager.registerListener(listener, magneticSensor,SensorManager.SENSOR_DELAY_GAME);
因爲方向傳感器的精確度要求一般都比較高,這裏咱們把傳感器輸出此案次的更新速率提升了一些,使用的是SENSOR_DELAY_GAME。
接下來在onSensorChanged()方法中能夠獲取到SensorEvent的values數組,分別記錄着加速度傳感器和地磁傳感器輸出的值。而後將這兩個值傳入到SensorManager的getRotationMatrix()方法中就能夠獲得一個包含旋轉矩陣的R數組,以下所示:
SensorManager.getRotationMatrix(R, null, acceler0meterValues, magneticValues);
其中第一個參數R是一個長度爲9的float數組,getRotationMatrix()方法計算出的旋轉數組就會賦值到這個數組中。第二個參數是一個用於將地磁向量轉換成重力座標的旋轉矩陣,一般指定爲null便可。第三和第四個參數則分別就是加速度傳感器和地磁傳感器輸出的values值。
獲得了R數組以後,接着就能夠調用SensorManager的getOrientation()方法來計算手機的旋轉數據了,以下所示:
SensorManager.getOrientation(R, values);
values是一個長度爲3的float數組,手機在各個方向上的旋轉數據都會被存放到這個數組當中。其中values[0]記錄着手機圍繞Z軸的旋轉弧度,values[1]記錄着手機圍繞X軸的旋轉弧度,values[2]記錄着手機圍繞Y軸的旋轉弧度。
注意這裏計算出的數據都是以弧度爲單位的,所以若是你想將它們轉換成角度還須要調用以下方法:
Math.toDegrees(values[0]);
1.使用Intent來傳遞對象一般有兩種實現方式,Sericalizable和Paracelable。
Serizable是序列化的意思,表示將一個對象轉換成可存儲或可傳輸的狀態。序列化後的對象能夠在網絡上進行傳輸,也能夠存儲到本地。至於序列化的方法也很簡單,只須要讓一個類趨勢線Serializable這個接口就能夠了。
除了Serializable以外,使用Parcelable也能夠實現相同的效果,不過不一樣於將對象進行序列化,Parcelable方式的實現原理是將一個完整的對象進行分解,而分解後的每一部分都是Intent所支持的數據類型,這樣也就實現傳遞對象的功能了。
Serializable的方式較爲簡單,但因爲會把整個對象進行序列化,所以效率方面會比Parcelable方式低一些,因此在一般狀況下仍是更加推薦使用Parcelable的方式實現Intent傳遞對象的功能。