广播机制基础知识

news2024/11/25 14:40:07

广播机制

1.广播机制

1.1概述

1.1.1引入

1.广播的生活案例

  • 记得以前读书的时候,每个班级都会有一个挂在墙上的大喇叭,用来广播一些通知,比如,开学要去搬书,广播: "每个班级找几个同学教务处拿书",发出这个广播后,所有同学都会在同一时刻收到这条广播通知,收到,但不是每个同学都会去搬书,一般去搬书的都是班里的"大力士",这群"大力士"接到这条广播后就会动身去把书搬回可是!——好吧,上面这个就是一个广播传递的一个很形象的例子:
  • 大喇叭--> 发送广播 --> 所有学生都能收到广播 --> 大力士处理广播

2.生活中广播特点

(1)广播发送者

  • 发一个或者多个
  • 不关心谁接收
  • 实时性

(2)广播接收者

  • 接收一个或者多个
  • 执行相应操作
  • 不关心谁发的
  • 实时性

3.广播的好处

  • 广播的发送者和接收者事先是不需要知道对方的存在的,这样带来的好处便是:系统的各个组件可以松耦合地组织在一起,这样系统就具有高度的可扩展性,容易与其它系统进行集成。

1.1.2Android中的广播

1.安卓中的广播

  • 如:手机接到一条短信,就会产生一个收到短消息的事件。接到一个电话,就会产生一个接到电话的事件。拍摄照片后就会产生一个拍摄照片的事件。
  • 在Android中,有一些操作完成以后,会发送广播,比如说发出一条短信,或打出一个电话,比如电池的使用状态,电话的接收和短信的接收都会产生一个广播。Android系统内部产生这些事件后广播这些事件,至于广播接收对象是否关心这些事件,以及它们如何处理这些事件,都由广播接收对象自己决定。

2.系统广播

  • 电池的状态(如:电量不足)
  • 短信的接收和发送
  • 电话的接听和拨打
  • 系统闹钟
  • 系统垃圾文件占用内存过多

3.广播的原理

4.广播机制

  • 检查注册时候的IntentFilter中的Action是不是和广播Intent中的action是一致的
  • 一致的话使用onReceive相匹配

1.1.3广播接收器

1.BroadcastReceiver

  • 监听系统或者是应用广播

2.BroadcastReceiver介绍

  • 安卓中四大组件之一
  • 本质:全局的监听器(OnXxxListener是程序级别的事件监听器

3.如何接收广播?

  • 先注册,注册方式有多种

4.系统广播接收器创建步骤

关键是注册

  1. 创建BroadcaseReceiver的子类,重写onReceive方法
  2. 注册,编写intentfilter标签设置action的值
  3. 广播发出后,对比intentfilter中的action的值是不是一致的,一致就调用onReceive方法创建接收器对象否则不创建

总之,接收的事件处理逻辑放到onReceive方法中就可以。调用完onReceive方法之后就失效了。

5.发送本地广播的创建方式

  1. 创建BroadcaseReceiver的子类,重写onReceive方法
  2. 注册,编写intentfilter标签设置action的值
  3. 创建Intent,设置action属性,使用sendBroadcast(intent)发送广播
  4. 广播发出后,对比intentfilter中的action的值是不是一致的,一致就调用onReceive方法创建接收器对象否则不创建

1.1.4自定义广播接收器

  • Intent就相当于无线电的信号,里面有很多正要的信息。

//第一个广播 接收器
public class MyBroadcastReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
    }
}

1.1.5常见的系统权限

发短信要有发短信的权限
<uses-permission android:name="android.permission.RECEIVE_SMS“/>
接收开机广播的权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

1.1.6常见的广播Action

1.1.7发送系统级广播

1.广播类型

  • 标准广播
    • 异步执行,不一定哪个先接收到,几乎是同时
  • 有序广播
    • 根据优先级和注册的顺序一个一个的接收,只有接受并处理完了才可以继续往下传播

