欢迎光临散文网 会员登陆 & 注册

Intent与BroadcastReceiver

2021-07-06 09:32 作者:独行D暗灵  | 我要投稿

Intent原理及分类

  • 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的步骤如下:

    1. 定义BroadCaseReceiver广播接收器

    2. 注册BroadCaseReceiver广播接收器

    3. 发送广播

    4. 执行

    5. 销毁


  • BroadcastReceiver的使用步骤:

    1. 定义一个BroadcaseReceiver的子类,重写onReceive()方法

    2. 在AndroidManifest.xml文件中注册广播接收器对象

    3. 在AndroidManifest.xml中添加相应权限(可选)

    4. 系统事件触发或手动发送广播消息


  • 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()等方法

    • 使用范型参数,更加安全,也更高效


  • 在执行异步任务时,通常会涉及以下几个步骤:

    1. execute(Params... params)

    2. onPreExecute()

    3. doInBackground

    4. onProgressUpdate(Progress... values)

    5. onPostExecute(Result result)


  • 使用AsyncTask工具类时,需要特别注意以下几点:

    • 异步任务的实例必须在UI线程中创建

    • execute(Params... params)方法必须在UI线程中调用

    • 不能手动调用onPreExecute()、doInBackground()等方法

    • 不能在doInBackground(Params... params)方法中更改UI组件的信息

    • 每个任务实例只能执行一次,当执行第二次时将会抛出异常


Intent与BroadcastReceiver的评论 (共 条)

分享到微博请遵守国家法律