Android - 四大组件之广播,广播接受者/电台/事件,四大组件之服务,进程优先级,服务的生命周期

本文详细介绍了Android平台上的广播接收者和服务的使用方法,包括创建、配置及应用场景。涵盖SD卡状态、开机启动、外拨电话等多种广播类型的配置示例,并深入探讨了服务的创建、生命周期及其在后台任务中的应用。
转载请注明出处:https://blog.youkuaiyun.com/mythmayor/article/details/72876686

1.广播接受者

电量不足,sd卡被移除,电话外拨,短信到了等等各种各样的事件…

1. 买个收音机
    class SDCardStatusReceiver extends BroadcastReceiver
2. 装上电池
    <receiver android:name="com.mythmayor.sdstatus.SDCardStatusReceiver" >
3. 调到对应的频道 FM 93.4MHZ
<intent-filter>
    <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
    <data android:scheme="file"></data>
</intent-filter>
4. onreceive方法里面编写业务逻辑

>
* sd卡状态
* 开机启动
* 外拨电话
* 应用程序安装和卸载
* 短信的广播接受者

5.短信窃听需要的配置

<receiver android:name="com.mythmayor.smslistener.SmsReceiver">
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

2.创建广播接收者

1. 创建一个类继承BroadcastReceiver
    class SDCardStatusReceiver extends BroadcastReceiver {
    }
2. 在清单文件中的Application节点下进行配置
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
    ...
    ...
    <!-- 广播接收者的全类名 -->
    <receiver android:name="com.mythmayor.sdstatus.SDCardStatusReceiver" >
        <!-- 配置要接收哪个广播 -->
        <intent-filter>
        <action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
        <data android:scheme="file"></data>
        </intent-filter>
    </receiver>
</application>
3. onreceive方法里面编写业务逻辑
public class SDCardStatusReceiver extends BroadcastReceiver {   
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "外部存储卡已被拔出,微信头像和朋友圈功能暂不可用", 0).show();
    }
}

3.开机启动的广播接收者的配置

添加权限

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

在清单文件的application节点中进行配置

<receiver android:name="com.mythmayor.bootcomplete.BootCompleteReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
</receiver>

4.如何重写返回键的功能

//重写Activity的onBackPressed()方法
@Override
public void onBackPressed() {       
}

5.外拨电话的广播接收者的配置

添加权限

<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

在清单文件的application节点中进行配置

<receiver android:name="com.mythmayor.ipdail.OutCallRecevier">
    <intent-filter>
        <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
    </intent-filter>
</receiver>

6.获得外拨电话号,修改外拨电话号

public class OutCallRecevier extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        SharedPreferences sp = context.getSharedPreferences("config", 0);
        String ipnumber = sp.getString("ipnumber", "");

        //获取外拨电话号
        String number = getResultData();
        if (number.startsWith("0")) {

            //设置外拨电话号
            setResultData(ipnumber + number);
        }
    }

}

7.软件安装和卸载的广播接收者的配置

在清单文件的application节点中进行配置

<receiver android:name="com.mythmayor.datacollection.AppStatusReceiver" >
    <intent-filter >
        <action android:name="android.intent.action.PACKAGE_ADDED"/>
        <action android:name="android.intent.action.PACKAGE_REMOVED"/>
        <data android:scheme="package"></data>
    </intent-filter>
</receiver>

8.短信广播接收者的配置

添加权限

<uses-permission android:name="android.permission.RECEIVE_SMS"/>

在清单文件的application节点中进行配置

<receiver android:name="com.mythmayor.smslistener.SmsReceiver">
    <intent-filter android:priority="1000">
        <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
    </intent-filter>
</receiver>

9.短信数据的解析