2.创建方式

  • 标准广播:context的sendBroadcast(Intent)
  • 有序广播:context的sendOrderedBroadcast(Intent,str)
    • <intent-filter>元素的android:priority属性中设置
    • 在IntentFilter对象的setPriority()设置
    • 取值范围:-1000到1000,数越大,优先级越高
    • str,权限参数,如果为null则表示不要求接收者声明指定的权限,如果不为null,则表示接收者若要接收此广播,需声明指定权限。

3.有序广播接收器

  • setResultExtras(Bundle)方法将一个Bundle对象设置为结果集对象,传给下一个接收者。
  • 下一个接收者通过getResultExtras()可以获取上一个接收者存入的数据

public final Bundle getResultExtras(boolean makeMap)

makeMap如果为true,如果当前的Bundle为null,将创建一个空的Bundle对象;否则需要准备好接收一个空Bundle对象。用的时候设置成true就行了

  • abortBroadcast(),阻断广播不往下传播

4.有序和无序的比较

标准

有序

异步

反之

不可以终止

反之

无法传递结果

反之

发送方式是sendBroadcast(intent)

反之

1.1.8本地广播(重点)

1.优缺点

  • 高效
  • 防止泄露
  • 安全性更高

2.如何创建

  • 只能采用动态的注册方式
  • 必须在一个包下

3.LocalBroadcastManager

  • 局部通知管理器,这种通知的好处是安全性高,效率也高,适合局部通信。

4.获取LocalBroadcastManager的实例对象

LocalBroadcastManager localBManager = 
		LocalBroadcastManager.getInstance( this ) ;

5.注册方式

  • LocalBroadcastManager对象的registerReceiver()注册广播

6.创建步骤(重点)

  1. 创建intent,设置action
  2. 可选,设置intent的数据
  3. 创建IntentFilter,设置action
  4. 创建自定义的BroadCastReceiver对象
  5. 获取LocalBroadcastManager对象
  6. 根据LocalBroadcastManager对象调用registerBroadcast(接收器对象,intentfilter)注册
  7. LocalBroadcastManager对象的sendBroadcast(intent)发送广播

注意:

  • 和一般的不同的就在于5,6,7步
  • 本地广播无法通过静态注册来接收
  • 本地广播相比系统全局广播更加高效

7.取消注册的方法

  1. LocalBroadcastManager对象的unregisterReceiver(localReceiver);方法

1.2注册方式

两种注册方式:

  • 动态注册:在代码里注册(万能)
  • 静态注册:在AndroidManifest.xml中注册;

1.2.1静态注册

1.注册方式

  • AndroidManifest.xml中注册。
  • action指定要接收的广播事件

 <receiver android:name=".MyBroadcastReceiver1"
            android:exported="true">
 <intent-filter>
 <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
            </intent-filter>
        </receiver>

扩展:在顺序广播中可以指定优先级

2.优缺点

优点:不用启动程序就可以

1.2.2动态注册

1.注册方式

  • 有两种代码的方式
  • IntentFilter设置要监听的广播
  • registerReceiver注册广播

2.IntentFilter的方法

No

方法

类型

描述

1

public IntentFilter()

构造

创建一个空的IntentFilter对象

2

public IntentFilter(String action)

构造

创建一个IntentFilter对象,并指定Action

3

public final void addAction(String action)

普通

增加一个要过滤的Action

4

public final void addCategory(String category)

普通

增加一个要过滤的Category

5

public final boolean hasAction(String action)

普通

判断指定的Action是否存在

6

public final boolean hasCategory(String category)

普通

判断指定的Category是否存在

3.取消注册

  • 一定要设置取消注册,不然的话在Activity或者是Service销毁的时候没有取消注册会报错的。

4.优缺点

优点:注册方式灵活,根据需要注册,常用于更新UI。

缺点:需要程序启动才可以接收广播,假如我们需要程序 没有启动,但是还是能接收广播的话,那么就需要注册静态广播了!

也就是广播接收器必须是启动着的。

1.2.3静态注册案例-接收开机广播

