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

写在前面的话

1、主要参考自:https://b23.tv/Flmxaa
2、内容如果有不对的,希望可以指出或补充。
3、新知识。

一、广播

(一)广播接收者

① 概述

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

特点:一对多(如一个电台的发出的频率,可以被多个收音机接收到),消息是单向的(如收音机只能接收消息)。

② 测试

1 创建广播接收者。
在这里插入图片描述
在这里插入图片描述
2 动态注册广播接收者-创建

静态的注册:系统一般会自动创建,在项目清单文件里。

动态注册的特点:只有当注册广播接收者的组件活着的时候(存在),对应的广播接收者才会接收到广播,这也是和静态注册的区别所在。
在这里插入图片描述
3 测试-拦截电话

① 布局
在这里插入图片描述
② 代码部分
在这里插入图片描述
在这里插入图片描述
③ 运行效果

项目清单文件
在这里插入图片描述
如下:
在这里插入图片描述

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

① 概述

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

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

② 测试

1 布局以及MainActivity.java内容
在这里插入图片描述
在这里插入图片描述
2 测试效果

和上面的测试一样的道理,处理项目清单文件(声明自定义的广播事件的意图)
在这里插入图片描述
运行结果:
在这里插入图片描述

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

① 概述

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

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

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

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

② 测试-有序广播

需要新建三个广播接收者,以便更好的测试。这三个广播接收者的设置都差不多,如:
在这里插入图片描述
1 布局略

2 运行效果

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

二、服务

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

(一)基础知识

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

生命周期:也就是它从启动到关闭所经历的一个过程。转↓
在这里插入图片描述
启动方式:

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

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

(二)测试

① startService启动Service

1 布局
在这里插入图片描述
2 服务类
在这里插入图片描述
3 展示结果
在这里插入图片描述
总结: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 展示结果
在这里插入图片描述
总结:多次启动服务,onBind()只被调用一次。

三、补充

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

2、遇到的意图报错问题

猜你喜欢

转载自blog.csdn.net/luck_ch09/article/details/112847532