public class SmsReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("短信到来了....");
        //短信的数据是pdu的数据,必须对短信的格式很了解才可以解析短信.
        Object[] objs = (Object[]) intent.getExtras().get("pdus");
        for(Object obj:objs){
            SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
            String body = smsMessage.getMessageBody();
            String sender = smsMessage.getOriginatingAddress();
            System.out.println("body:"+body);
            System.out.println("sender:"+sender);
            abortBroadcast();
        }
    }
}

10.广播接收者不同版本中的特性

  1. 自Android 3.1之后,所有新安装但未被执行过的apk,以及那些被用户强行停止的apk,都会处于stopped状态。这个状态下,apk中的广播接收者,均处于未激活状态, 无法履行监听功能。
  2. 在广播发送方发送广播时需要设置Intent.FLAG_INCLUDE_STOPPED_PACKAGES

    Intent intent = new Intent();
    intent.setAction("com.mythmayor.broadcast");
    if (android.os.Build.VERSION.SDK_INT >= 12) {
         intent.setFlags(32);//3.1以后的版本需要设置Intent.FLAG_INCLUDE_STOPPED_PACKAGES
    }
    sendBroadcast(intent);
    

11.如何发送和接收自定义广播

1. 发送
    Intent intent = new Intent();
    //自定义action
    intent.setAction("com.mythmayor.ccav.XWLB");
    //可以添加参数
    intent.putExtra("key", "dfafadfa");
    sendBroadcast(intent);
2. 接收
    <receiver android:name="com.mythmayor.myreceiver.MyReceiver">
        <intent-filter >
            //填写要接收自定义广播的action
            <action android:name="com.mythmayor.ccav.XWLB"/>
        </intent-filter>
    </receiver>     

12.有序广播和无序广播的区别

  1. 有序广播
    • 广播消息是按照一定的顺序传达的,高优先级的先得到广播消息,低优先级的后得到
    • 高优先级的可以拦截广播消息或者修改广播消息
    • 效率比较低
  2. 无序广播
    • 广播消息没有顺序,同时接受广播消息
    • 不可以修改广播消息
    • 效率高

13.如何发送有序广播

Intent intent = new Intent();
intent.setAction("com.mythmayor.gov.SENDMASHROOM");
// 发送有序广播
// intent 意图
// receiverPermission 权限 默认null
// resultReceiver 结果接受者 null
// scheduler 消息处理器 null 默认
// initialCode 初始化码
// initialData 初始化数据
// initialExtras null 额外的数据
sendOrderedBroadcast(intent, null, null, null, 1, "主席讲话: 每人10斤蘑菇", null);

14.有序广播的特点

  1. 优先级在哪里配置,范围是多少

    <receiver android:name="com.mythmayor.smslistener.SmsReceiver">
        //在此处配置,范围从1000到-1000
        <intent-filter android:priority="1000">
            <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
        </intent-filter>
    </receiver>
    
  2. 如何获取数据,如何修改数据

    //获取数据
    String data = getResultData();
    
    //修改数据
    setResultData("主席讲话:每人5斤蘑菇");
    
  3. 如何终止有序广播

    abortBroadcast();
    
  4. resultReceiver什么时候收到广播,需要在清单文件中配置吗

    1.在所有广播接收者都收到消息后接受到广播
    2.即使有广播接收者终止了广播,resultReceiver也可以接收到广播
    3.不需要在清单文件中配置
    

15.如何动态注册广播接收者

receiver = new ScreenStatusReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.SCREEN_OFF");
filter.addAction("android.intent.action.SCREEN_ON");
registerReceiver(receiver, filter);

16.动态注册广播接收者的特点

  1. 在android里面有一些产生非常频繁的广播事件,在清单文件里面配置是不会生效。电量变化、屏幕锁屏、解锁,这些广播事件只能利用代码注册
  2. 动态注册的广播接收者可以将其关闭掉
    unregisterReceiver(receiver);

17.广播接收者的特点:

即使应用程序的进程不存在,当广播事件到来的时候,广播接受者的进程会自动的启动,响应广播事件