1.案例:接收开机的广播

  1. 创建自定义的BroadcastReceiver用于处理监听到的系统广播。

//接收系统开机的广播事件
public class BootCompleteReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "开机成功!", Toast.LENGTH_SHORT).show();
    }
}

  1. 注册广播接收器。

   <receiver android:name=".BootCompleteReceiver"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

  1. 开启权限。

   <!--接收开机广播的权限-->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

  1. 重启手机。

1.2.4静/动态注册案例-发送广播

1.动态注册的方式发送标准广播

  • 发送标准广播
  • 设置要发送的数据
  • 不带权限

(1)布局文件

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送标准广播"
        android:textSize="30dp"
        android:onClick="sendBroadcast" />

(2)Java代码

    //点击按钮发送标准广播
    public void sendBroadcast(View view) {
        //设置发送的数据
        Intent intent =new Intent();
        intent.setAction("com.lxz.app8");
        intent.putExtra("code","我是张三!");
        //动态注册
        IntentFilter filter=new IntentFilter();
        filter.addAction("com.lxz.app8");
        BroadcastReceiver1 receiver=new BroadcastReceiver1();
        registerReceiver(receiver,filter);
        //发送广播
        sendBroadcast(intent);

    }

(3)自定义广播接收器

//接收标准广播
public class BroadcastReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code"), Toast.LENGTH_SHORT).show();
    }
}

(4)效果图

2.在1的基础上设置权限

(1)manifest中定义和设置权限

    <!--定义权限-->
    <permission android:name="com.lxz.app.permission"/>
    <!--设置权限-->
    <uses-permission android:name="com.lxz.app.permission"/>

(2)布局文件

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送标准广播(带权限)"
        android:textSize="30dp"
        android:onClick="sendBroadcast2" />

(3)发送广播的Java代码

  //点击按钮发送标准广播(带权限)
    public void sendBroadcast2(View view) {
        //设置发送的数据
        Intent intent =new Intent();
        intent.setAction("com.lxz.app8");
        intent.putExtra("code","我是张三!有权限!");
        //动态注册
        IntentFilter filter=new IntentFilter();
        filter.addAction("com.lxz.app8");
        BroadcastReceiver1 receiver=new BroadcastReceiver1();
        registerReceiver(receiver,filter);

        //设置权限
        String str="com.lxz.app.permission";
        //发送广播
        sendBroadcast(intent,str);

    }

(4)广播接收器

//接收标准广播
public class BroadcastReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code"), Toast.LENGTH_SHORT).show();
    }
}

(5)效果图

3.有序广播的测试

  • 采用静态注册的方式
  • 设置优先级

(1)布局文件


    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送有序广播"
        android:textSize="30dp"
        android:onClick="sendOrderBroadcast1" />

(2)发送有序广播的方法

 //点击按钮发送有序广播
    public void sendOrderBroadcast1(View view) {
        //设置发送的数据
        Intent intent =new Intent();
        intent.setAction("com.lxz.app8");
        intent.putExtra("code","请依次报号!");

        //发送广播-参数2代表的是自定义的权限
        sendOrderedBroadcast(intent,null);

    }

(3)注册代码

    <!--注册广播-->
        <receiver android:name=".BroadcastOrderReceiver"
            android:exported="true"
            >
            <intent-filter android:priority="0">
                <action android:name="com.lxz.app8"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".BroadcastOrderReceiver1"
            android:exported="true"
            >
            <intent-filter android:priority="1">
                <action android:name="com.lxz.app8"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".BroadcastOrderReceiver2"
            android:exported="true"
            >
            <intent-filter android:priority="2">
                <action android:name="com.lxz.app8"/>
            </intent-filter>
        </receiver>
        <receiver android:name=".BroadcastOrderReceiver3"
            android:exported="true"
            >
            <intent-filter android:priority="3">
                <action android:name="com.lxz.app8"/>
            </intent-filter>
        </receiver>

(4)广播接收者

  • 注册顺序从上到下
  • 优先级从下到上
  • 响应的时候从下到上

  • 代码从下到上依次为

