Intent與BroadcastReceiver
Intent是Android應用內不同組件之間的通訊載體
使用Intent可以激活Android的三個核心組件
Activity
Service
BroadcastReceiver
Intent啟動Activity、Service和BroadcastReceiverd的方法:
啟動Activity:調用startActivity(Intent intent)或 startActivityForResult(Intent intent,int requestCode)方法
啟動Service :調用startService(Intent intent)或bindService(Intentintent,ServiceConnection conn ,int flags)方法
觸發(fā)BroadcastReceiver時,調用sendBroadcast(Intent intent)方法
上述方法中Intent參數(shù)用于封裝當前組件在啟動目標組件時所需的信息,系統(tǒng)通過該信息找到對應的組件,完成組件之間的調用。
顯示Intent:明確指定需要啟動或觸發(fā)組件的類名
隱式Intent:只指定了需要啟動或觸發(fā)的組件應滿足的條件
Intent對象通過屬性來設定相應的啟動目標。
Intent對象包含以下幾種屬性:
Component組件
Action動作
Category類別
Data數(shù)據(jù)
Type數(shù)據(jù)類型
Extras擴展信息
Flags標志位
l ntent屬性:Component組件
Component組件為目標組件,需要接受一個ComponentName對象
ComponentName對象的構造方法有以下幾種方式∶
ComponentName(String pkg,String className)
ComponentName(Context context,String className)
ComponentName(Context context,Class<?> className)
Intent還可以指定待啟動組件的包名和類名∶
setClass(Context ctx,Class<?> cls)
setClassName(Context ctx,String className)
setClassName(String pkg,String className)
創(chuàng)建ComponentName對象
?Intent intent =new Intent () ;
?ComponentName component = new ComponentName (MainActivity.this,secondActivity.class);
?intent.setComponent ( component) ;
?startActivity (intent) ;
?
使用setClass()方法指定待啟動組件
?Intent intent = new Intent () ;
?intent.setClass (MainActivity.this,secondActivity.class);
?startActivity (intent) ;
?
使用Intent()構造方法指定啟動組件
?Intent intent = new Intent(MainActivity.this,SecondActivity.class);startActivity (intent) ;
?
Intent屬性:Action動作
Action是一個字符串,用于描述─個Android應用程序的組件
啟動Activity的系統(tǒng)標準Action
Action常量字符串描述ACTION_SENDandroid.intent.action.SEND啟動一個Activity,該Activity會發(fā)送Intent中指定的數(shù)據(jù)。接收人需要由解析的Activity來選擇。ACTION_SENDTOandroid.intent.action.SENDTO啟動一個Activity來向Intent的數(shù)據(jù)URI所指定的聯(lián)系人發(fā)送一條消息。ACTION_ANSWERandroid.intent.action.ANSWER打開一個處理來電的Activity,通常這個動作是由本地電話撥號程序處理ACTION_INSERTandroid.intent.action.INSERT打開一個子Activity能在Intent的數(shù)據(jù)URI指定的游標處插入新項的Activity。當作為子Activity調用時,應該返回一個指向新插入項的URIACTION_DELETEadnroid.intent.action.DELETE啟動一個Activity,允許刪除Intent的數(shù)據(jù)URI中指定的數(shù)據(jù)ACTION_ALL_AppSandroid.intent.action.ACTION_ALL_AppS打開一個列出所有已安裝應用程序的Activity,通常此操作由啟動器處理ACTION_SEARCHandroid.intent.action.SEARCH通常用于啟動特定的搜索Activity.
Android中針對一些系統(tǒng)級的事件,預先定義了一些標準Action,這此Action對應干Intent類中的常量,其值和意義如下:
ACTION_ BOOT_ _COMPLETED :系統(tǒng)啟動完成廣播
ACTION TIME _CHANGED : 時間改變廣播
ACTION_ DATE_ _CHANGED :日期改變廣播
ACTION_ TIME_ TICK :每分鐘改變一次時間
ACTION_ TIMEZONE_ CHANGED :時區(qū)改變廣播
ACTION_ BATTERY_ _LOW :電量低廣播
ACTION_ PACKAGE_ _ADDED :添加包廣播
ACTION_ PACKAGE_ REMOVED :刪除包廠播
lntent屬性: Category類別
Category屬性用來描述動作的類別
Category常量字符串描述CATEGORY_DEFAULTandroid.intent.category.DEFAULT默認的CategoryCATEGORY_BROWSABLEandroid.intent.category.BROWSABLE指定Activity能被瀏覽器安全調用CATEGORY_TABandroid.intent.category.TAB指定Activity能作為TabActivity的Tab頁CATEGORY_LAUNCHERandroid.intent.category.LAUNCHERActivity顯示頂級程序列表中CATEGORY_INFOandroid.intent.category.INFO用于提供包信息CATEGORY_HOMEandroid.intent.category.HOME設置該Activity隨系統(tǒng)啟動而運行CATEGORY_PREFERENCEandroid.intent.category.PREFERENCE該Activity是參數(shù)面板CATEGORY_TESTandroid.intent.category.TEST該Activity是一個測試CATEGORY_CAR_DOCKandroid.intent.category.ANSWER指定手機被插入汽車底座時運行該ActivityCATEGORY_DESK_DOCKandroid.intent.category.CAR_DOCK指定手機被插入桌面底座時運行該ActivityCATEGORY_CAR_MODEandroid.intent.category.CAR_MODE設置該Activity可以在車載環(huán)境下使用
Intent屬性:Data數(shù)據(jù)
Data屬性通常用于與Action屬性結合使用,為Intent提供可操作的數(shù)據(jù)
Data屬性接收URI對象
Data與Action屬性結合使用
?//打開網(wǎng)頁
?Intent intent=new Intent ( ) ;
?intent.setAction (Intent.ACTION_VIEw);
?Uri data =Uri.parse ( "http : // www .baidu . com" ) ;//利用Data屬性
?intent.setData(data) ;startActivity (intent) ;
?
Intent屬性:Type數(shù)據(jù)類型
Type屬性用于指定Data屬性URI所對應的MIME類型
Data屬性與Type屬性之間能夠互相覆蓋:
如果為Intent先設置Data屬性,再設置Type屬性,那么Type屬性將會覆蓋Data屬性
如果為Intent先設置Type屬性,再設置Data屬性,那么Data屬性將會覆蓋Type屬性
如果希望Intent既有Data屬性也有Type屬性,應該調用Intent的setDataAndType()方法
lntent屬性:Extras擴展信息
Extras屬性是一個Bundle對象,用于在多個Activity之間交換數(shù)據(jù)
在Intent中通過Bundle類型的Extras屬性來封裝數(shù)據(jù),實現(xiàn)數(shù)據(jù)傳遞
Extras屬性的使用過程
?Bundle bundle= new Bundle();
?bundle.putstring ( "test","this is a test" ) ;Intent intent = new
?Intent (MainActivity.this, secondActivity.class) ;intent.putExtras (bundle);
?startActivity (intent);
??Bundle bundle = this.getIntent () .getExtras () ;string test = bundle.getstring ( "test" );
?通過getExtras()方法獲得Bundle對象并進行取值
使用Extras屬性
l ntent屬性:Flags標志位
Flag屬性用于為Intent添加額外的控制標志
通過Intent的addFlags()方法為Intent添加控制標志
常用的Flag值:
FLAG_ACTIVITY_CLEAR_TOP
FLAG_ACTIVITY_NEW_TASK
FLAG_ACTIVITY_NO_HISTORY
FLAG_ACTIVITY_SINGLE_TOP
使用Intent啟動Activity
startActivity()方法會查找并啟動一個與Intent參數(shù)相匹配的Activity
startActivityForResult()方法啟動Activity并跟蹤子Activity的反饋
通過Intent來顯式地指定要打開的Activity
l ntent Filter過濾器
Intent Filter過濾器用于描述指定的組件可以處理哪些意圖
在Intent Filter中可以包含Intent對象的三個屬性∶
ACTION
DATA
CATEGORY
當Intent對象或者過濾器沒有指定
時:
如果一個Intent過濾器沒有指定任何
,則不會匹配任何Intent ;
如果一個Intent對象沒有指定任何
,而相應的過濾器中有至少一個
時將自動通過此測試。
BroadCastReceiver
BroadcastReceiver是廣播接收器,用于接收系統(tǒng)和應用中的廣播
BroadcastReceiver是一種對廣播進行過濾接收并響應的組件
BroadcastReceiver自身并不提供用戶圖形界面
本質上就是一個全局監(jiān)聽器,用于監(jiān)聽系統(tǒng)全局的廣播消息
實現(xiàn)廣播和接收Intent的步驟如下:
定義BroadCaseReceiver廣播接收器
注冊BroadCaseReceiver廣播接收器
發(fā)送廣播
執(zhí)行
銷毀
BroadcastReceiver的使用步驟:
定義一個BroadcaseReceiver的子類,重寫onReceive()方法
在AndroidManifest.xml文件中注冊廣播接收器對象
在AndroidManifest.xml中添加相應權限(可選)
系統(tǒng)事件觸發(fā)或手動發(fā)送廣播消息
BroadcastReceiver的兩種注冊方式︰
靜態(tài)注冊︰在AndroidManifest.xml文件中定義,注冊的廣播接收器必須繼承BroadReceiver
動態(tài)注冊︰在程序中使用Context.registerReceiver注冊
BroadcastReceiver的兩種使用方式:
主動發(fā)送廣播事件∶通過Context.sendBroadcast來發(fā)送,由 Intent來傳遞注冊時用到的Action。
被動觸發(fā)廣播事件:Android系統(tǒng)提供了一些自帶的標準廣播Action,這些廣播是由系統(tǒng)自動發(fā)出的,直接接收即可。
BroadcastReceiver的兩種注冊方式的區(qū)別:
靜態(tài)注冊︰在AndroidManifest中進行注冊后,不管該應用程序是否處于活動狀態(tài),都會進行監(jiān)聽,比如某個監(jiān)聽內存使用情況的程序,當在手機上安裝好后,不管該應用程序是處于什么狀態(tài),都會執(zhí)行該監(jiān)聽方法中的內容。
動態(tài)注冊︰在代碼中進行注冊后,當應用程序關閉后,就不再進行監(jiān)聽。應用程序是否省電決定了該應用程序的受歡迎程度,所以,對于那些沒必要在程序關閉后仍然進行監(jiān)聽的Receiver,在代碼中進行注冊,無疑是一個明智的選擇。
廣播接收器的注冊方式在Android8.0之后,官方考慮了對耗電量的優(yōu)化,同時也為了防止App廣播的濫用,故除了個別廣播外能使用靜態(tài)注冊外,大部分廣播只支持動態(tài)注冊!
根據(jù)廣播的發(fā)送方式,可以將其分為以下幾種類型︰
普通廣播
系統(tǒng)廣播
有序廣播
粘性廣播
App應用內廣播
Notification通知
Notification的基本布局
Icon/Photo :大圖標
Title/Name :標題
Message:內容信息
Timestamp:通知時間,默認是系統(tǒng)發(fā)出通知的時間,也可以通過setWhen()來設置
Secondary Icon :小圖標
內容文字,在小圖標的左手邊的一個文字
Notification的組成元素依次是∶
Notification的基本使用流程
Notification :通知信息類,它里面對應了通知欄的各個屬性
NotificationManager:是狀態(tài)欄通知的管理類,負責發(fā)通知、清除通知等操作。
狀態(tài)通知欄主要涉及到2個類:Notification和NotificationManager
Step 1.獲得NotificationManager對象︰ NotificationManager mNManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Step 2.創(chuàng)建一個通知欄的Builder構造類∶ Notification.Builder mBuilder = new Notification.Builder(this);
Step 3.對Builder進行相關的設置,比如標題,內容,圖標,動作等;
Step 4.調用Builder的build()方法為notification賦值
Step 5.調用NotificationManager的notify()方法發(fā)送通知!
Notification設置相關的一些方法
setContentTitle(CharSequence):設置標題
setContentText(CharSequence):設置內容
setSubText(CharSequence):設置內容下面一小行的文字
setTicker(CharSequence):設置收到通知時在頂部顯示的文字信息setWhen(long):設置通知時間,一般設置的是收到通知時的System.currentTimeMillis()
setSmallcon(int):設置右下角的小圖標,在接收到通知的時候頂部也會顯示這個小圖標
setLargeIcon(Bitmap)∶設置左邊的大圖標
setAutoCancel(boolean):用戶點擊Notification點擊面板后是否讓通知取消(默認不取消)
setDefaults(int):向通知添加聲音、閃燈和振動效果的最簡單、使用默認( defaults )屬性,可以組合多個屬性
Notification.DEFAULT_VIBRATE(添加默認震動提醒)
Notification.DEFAULT_SOUND(添加默認聲音提醒)
Notification.DEFAULT_LIGHTS(添加默認三色燈提醒)
Notification.DEFAULT_ALL(添加默認以上3種全部提醒)
通過Notification.Builder mBuilder = new Notification.Builder(this)創(chuàng)建通知實例后再調用下述的相關的方法進行設置,常用的方法如下∶
AlarmManager(鬧鐘服務)
什么是AlarmManager?
通常在設定的特定的時間到來時,AlarmManager會為廣播一個設定好的Inten例如時間到了,可以指向某個Activity或者Service。
AlarmManager主要是用來在某個時刻運行代碼,即使App在那個特定時間并沒有運行!從API 19開始,Alarm的機制都是非準確傳遞的,操作系統(tǒng)將會轉換鬧鐘來最小化喚醒和電池的使用。某些新的API會支持嚴格準確的傳遞,見setWindow(int, long, long,PendingIntent)和setExact(int, long, PendingIntent)。targetSdkVersion在API 19之前應用仍將繼續(xù)使用以前的行為,所有的鬧鐘在要求準確傳遞的情況下都會準確傳遞。
Timer類與AlarmManager類區(qū)別
Timer類 Java中的定時器類,用于寫定時任務。但是在Android里,不太適合需要長時間在后臺運行的定時任務,因為Android設備有自己的休眠策略,當長時間的無操作,設備會自動讓CPU進入休眠狀態(tài),這樣就可能導致Timer中的定時任務無法正常運行!
AlarmManager類 AlarmManager不存在Timer類的情況,因為它具有喚醒CPU的功能,可以保證每次需要執(zhí)行特定任務時CPU都能正常工作,或者說當CPU處于休眠時注冊的鬧鐘會被保留(可以喚醒CPU),但如果設備被關閉,或者重新啟動,鬧鐘將被清除!(Android手機關機鬧鐘不響...)
Handler消息傳遞機制
Handler的相關方法
方法描述handleMessage(Message msg)通過重寫該方法來處理消息hasMessage(int what)檢查消息隊列中是否包含what所指定的消息hasMessage(int what,Object object)檢查隊列中是否有指定的what和指定對象的消息obtainMessage()用于獲取消息,具有多個重載方法sendEmptyMessage(int what)用于發(fā)送空消息sendEmptyMessageDelayed(int what,long delayMillis)用于在指定的時間之后發(fā)送空消息sendMessage(Message msg)立即發(fā)送消息sendMessageDelayed(Message msg,longdelayMillis)用于在指定的時間之后發(fā)送空消息
Handler的工作機制
配合Handler工作的其他組件∶
android.os.Message——用于封裝線程之間傳遞的消息
android.os.MessageQueue—一用于負責接收并處理Handler發(fā)送過來的消息
android.os.Looper——負責消息隊列的管理
Handler的執(zhí)行流程圖
UI線程︰就是主線程,系統(tǒng)在創(chuàng)建UI線程的時候會初始化一個Looper對象,同時也會創(chuàng)建一個與其關聯(lián)的MessageQueue;
Handler:作用是發(fā)送與處理信息,如果希望Handler正常工作,在當前線程中要有一個Looper對象﹔
Message : Handler接收與處理的消息對象﹔
MessageQueue :消息隊列,先進先出管理Message,在初始化Looper對象時會創(chuàng)建一個與之關聯(lián)的MessageQueue;
Looper :每個線程只能夠有一個Looper,管理MessageQueue,不斷地從中取出Message分發(fā)給對應的Handler處理。
AsyncTask類
為什么要使用AsyncTask ?
AsyncTask是通過線程池來實現(xiàn)的,在這一點上減少了新建線程和銷毀線程的開銷,減少了內存的使用。
AsyncTask封裝了Threan和 Handler 便于前臺和后臺線程的切換
不能手動調用onPreExecute()、 doInBackground()等方法
使用范型參數(shù),更加安全,也更高效
在執(zhí)行異步任務時,通常會涉及以下幾個步驟:
execute(Params... params)
onPreExecute()
doInBackground
onProgressUpdate(Progress... values)
onPostExecute(Result result)
使用AsyncTask工具類時,需要特別注意以下幾點:
異步任務的實例必須在UI線程中創(chuàng)建
execute(Params... params)方法必須在UI線程中調用
不能手動調用onPreExecute()、doInBackground()等方法
不能在doInBackground(Params... params)方法中更改UI組件的信息
每個任務實例只能執(zhí)行一次,當執(zhí)行第二次時將會拋出異常