18.广播事件的类型

  • 有序广播

    广播消息是按照一定的顺序传达的, 高优先级的先得到广播消息,低优先级的后得到,高优先级的可以拦截广播消息或者修改广播消息. 效率比较低.

  • 无序广播

    广播消息没有顺序,同时接受广播消息. 效率高.

19.特殊广播事件

在android里面有一些产生非常频繁的广播事件,在清单文件里面配置是不会生效.
电量变化 屏幕锁屏/解锁 这些广播事件只能利用代码注册.
这里写图片描述

20.服务

长期后台运行,没有界面的组件,服务是运行在当前应用程序进程里面

21.如何创建一个服务

  1. 创建一个类继承Service

    public class DemoService extends Service {
    
    }
    
  2. 在清单文件的application节点中进行配置

    <service android:name="com.mythmayor.servicedemo.DemoService" >
    </service>
    

22.如何开启和关闭服务

  1. 开启服务

    Intent intent = new Intent(this,DemoService.class);
    startService(intent);
    
  2. 关闭服务

    Intent intent = new Intent(this,DemoService.class);
    stopService(intent);
    

23.服务创建和销毁的生命周期方法

  1. 服务创建:onCreate
  2. 服务销毁:onDestroy

24.服务运行在那个线程

运行在主线程,不能执行耗时操作

25.服务的生命周期

  1. 多次调用startService()的方式开启服务,服务只会被创建一次,在创建的时候执行onCreate()方法,一旦服务创建完毕,再去开启service就不会重复执行onCreate()方法了,只会执行onStart()和onStartCommand()

  2. 调用stopService()停止服务,执行ondestroy()方法,服务只会被停止一次

26.组件


  • Activity
  • broadcast Receiver
  • Service : 服务

windows: 长期后台运行没有界面的进程就叫服务.

android: 长期后台运行,没有界面的组件, 服务是运行在当前应用程序进程里面

27.服务的应用场景

长期后台运行,没有界面的组件.

  1. 监视一个硬件是否被插入
  2. 连接服务器刷新最新的数据.
  3. 定时的轮询
    注意: 服务是运行在主线程里面(main), 不可以直接在服务里面编写耗时的逻辑.

28.进程的优先级


  • Foreground process

前台进程: 用户正在操作的应用程序所在的进程就是前台进程
  • Visible process
    可视进程: 用户已经不能操作这个应用程序了,但是界面用户仍然可以看到
  • Service process
    服务进程: 应用程序有一个服务代码正在运行
  • Background process
    后台进程: 应用程序有界面,但是界面被用户最小化(home)
  • Empty process
    空进程: 应用程序没有任何运行的Activity,service.
    前台进程>可视进程>服务进程>后台进程>空进程

29.为什么要使用服务而不用子线程

    当应用程序退出后,如果里面只有一个子线程,那么这个进程就会被当做一个空进程,优先级很低,当内存不足的时候,会很快地被回收了。而如果开了一个服务的话,就算把程序退出了,那么这个进程也是一个服务进程,优先级算中等。不会马上被回收,在内存充足的时候会被重新开启

30.有用网站

www.grepcode.com

31.总结

  1. 广播接收者(BroadcastReceiver)
    1. 什么是广播接收者
    2. 如何使用广播接收者
      • SD卡挂载状态的广播接收者
      • 开机的广播的接收者
      • 外拨电话的广播接收者
      • 软件安装与卸载的广播接收者
      • 短信的广播接收者
    3. 不同版本广播接收者的特点
    4. 如何发送自定义广播,如何接收自定义广播
    5. 无序广播和有序广播的区别
    6. 如何动态注册广播接收者,动态注册广播接收者的特点
  2. 服务(Service)
    1. 什么是服务
    2. 如何创建服务
    3. 如何开启和关闭服务
    4. 进程的5个优先级
    5. 服务的生命周期
  3. MediaPlayer的简单使用
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值