public class BroadcastOrderReceiver3 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code")+"我是3号", Toast.LENGTH_SHORT).show();
        Bundle bundle=getResultExtras(true);
        System.out.println("----第3个接收器---");
        System.out.println("附加信息---"+bundle.getString("other"));
        bundle.putString("other",bundle.getString("other")+",我是3号!");
        setResultExtras(bundle);

    }
}

public class BroadcastOrderReceiver2 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code")+"我是2号", Toast.LENGTH_SHORT).show();
        Bundle bundle=getResultExtras(true);
        System.out.println("----第2个接收器---");
        System.out.println("附加信息---"+bundle.getString("other"));
        bundle.putString("other",bundle.getString("other")+",我是2号!");
        setResultExtras(bundle);


    }
}

public class BroadcastOrderReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code")+"我是1号", Toast.LENGTH_SHORT).show();
        Bundle bundle=getResultExtras(true);
        System.out.println("----第1个接收器---");
        System.out.println("附加信息---"+bundle.getString("other"));
        bundle.putString("other",bundle.getString("other")+",我是1号!");
        setResultExtras(bundle);
        //停止广播的传递
        abortBroadcast();
        System.out.println("阻断传播");
    }
}

public class BroadcastOrderReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code")+"我是0号", Toast.LENGTH_SHORT).show();
        Bundle bundle=getResultExtras(true);
        System.out.println("----第0个接收器---");
        System.out.println("附加信息---"+bundle.getString("other"));
    }
}

(5)效果图

1.2.5本地广播案例-简单的发送和接收

1.参考代码

(1)布局文件代码

 <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="发送本地广播"
        android:textSize="30dp"
        android:onClick="localBroadcast" />

(2)发送本地广播的Java代码

    //发送本地广播
    public void localBroadcast(View view) {
        //设置数据
        Intent intent=new Intent();
        intent.setAction("com.lxz.localapp");
        intent.putExtra("code","我是本地广播");
        //动态注册
        LocalBroadReceiver receiver=new LocalBroadReceiver();
        IntentFilter filter=new IntentFilter();
        filter.addAction("com.lxz.localapp");
        LocalBroadcastManager manager=LocalBroadcastManager.getInstance(getApplicationContext());
        manager.registerReceiver(receiver,filter);

        //发送广播
        manager.sendBroadcast(intent);
    }

(3)本地广播接收者的代码

//接收本地广播
public class LocalBroadReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "接收信息:"+intent.getStringExtra("code"), Toast.LENGTH_SHORT).show();
    }
}

(4)效果图

1.2.6本地广播案例-仿qq下线

待实现

1.案例要求

  • 像QQ一样,正在运行的QQ,如果我们用别的手机再次登陆自己的账号,前面这个是会提醒账户在别的终端登录,然后把我们打开的app都关掉,然后回到登陆页面。LoginActivity.java
  • 注意:需要在模拟器中设置—应用-左上角— —打开应用信息—设置出现在其它应用上

2.参考代码

(1)项目目录结构

(2)ActivityCtroller代码。

  • 用于管理所有的Activity

//Activity管理类
public class ActivityController {
    //保存Activity
   private static List<Activity> list=new ArrayList<>();
   //添加Activity
   public  static void addActivity(Activity activity){
        list.add(activity);
   }
    //删除Activity
    public  static void removeActivity(Activity activity){
        list.remove(activity);
    }
    //结束所有的Activity
    public static void finishAllActivity(){
        for (Activity a:list){
           if (!a.isFinishing()){
               a.finish();
           }
        }
    }
}

(3)BaseActivity,是登录成功界面的基类,可以注册BroadcastReceiver。

  • 注意必须添加
  • android.intent.category.DEFAULT

