美文网首页
广播与服务

广播与服务

作者: fantasy_dandan | 来源:发表于2016-05-10 13:18 被阅读0次

    广播接收者

    • BroadcastReceiver
    • 接收系统发出的广播
    • 现实中的广播:电台为了传达一些消息,而发送的广播,通过广播携带要传递的消息,群众只要买了收音机,就可以收到广播了
    • Android中的广播:系统在运行过程中,会发生很多事件,系统为了让其他应用知道系统发生了这个事件,会发送一个对应事件的广播,比如:电量改变,收到短信,拨打电话,屏幕解锁,系统开机,只有注册一个广播接收者,就可以接收到系统发送的广播。

    IP拨号器

    • 系统拨打号码时,会发出一个广播,广播中会携带拨打的号码,注册广播接收者接收这个广播,取出这个号码,修改号码,然后把修改的号码重新放入广播。

    • 原理


      原理

    定义方式

    • 定义一个类继承BroadCastReceiver
    • 在清单文件中配置该类,并指定接收的广播种类必须配置intent-filter。


      Paste_Image.png

      需要加入权限:

    <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
    
    • 广播是通过Intent发送的,Intent中会携带一个action,系统会在所有的清单文件中寻找,看哪个一个广播接收器的intent-filter 和广播中的intent是匹配的,那么这个广播接收器就会收到这条广播。
    代码
    • 广播运行在哪个进程里面就看她运行在哪个项目里面。
      如果关掉应用进程之后,广播接收者还是会接收,即便没有启动应用进程,广播发出来时,系统也会启动这个进程,然后把广播交给广播接受者。
      广播接受者所在进程是不怕被杀掉的。

    短信防火墙原理

    短信防火墙 短信接收器

    需要的权限:

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    
    注册接收器

    可以取大于1000的数,取整数的最大值

    • 一条短信是由很多 条短信拼接起来的,所以是数组形式
    • 短信拦截必须在有短信时就拦截就必须优先级要高,系统短信优先级不高于1000,先一步收到短信广播,然后拦截广播,短信应用就收不到短信的。


      短信代码
    • 4.0之后,用户手动开启进程,那么广播接收者才能生效
    • 4.0之后,用户手动停止进程,那么广播接受者再也不会启动了,直到用户下一次手动启动进程。

    监听SD卡状态

    监听SD卡不需要权限

    注册监听器设置要监听的Action
    监听SD卡

    开机勒索软件

    注册广播接收器 加入权限
    广播接收器代码
    • 在广播接收器中启动Activity 出现错误


      出现错误
    • 启动一个新的任务栈来保存Activity,之前我们启动Activity是直接点击图标启动的,启动Activity本身是有任务栈的,我们现在在一个Activity任务栈之外启动Activity就会出现问题。因为当前没有任务栈。需要直接创建一个任务栈。
    创建任务栈

    应用的安装卸载和更新

    • 注册广播


      安装卸载广播
    • 广播接收处理


      广播代码

    发送自定义广播

    • 发送广播


      发送代码

      *接收广播


      接收代码

    有序和无序广播

    • 无序广播
      所有与广播中的Intent匹配的广播接收者,都可以收到这条广播,并且不分先后顺序,视为同时收到。

    • 有序广播
      所有与广播中的intent匹配的广播接收者,都可以收到这条广播,但是分先后顺序,优先级高的先收到,优先级低的后收到。

    发送有序广播 设置结果接收器 设置接收者
    设置接收者优先级

    服务

    • Service
      四大组件之一
      运行于后台,没有前台界面,用于运行需要在后台运行的代码
      如:下载任务,音乐播放。
      如果下载线程放在Activity中时,
      按home和返回键 销毁Activity之后 下载还可以运行,这是因为线程还在进程运行,但是进程被杀掉之后,线程就会被销毁。当内存不足时就会杀掉进程,因此不要把下载放在Activity中。

    • Empty 进程(没有任何活动的应用组件(Activity和Service))
      一个进程不包含任何活跃的应用组件(指的是服务和Activity),保持该类型进程活跃的原因只是是缓存,提高下次组件在该进程中的开启速度。
      该进程很容易被杀掉

    • 后台进程(如按home键)
      如果一个进程持有一个对用户不可见的Activity时(该activity的onStop()方法已经被调用),这些进程对用户的体验没有直接的影响。
      很容易被杀死

    • 服务进程(相比bindService而言,这个才是真正用来下载,不到万不得已不会被杀死)
      拥有一个服务的进程。
      该进程中正在运行的是以startService()方法开启的服务。

    • 可见进程

    • 拥有一个不在前台但对用户依然可见的Activity(onPause()方法被调用)的进程

    • 拥有一个与可见Activity(onPause()方法被调用)绑定的服务(特指远程服务)

    • 前台进程

      • 拥有一个正在与用户交互的Activity(onResume()方法调用)
      • 拥有一个与正在与用户交互的Activity绑定的服务(特指远程服务)
      • 拥有一个运行在前台的服务(服务调用了startForeground())
      • 拥有一个正在执行其中一个生命周期方法( onCreate(),onStartCommand(),or onDestory())的服务。
        保证生命周期执行完毕,短暂提高优先级,保证代码执行完毕,完成后就自动降为服务进程。在内存不足不被杀掉。
      • 拥有一个正在执行onReceive的方法的广播接受者。执行完毕该杀就被杀。

    服务的启动和停止

    • 定义方式:创建java类再继承Service类,清单文件做配置。
      可以理解为:没有界面的Activity。


      启动服务
    • 服务单位生命周期
      startService的生命周期:
      onStartCommand:可以多次被调用
      onCreate:只会被调用一次
      onDestory:值会被调用
    • onCreate->onStartCommand->onDestory
      重复的startService不会调用onCreate只会重复调用onStartCommand

    通话录音机

    使用完MediaRecorder释放资源为什么要release()
    电话权限

    服务的两种启动方式及生命周期

    startService

    • 通过startService启动的服务,该服务所在的进程会变成服务进程。
    • Service 与启动它的Activity没有关系。

    bindService

    • 通过bindService启动的服务,进程优先级不变。
    • 绑定出来的Service不是服务进程,它的优先级跟他本身绑定的Activit有关,Activity 是后台的,那就是后台进程,Activity没有了,那就是空进程。
      绑定出来的Service是不能作为后台操作的。很容易死掉进程。

    不能再次解绑的,重复解绑会报错。
    绑定服务后,直接按返回键会报错。说明绑定服务不能作为后台操作

    返回错误
    • 绑定的服务于启动它的Activity是同生共死的,Activity销毁了,服务也要销毁。服务销毁了,activity不销毁。

    调用服务中的方法

    对比办证服务

    回调类ServiceConnection

    服务连接回调

    把中间人的方法抽取到接口中

    抽取接口
    实现抽取方法
    强转

    为什么要这么做,不私有化方法呢?

    模拟音乐播放器

    混合启动Service(startService和bindService)

    start->bind->unbind->stop
    因为要保证音乐播放器退出后音乐还在播放,就必须启动服务进程

    • 一定要先启动后绑定
      先启动startService
      onCreate->onStartCommand
      再绑定
      ->onBind
      再解绑 服务还在
      ->onUnbind ( 不会被摧毁)
      再摧毁
      ->onDetory
    • 如果先bindService(逻辑会出问题)
      onCreate->onbind
      再startService
      ->onStartCommand
      再stopService
      ->服务什么也不干
      最后解绑
      ->onUnbind(会销毁)

    使用代码注册和反注册广播接受者

    清单文件注册

    • 广播接收者永远生效,除非卸载应用,或者手动停止进程(如防火墙)

    代码注册

    通常和service联系在一起,一般启动服务来注册。

    • 需要广播接收者生效时,注册它,不需要时,反注册它,反注册之后,广播接收者就失效了。(只在需要时注册)

    • 特殊广播接收者,必须代码注册。
      这种需求没有必要一直生效。因为这些广播变化得很快,次数很频繁。
      (清单文件注册了而没有代码注册也接收不到)

      • 屏幕开关
      • 电量改变
    • 第一步定义服务并在清单文件中注册服务

    定义服务并在创建中注册广播在销毁中注销广播
    • 第二步定义广播接收器
    定义广播接收器 注册和反注册时需要注意的

    启动和绑定远程服务

    服务的分类

    都是在手机上与web不一样

    本地服务

    • 与启动者都在同一应用的服务

    远程服务

    • 与启动者不在同一应用的服务

    本地服务使用显示启动
    远程服务使用隐式启动

    注意:Android 5.0 之后 Service必须显示启动,不然会报错

    Service隐式启动会报错

    解决方案

    解决方法

    远程服务中使用aidl

    进程间通信

    • AIDL
      android interface definition language
      在Android中进行进程间通讯

    步骤:

    远程Service

    1.把接口文件的后后缀名.aidl;(在gen中自动生成.java文件)
    2.aidl文件中的所有东西都是public ,不需要访问修饰符;
    3.中间人对象继承Stub,这个抽象类Stub已经继承了Binder并实现了aidl里面的方法。


    远程Service

    访问远程服务

    1.把上述的aidl文件复制到访问远程服务的工程中,然后aidl所在的包名必须和远程Service中的aidl一致。

    2.把获取的中间人对象使用Stub.asInterface强转。

    访问远程Service

    支付宝远程服务

    不安全做法 安全做法

    进程优先级的补充

    确定取消对话框

    设置对话框

    单选对话框

    setMessage 是绝对不能设置的,会将单选内容盖掉。

    单选对话框

    设置多选对话框

    设置多选对话框

    设置进度条对话框

    设置进度条对话框

    样式和主题

    • 样式和主题定义的方式是一模一样的
    • 布局文件中使用样式
    • 清单文件中使用主题


      样式和主题的定义方式

    国际化

    国际化

    图片也能国际化:


    图片国际化

    相关文章

      网友评论

          本文标题:广播与服务

          本文链接:https://www.haomeiwen.com/subject/adkyrttx.html