美文网首页
安卓基础学习 Day11 |常用组件-广播和服务

安卓基础学习 Day11 |常用组件-广播和服务

作者: Y__W | 来源:发表于2021-03-27 10:15 被阅读0次

    目录
    一、广播
    (一)广播接收者
    (二)自定义广播的发送与接收
    (三)有序广播和无序广播
    二、服务
    (一)基础知识
    (二)测试
    三、补充
    1、主要参考自:https://b23.tv/Flmxaa
    2、内容如果有不对的,希望可以指出或补充。
    3、新知识。

    一、广播
    (一)广播接收者

    ① 概述

    广播接收者(BroadcastReceiver):Android系统中内置了很多广播,列如手机的开机完成、电池电量不足时都会发送一条广播。为了监听来自系统或者应用程序的广播事件,Android系统提供了广播接收者组件(四大组件之一)。当Android系统产生一个广播事件时,可以有多个对应的广播接收者接收并进行处理。相当于是接收电台消息的收音机。
    特点:一对多(如一个电台的发出的频率,可以被多个收音机接收到),消息是单向的(如收音机只能接收消息)。
    ② 测试

    1 创建广播接收者。


    20210119175502333.png 20210119180040828.png

    2 动态注册广播接收者-创建

    静态的注册:系统一般会自动创建,在项目清单文件里。
    动态注册的特点:只有当注册广播接收者的组件活着的时候(存在),对应的广播接收者才会接收到广播,这也是和静态注册的区别所在。


    20210119182638671.png

    3 测试-拦截电话

    ① 布局


    20210119193816869.png

    ② 代码部分


    20210119194240957.png 20210119194321926.png

    ③ 运行效果

    项目清单文件


    20210119193651599.png

    如下:


    20210119195048263.gif

    (二)自定义广播的发送与接收

    ① 概述

    当系统提供的广播不能满足需求时,可以自定义广播(发送消息),同时需要编写对应的广播接收者(监听消息)。

    当自定义广播发送消息时,会存储到公共消息区中,而公共消息区中如果存在对应的广播接收者,就会及时的接收这条消息。

    ② 测试

    1 布局以及MainActivity.java内容


    20210119202039424.png 20210119202128820.png

    2 测试效果

    和上面的测试一样的道理,处理项目清单文件(声明自定义的广播事件的意图)


    20210119201811513.png

    运行结果:


    20210119201705658.png

    (三)有序广播和无序广播

    ① 概述

    Android系统提供了两种广播类型,有序广播和无序广播,开发者可根据需求为程序设置不同的广播类型。

    有序广播:按照接收者的优先级接收,只有一个广播接收者能接收到消息,在此广播接收者中逻辑执行完毕后,才会继续传递。

    无序广播:是完全异步执行,发送广播时所有监听这个广播的广播接收者都会接收到此消息,但接收的顺序不确定。

    有序广播可以被拦截;无序广播所有的广播接收者都可以接收到消息。

    ② 测试-有序广播

    需要新建三个广播接收者,以便更好的测试。这三个广播接收者的设置都差不多,如:


    20210119210802432.png

    1 布局略

    2 运行效果

    项目清单文件


    20210119205256234.png

    效果如下:


    20210119210144765.png

    注:如果priority的数值相同(优先级一样),那么就是在项目清单文件中最先声明(位置在前面的)先收到消息。如果把高优先级的广播中断了(在广播接收者里编写 拦截有序广播:abortBroadcast(); ),优先级较低的就不会再收到消息了,但有方法(如下图-在发送方法里编写)可以强制广播接收者接收到消息。


    20210119211517483.png

    二、服务

    Day12内容。

    服务(Service)也是四大组件之一,可将它看作是一个没界面的activity(一般用于后台操作,如手机息屏后音乐的播放)。
    最大的特点:可在后台长时间运行。
    (一)基础知识

    创建:同广播接收者的创建类似(在程序包名上右击选择【New】→【Service】→【Service】→在弹出的窗口中输入服务名称或默认即可);若采用自行创建Java类继承Service类的方式创建服务,则需要手动在项目清单文件中进行注册。

    生命周期:也就是它从启动到关闭所经历的一个过程。转↓


    20210120184904896.png

    启动方式:

    ① 通过startService()方法:服务会长期运行在后台,且服务的状态与开启者的状态无关,也就是即使启动服务的组件已被销毁,服务会依旧运行。需要自身调用stopSelf()方法或其他组件调用stopService()方法时服务才能停止。

    ② 通过bindService()方法:服务会与组件绑定。需要调用onUnbind()方法解除绑定之后才会被销毁。注:如果要长期存在,就需要在绑定之前用startService启动 20210120194335831.png

    服务(结合使用)。
    (二)测试

    ① startService启动Service

    1 布局


    20210120194456337.png

    2 服务类


    20210120200115960.png

    3 展示结果


    20210120194335831.png

    总结:onCreate()表示的是当服务创建的时候执行(创建成功了就不会再有作用了),只调用一次;多次执行开启服务(只要服务还是启动着的)会多次调用onStartCommand()且只是复用前面产生的service对象,不会新建新service对象;onDestroy()表示的是关闭服务,同onCreate()一样的道理,只调用一次。

    ② bindService启动Service

    1 布局略(与①的布局设置同理)

    2 代码

    ① MyService.java

    在OnBind()方法中需要返回一个IBinder的实例,否则监听连接状态的方法就不会调用。

    package com.example.testservice;
    
    import android.app.Service;
    import android.content.Intent;
    import android.os.Binder;
    import android.os.IBinder;
    import android.util.Log;
    
    public class MyService extends Service {
        public MyService() { }
    
        //定义onBinder方法所返回的对象实例
        //创建服务代理 调用服务中的方法
        class MyBinder extends Binder{
            //可以间接调用到service里面的相关方法
            public void callTestInService(){
                testInService();
            }
        }
        public void testInService(){
            Log.i("MyService","自定义方法,testInService()");
        }
    
        @Override
        //IBinder是一个接口  可进行跨进程访问(远程调用)
        public IBinder onBind(Intent intent) {
            Log.i("MyService","绑定服务,调用onBind()");
            return new MyBinder();
        }
    
        @Override
        public void onCreate() {
            super.onCreate();
            Log.i("MyService","创建服务,调用onCreate()");
        }
    
        @Override
        //解绑
        public boolean onUnbind(Intent intent) {
            Log.i("MyService","解绑服务,调用onUnbind()");
            return super.onUnbind(intent);
        }
    }
    

    ② MainActivity.java

    package com.example.testservice;
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.content.ComponentName;
    import android.content.Intent;
    import android.content.ServiceConnection;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    import android.view.View;
    
    public class MainActivity extends AppCompatActivity {
        private MyService.MyBinder myBinder;
        private MyTest mytest;
    
        @Override
        //自带
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        }
    
        //绑定(开启)服务
        public void btnBind(View view){
            if(mytest == null){
                mytest = new MyTest();
            }
            Intent intent = new Intent(this,MyService.class);
            //参数1:用于指定要启动的service,参数2:监听调用者与service间的连接状态,
            // 参数3:指定绑定时是否自动创建service
            bindService(intent,mytest,BIND_AUTO_CREATE);
        }
    
        //服务连接时执行
        private class MyTest implements ServiceConnection{
            @Override
            //当成功绑定服务时调用,返回MyService里面的Ibinder对象
            public void onServiceConnected(ComponentName name, IBinder service) {
                myBinder = (MyService.MyBinder) service;
                Log.i("MainActivity","服务成功绑定,内存地址为:"+myBinder.toString());
            }
            //当服务失去连接时,调用的方法
            @Override
            public void onServiceDisconnected(ComponentName name) {
                Log.i("MainActivity","服务失去连接");
            }
        }
    
        //调用服务中的方法
        public void btnCall(View view){
            //访问到MyService里的callTestInService()方法
            myBinder.callTestInService();
        }
    
        //解绑服务
        public void btnUnbind(View view){
            //需要判断是因为:解除绑定时就需要接收ServiceConnection
            if(mytest != null){
                unbindService(mytest);
                mytest = null;
            }
        }
    }
    

    3 展示结果


    20210120215130830.png

    总结:多次启动服务,onBind()只被调用一次。
    三、补充

    1、Android的四大组件,只要被定义了,就必须在AndroidManifest.xml(清单文件)中注册。一般,系统都会自动注册。

    2、遇到的意图报错问题

    相关文章

      网友评论

          本文标题:安卓基础学习 Day11 |常用组件-广播和服务

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