public class BaseActivity extends AppCompatActivity {
    private LoginOutReceiver receiver;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityController.addActivity(this);
    }

    @Override
    protected void  onResume() {
        super.onResume();
        //注册广播
        IntentFilter filter = new IntentFilter();
        filter.addAction("com.lxz.loginout");
        filter.addCategory("android.intent.category.DEFAULT");
        receiver = new LoginOutReceiver();
        registerReceiver(receiver, filter);


    }

    @Override
    protected void onPause() {
        super.onPause();

        if (receiver!=null){
            unregisterReceiver(receiver);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}

(4)登录界面的Activity。

//仿qq下线
public class LoginActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
    }

    //方法:登录
    public void login(View view) {
        EditText account=findViewById(R.id.account);
        EditText password=findViewById(R.id.password);
        System.out.println(account+","+password);
        if (account.getText().toString().equals("root")&&password.getText().toString().equals("123456")){
             Toast.makeText(this, "登录成功!", Toast.LENGTH_SHORT).show();
            Intent intent=new Intent();
            intent.setClass(getApplicationContext(),LoginSuccessActivity.class);
            startActivity(intent);
            finish();
        }
        else{
            Toast.makeText(this, "账号或密码错误!", Toast.LENGTH_SHORT).show();
        }


    }
}

(5)登录界面activity对应的布局文件。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".LoginActivity">

    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:stretchColumns="1">

        <TableRow>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="text"
                android:text="账号:"
                android:textSize="30dp" />

            <EditText
                android:id="@+id/account"
                android:text="root"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="账号(root)"
                android:inputType="text"
                android:maxLines="1"
                android:textSize="30dp" />
        </TableRow>

        <TableRow>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:inputType="text"
                android:text="密码:"
                android:textSize="30dp" />

            <EditText
                android:id="@+id/password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:hint="密码(123456)"
                android:inputType="text"
                android:maxLines="1"
                android:text="123456"
                android:textSize="30dp" />
        </TableRow>
    </TableLayout>

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="login"
        android:text="登录"
        android:textSize="30dp" />
</LinearLayout>

(6)登录成功Activity,LoginSuccessActivity的代码。

  • 发送广播

//登录成功后的界面
public class LoginSuccessActivity extends BaseActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login_success);
        //当登录后的Activity添加到管理类中去
        ActivityController.addActivity(this);


    }

    //方法:强制下线(发布广播)
    public void outlogin(View view) {
            Intent intent=new Intent();
            intent.setAction("com.lxz.loginout");
            intent.addCategory("android.intent.category.DEFAULT");
           sendBroadcast(intent);
    }

}

(7)activity_login_success布局文件代码。

  • 有一个强制下线的按钮。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".LoginSuccessActivity">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="outlogin"
        android:text="强制下线"
        android:textSize="30dp" />
</LinearLayout>

(8)LoginOutReceiver广播接收器代码。

  • 设置一个Dialog用于弹窗
  • 我目前测试了本地广播和系统广播发现本地广播的context会报错,可能是因为进程号不统一导致的。

//强制下线的界面
public class LoginOutReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        AlertDialog.Builder builder=new AlertDialog.Builder(context);
        builder.setTitle("Error")
                .setMessage("您的账号在另外一台设备登录,程序即将回到登录界面!")
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ActivityController.finishAllActivity();
                        Toast.makeText(context, "退出成功!", Toast.LENGTH_SHORT).show();
                        Intent intent1=new Intent();
                        intent1.setClass(context,LoginActivity.class);
                        context.startActivity(intent1);
                    }
                })
                ;
                builder.create().show();    }
}

(9)效果图

1.3生命周期

1.3.1生命周期图

1.3.2onReceive注意事项

onReceive方法中不能加入比较耗时的操作,否则系统会认为程序无响应,不要在广播里添加过多逻辑或者进行任何耗时操作,因为在广播中是不允许开辟线程的, 当onReceiver( )方法运行较长时间(超过10秒)还没有结束的话,那么程序会报错(ANR), 广播更多的时候扮演的是一个打开其他组件的角色,比如启动Service,Notification提示, Activity等。如果需要完成一项比较耗时的工作,可以通过发送Intent给Activity或Service,由Activity或Service来完成。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/116244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

商业智能BI与业务结构分析

