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)方法
触发BroadcastReceiver时,调用sendBroadcast(Intent intent)方法
上述方法中Intent参数用于封装当前组件在启动目标组件时所需的信息,系统通过该信息找到对应的组件,完成组件之间的调用。
显示Intent:明确指定需要启动或触发组件的类名
隐式Intent:只指定了需要启动或触发的组件应满足的条件
Intent对象通过属性来设定相应的启动目标。
Intent对象包含以下几种属性:
Component组件
Action动作
Category类别
Data数据
Type数据类型
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)
创建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的系统标准Action
Action常量字符串描述ACTION_SENDandroid.intent.action.SEND启动一个Activity,该Activity会发送Intent中指定的数据。接收人需要由解析的Activity来选择。ACTION_SENDTOandroid.intent.action.SENDTO启动一个Activity来向Intent的数据URI所指定的联系人发送一条消息。ACTION_ANSWERandroid.intent.action.ANSWER打开一个处理来电的Activity,通常这个动作是由本地电话拨号程序处理ACTION_INSERTandroid.intent.action.INSERT打开一个子Activity能在Intent的数据URI指定的游标处插入新项的Activity。当作为子Activity调用时,应该返回一个指向新插入项的URIACTION_DELETEadnroid.intent.action.DELETE启动一个Activity,允许删除Intent的数据URI中指定的数据ACTION_ALL_AppSandroid.intent.action.ACTION_ALL_AppS打开一个列出所有已安装应用程序的Activity,通常此操作由启动器处理ACTION_SEARCHandroid.intent.action.SEARCH通常用于启动特定的搜索Activity.
Android中针对一些系统级的事件,预先定义了一些标准Action,这此Action对应干Intent类中的常量,其值和意义如下:
ACTION_ BOOT_ _COMPLETED :系统启动完成广播
ACTION TIME _CHANGED : 时间改变广播
ACTION_ DATE_ _CHANGED :日期改变广播
ACTION_ TIME_ TICK :每分钟改变一次时间
ACTION_ TIMEZONE_ CHANGED :时区改变广播
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随系统启动而运行CATEGORY_PREFERENCEandroid.intent.category.PREFERENCE该Activity是参数面板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可以在车载环境下使用
Intent属性:Data数据
Data属性通常用于与Action属性结合使用,为Intent提供可操作的数据
Data属性接收URI对象
Data与Action属性结合使用
//打开网页
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数据类型
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之间交换数据
在Intent中通过Bundle类型的Extras属性来封装数据,实现数据传递
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参数相匹配的Activity
startActivityForResult()方法启动Activity并跟踪子Activity的反馈
通过Intent来显式地指定要打开的Activity
l ntent Filter过滤器
Intent Filter过滤器用于描述指定的组件可以处理哪些意图
在Intent Filter中可以包含Intent对象的三个属性∶
ACTION
DATA
CATEGORY
当Intent对象或者过滤器没有指定
时:
如果一个Intent过滤器没有指定任何
,则不会匹配任何Intent ;
如果一个Intent对象没有指定任何
,而相应的过滤器中有至少一个
时将自动通过此测试。
BroadCastReceiver
BroadcastReceiver是广播接收器,用于接收系统和应用中的广播
BroadcastReceiver是一种对广播进行过滤接收并响应的组件
BroadcastReceiver自身并不提供用户图形界面
本质上就是一个全局监听器,用于监听系统全局的广播消息
实现广播和接收Intent的步骤如下:
定义BroadCaseReceiver广播接收器
注册BroadCaseReceiver广播接收器
发送广播
执行
销毁
BroadcastReceiver的使用步骤:
定义一个BroadcaseReceiver的子类,重写onReceive()方法
在AndroidManifest.xml文件中注册广播接收器对象
在AndroidManifest.xml中添加相应权限(可选)
系统事件触发或手动发送广播消息
BroadcastReceiver的两种注册方式︰
静态注册︰在AndroidManifest.xml文件中定义,注册的广播接收器必须继承BroadReceiver
动态注册︰在程序中使用Context.registerReceiver注册
BroadcastReceiver的两种使用方式:
主动发送广播事件∶通过Context.sendBroadcast来发送,由 Intent来传递注册时用到的Action。
被动触发广播事件:Android系统提供了一些自带的标准广播Action,这些广播是由系统自动发出的,直接接收即可。
BroadcastReceiver的两种注册方式的区别:
静态注册︰在AndroidManifest中进行注册后,不管该应用程序是否处于活动状态,都会进行监听,比如某个监听内存使用情况的程序,当在手机上安装好后,不管该应用程序是处于什么状态,都会执行该监听方法中的内容。
动态注册︰在代码中进行注册后,当应用程序关闭后,就不再进行监听。应用程序是否省电决定了该应用程序的受欢迎程度,所以,对于那些没必要在程序关闭后仍然进行监听的Receiver,在代码中进行注册,无疑是一个明智的选择。
广播接收器的注册方式在Android8.0之后,官方考虑了对耗电量的优化,同时也为了防止App广播的滥用,故除了个别广播外能使用静态注册外,大部分广播只支持动态注册!
根据广播的发送方式,可以将其分为以下几种类型︰
普通广播
系统广播
有序广播
粘性广播
App应用内广播
Notification通知
Notification的基本布局
Icon/Photo :大图标
Title/Name :标题
Message:内容信息
Timestamp:通知时间,默认是系统发出通知的时间,也可以通过setWhen()来设置
Secondary Icon :小图标
内容文字,在小图标的左手边的一个文字
Notification的组成元素依次是∶
Notification的基本使用流程
Notification :通知信息类,它里面对应了通知栏的各个属性
NotificationManager:是状态栏通知的管理类,负责发通知、清除通知等操作。
状态通知栏主要涉及到2个类:Notification和NotificationManager
Step 1.获得NotificationManager对象︰ NotificationManager mNManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Step 2.创建一个通知栏的Builder构造类∶ Notification.Builder mBuilder = new Notification.Builder(this);
Step 3.对Builder进行相关的设置,比如标题,内容,图标,动作等;
Step 4.调用Builder的build()方法为notification赋值
Step 5.调用NotificationManager的notify()方法发送通知!
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)创建通知实例后再调用下述的相关的方法进行设置,常用的方法如下∶
AlarmManager(闹钟服务)
什么是AlarmManager?
通常在设定的特定的时间到来时,AlarmManager会为广播一个设定好的Inten例如时间到了,可以指向某个Activity或者Service。
AlarmManager主要是用来在某个时刻运行代码,即使App在那个特定时间并没有运行!从API 19开始,Alarm的机制都是非准确传递的,操作系统将会转换闹钟来最小化唤醒和电池的使用。某些新的API会支持严格准确的传递,见setWindow(int, long, long,PendingIntent)和setExact(int, long, PendingIntent)。targetSdkVersion在API 19之前应用仍将继续使用以前的行为,所有的闹钟在要求准确传递的情况下都会准确传递。
Timer类与AlarmManager类区别
Timer类 Java中的定时器类,用于写定时任务。但是在Android里,不太适合需要长时间在后台运行的定时任务,因为Android设备有自己的休眠策略,当长时间的无操作,设备会自动让CPU进入休眠状态,这样就可能导致Timer中的定时任务无法正常运行!
AlarmManager类 AlarmManager不存在Timer类的情况,因为它具有唤醒CPU的功能,可以保证每次需要执行特定任务时CPU都能正常工作,或者说当CPU处于休眠时注册的闹钟会被保留(可以唤醒CPU),但如果设备被关闭,或者重新启动,闹钟将被清除!(Android手机关机闹钟不响...)
Handler消息传递机制
Handler的相关方法
方法描述handleMessage(Message msg)通过重写该方法来处理消息hasMessage(int what)检查消息队列中是否包含what所指定的消息hasMessage(int what,Object object)检查队列中是否有指定的what和指定对象的消息obtainMessage()用于获取消息,具有多个重载方法sendEmptyMessage(int what)用于发送空消息sendEmptyMessageDelayed(int what,long delayMillis)用于在指定的时间之后发送空消息sendMessage(Message msg)立即发送消息sendMessageDelayed(Message msg,longdelayMillis)用于在指定的时间之后发送空消息
Handler的工作机制
配合Handler工作的其他组件∶
android.os.Message——用于封装线程之间传递的消息
android.os.MessageQueue—一用于负责接收并处理Handler发送过来的消息
android.os.Looper——负责消息队列的管理
Handler的执行流程图
UI线程︰就是主线程,系统在创建UI线程的时候会初始化一个Looper对象,同时也会创建一个与其关联的MessageQueue;
Handler:作用是发送与处理信息,如果希望Handler正常工作,在当前线程中要有一个Looper对象﹔
Message : Handler接收与处理的消息对象﹔
MessageQueue :消息队列,先进先出管理Message,在初始化Looper对象时会创建一个与之关联的MessageQueue;
Looper :每个线程只能够有一个Looper,管理MessageQueue,不断地从中取出Message分发给对应的Handler处理。
AsyncTask类
为什么要使用AsyncTask ?
AsyncTask是通过线程池来实现的,在这一点上减少了新建线程和销毁线程的开销,减少了内存的使用。
AsyncTask封装了Threan和 Handler 便于前台和后台线程的切换
不能手动调用onPreExecute()、 doInBackground()等方法
使用范型参数,更加安全,也更高效
在执行异步任务时,通常会涉及以下几个步骤:
execute(Params... params)
onPreExecute()
doInBackground
onProgressUpdate(Progress... values)
onPostExecute(Result result)
使用AsyncTask工具类时,需要特别注意以下几点:
异步任务的实例必须在UI线程中创建
execute(Params... params)方法必须在UI线程中调用
不能手动调用onPreExecute()、doInBackground()等方法
不能在doInBackground(Params... params)方法中更改UI组件的信息
每个任务实例只能执行一次,当执行第二次时将会抛出异常