做商业智能BI还必须熟悉行业和业务知识&#xff0c;不结合行业业务知识&#xff0c;商业智能BI的项目是很难落地的。商业智能BI的本质其实是企业的业务和管理思维的落地。企业的高层、业务部门的管理人员为什么要通过商业智能BI去看报表&#xff0c;他们看的是什么&#xff0c;…

深度学习-吴恩达(C3)结构化你的机器学习工程

结构化你的机器学习工程改变了深度学习的错误 比如你分割数据的方法&#xff0c;分割成train&#xff0c;development(dev)或叫valid&#xff0c;test&#xff0c;所以最好的实践方法是什么&#xff1f;了解更多端对端的深度学习&#xff0c;进而了解到你是否需要使用它&#…

Elasticsearch 核心技术(三):Kibana 安装、配置、运行(Windows 版)

❤️ 个人主页&#xff1a;水滴技术 &#x1f680; 支持水滴&#xff1a;点赞&#x1f44d; 收藏⭐ 留言&#x1f4ac; &#x1f338; 订阅专栏&#xff1a;大数据核心技术从入门到精通 文章目录一、下载 Kibana二、安装 Kibana三、配置 Kibana1. 主机名2. 端口3. Elasticsea…

Spark基础入门----框架概述

Spark Spark 框架概述 Spark 诞生背景 Apache Spark是用于大规模数据处理的统一分析引擎 Spark 最早源于一片论文&#xff0c;该论文是由加州大学柏克莱分校的Matei Zaharia等人发表。论文中提出了一种弹性分布式数据集(RDD)的概念。 总的说&#xff0c;Spark借鉴了Map Red…

Android进阶——sdk开发和apk开发有什么区别?

sdk SDK 就是 Software Development Kit 的缩写&#xff0c;中文意思就是“软件开发工具包”。即辅助开发某一类软件的相关文档、范例和工具的集合都可以叫做“SDK”。 apk APK&#xff08;全称&#xff1a;Android application package&#xff0c;Android应用程序包&#…

【重学Javase】—— 数组(从头剖析一维数组,二维数组,array常用工具类以及数组的两种常见异常)

目录 数组的概述 1、数组的理解&#xff1a; 2、数组的特点&#xff1a; 3、数组的分类&#xff1a; 一维数组 1、一维数组的声明与初始化 2、一维数组元素的引用&#xff1a;通过角标的方式调用 3、数组的属性&#xff1a;length 4、一维数组的遍历&#xff08;for循…

mysql 备份还原数据库,java使用Runtime对象执行mysqldump备份数据库

为了提高系统可用性,通过java写定时任务每天晚上定时备份mysql数据库,然后把备份的.sql文件(建议在压缩一次上传,减少文件体积提高传输效率)调用文件上传服务器提供的文件上传接口上传到文件服务器,达到数据库服务器损坏后快速还原数据库的目的。以windows系统为例。linux注…

high-resolution image synthesis with latent diffusion models

如何通俗理解扩散模型&#xff1f; - 知乎泻药。实验室最近人人都在做扩散&#xff0c;从连续到离散&#xff0c;从CV到NLP&#xff0c;基本上都被diffusion洗了一遍。但是观察发现&#xff0c;里面的数学基础并不是模型应用的必须。其实大部分的研究者都不需要理解扩散模型的数…

理解linux虚拟网络设备veth

理解linux虚拟网络设备veth 上一章介绍了linux network namespace,接着来讨论一下如何让一个独立的网络命名空间的和主机的网络相互通信,这里我们需要用到linux虚拟网络设备veth。 veth设备 veth设备总是成对出现,通常就是用来连接不同网络命名空间(下面开始简称…

基于线性表的图书管理系统实验报告

目录 基于线性表的图书管理系统实验报告 1、成员分工 2、数据字典 3、抽象数据类型定义 4、图书存储结构描述 5、基本操作的算法描述 6、测试 6.1测试数据集 6.2测试程序运行结果截图 7、存在的问题与思考 基于线性表的图书管理系统实验报告 组长&#xff1a;xxx 组…

2022年学习机器人和人工智能的一些体会

前些日子开会&#xff0c;很受启发&#xff0c;比如有大佬指出&#xff1a; 总结&#xff1a;一般是高屋建瓴&#xff0c;通常是级别高的总揽全局&#xff0c;小虾虾不适用&#xff1b;感想和体会&#xff1a;小虾虾们学习完大佬讲话之后&#xff0c;自己的收获。 这才发现写博…

CRM能给企业带来什么价值

对于任何企业而言&#xff0c;客户都是企业生存下去的根本&#xff0c;管理客户也是企业一直在做的事情&#xff0c;有的企业尝试采用CRM来管理客户&#xff0c;有的企业还在观望CRM能给企业带来什么价值。 前言 对于任何企业而言&#xff0c;客户都是企业生存下去的根本&…

如何增加3d渲染的逼真感?提高3d渲染真实感的技巧

照片写实主义是一种艺术&#xff0c;它需要图形媒体来创造独特的艺术品&#xff0c;看起来非常有说服力。专业艺术家研究图像并使用照片写实技术从中创作艺术品。真实感可以在 2D 和 3D 渲染中实现&#xff0c;该过程称为真实感渲染。专业人士倾向于使用智能渲染过程&#xff0…

管理员权限功能和开机自启功能

前言 开机启动功能在Window下是很重要的一个功能&#xff0c;很多程序它都需要这样的功能 一.VS的配置选项&#xff08;以管理员权限启动程序&#xff09; 作用&#xff1a;用户在点击任务栏窗口等需要管理员权限时不会没有响应。 二.开机自启动&#xff08;注册表&#xff…

解决Navicat打开表的速度慢的问题

前言 最近使用Navicat打开表或者设计表都很慢&#xff0c;需要等十几秒才能打开&#xff0c;一开始我以为是我电脑老了&#xff0c;配置比较差&#xff0c;慢点就慢点吧&#xff0c;好像慢的也比较合理&#xff0c;想到这里我也就没有追究先忍了。 但是这几天公司给我配置的新…

PriorityQueue详解

目录标题前言PriorityQueue特点API构造操作API底层显示&#xff1a;数组offer(E e)前言 PriorityQueue是优先队列&#xff0c;作用是保证每次取出的元素都是队列中权值最小的&#xff0c;这里涉及到了大小关系&#xff0c;元素大小的评判可以通过元素自身的自然顺序&#xff0…

手把手教你搭建环境和内核编译

环境搭建--安装Debian7.3 本系列文章假设读者已对linux有一定的了解&#xff0c;其实学习linux内核不需要有很深的关于linux的知识&#xff0c;只需要了解以下内容&#xff1a;linux基础知识及基本shell命令&#xff1b;现代操作系统的基本概念&#xff1b;C语言和gcc基本使用…

Python操作数据库及Python实现mysql数据库连接池源代码

简介 pymysql&#xff1a;纯Python实现的一个驱动。因为是纯Python编写的&#xff0c;因此执行效率不如MySQL-python。并且也因为是纯Python编写的&#xff0c;因此可以和Python代码无缝衔接。 MySQL Connector/Python&#xff1a;MySQL官方推出的使用纯Python连接MySQL的驱动…

react-router-dom v6.5.0实现路由守卫RouterBeforeEach及缓存

一、概述 最近留意下react-router-dom有更新到6.6.1的版本&#xff0c;在这个版本增加了不少的功能。研究了下&#xff0c;可以利用其提供的API实现一个类似Vue的路由守卫&#xff0c;从而简便达到路由鉴权的业务场景。这里我是使用npm的包&#xff0c;是react-router-dom v6.5…

leetcode 124. 二叉树中的最大路径和-java题解

题目所属分类 二叉树的最大值 dfs 原题链接 路径 被定义为一条从树中任意节点出发&#xff0c;沿父节点-子节点连接&#xff0c;达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点&#xff0c;且不一定经过根节点。 路径和 是路径中…