Android框架源码,AccessibilityButtonController.java文件,简单的解读一下

news/发布时间2024/5/29 4:55:41

源码路径

https://cs.android.com/android/platform/superproject/main/+/main:frameworks/base/core/java/android/accessibilityservice/AccessibilityButtonController.java?hl=zh-cn
代码如下:

package android.accessibilityservice;import android.annotation.NonNull;
import android.os.Handler;
import android.os.Looper;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.Slog;import java.util.Objects;public final class AccessibilityButtonController {private static final String LOG_TAG = "A11yButtonController";private final IAccessibilityServiceConnection mServiceConnection;private final Object mLock;private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {mServiceConnection = serviceConnection;mLock = new Object();}public boolean isAccessibilityButtonAvailable() {if (mServiceConnection != null) {try {return mServiceConnection.isAccessibilityButtonAvailable();} catch (RemoteException re) {Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);re.rethrowFromSystemServer();return false;}}return false;}public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {registerAccessibilityButtonCallback(callback, new Handler(Looper.getMainLooper()));}public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,@NonNull Handler handler) {Objects.requireNonNull(callback);Objects.requireNonNull(handler);synchronized (mLock) {if (mCallbacks == null) {mCallbacks = new ArrayMap<>();}mCallbacks.put(callback, handler);}}public void unregisterAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {Objects.requireNonNull(callback);synchronized (mLock) {if (mCallbacks == null) {return;}final int keyIndex = mCallbacks.indexOfKey(callback);final boolean hasKey = keyIndex >= 0;if (hasKey) {mCallbacks.removeAt(keyIndex);}}}void dispatchAccessibilityButtonClicked() {final ArrayMap<AccessibilityButtonCallback, Handler> entries;synchronized (mLock) {if (mCallbacks == null || mCallbacks.isEmpty()) {Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");return;}// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent// modification.entries = new ArrayMap<>(mCallbacks);}for (int i = 0, count = entries.size(); i < count; i++) {final AccessibilityButtonCallback callback = entries.keyAt(i);final Handler handler = entries.valueAt(i);handler.post(() -> callback.onClicked(this));}}void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {final ArrayMap<AccessibilityButtonCallback, Handler> entries;synchronized (mLock) {if (mCallbacks == null || mCallbacks.isEmpty()) {Slog.w(LOG_TAG,"Received accessibility button availability change with no callbacks!");return;}// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent// modification.entries = new ArrayMap<>(mCallbacks);}for (int i = 0, count = entries.size(); i < count; i++) {final AccessibilityButtonCallback callback = entries.keyAt(i);final Handler handler = entries.valueAt(i);handler.post(() -> callback.onAvailabilityChanged(this, available));}}public static abstract class AccessibilityButtonCallback {public void onClicked(AccessibilityButtonController controller) {}public void onAvailabilityChanged(AccessibilityButtonController controller,boolean available) {}}
}

源码分析

    private static final String LOG_TAG = "A11yButtonController";private final IAccessibilityServiceConnection mServiceConnection;private final Object mLock;private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks;AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) {mServiceConnection = serviceConnection;mLock = new Object();}
  • private static final String LOG_TAG = "A11yButtonController"; 这一行定义了一个私有的、静态的、最终的字符串变量,它的值是"A11yButtonController",用于作为日志的标签。私有的意思是只有这个类自己可以访问这个变量,静态的意思是这个变量不属于任何对象,而是属于这个类,最终的意思是这个变量的值不能被修改。
  • private final IAccessibilityServiceConnection mServiceConnection; 这一行定义了一个私有的、最终的接口类型的变量,它的值是一个实现了IAccessibilityServiceConnection接口的对象,用于表示一个无障碍服务的连接。私有的意思是只有这个类自己可以访问这个变量,最终的意思是这个变量的值不能被修改,但是这个对象的属性可以被修改。
  • private final Object mLock; 这一行定义了一个私有的、最终的对象类型的变量,它的值是一个Object对象,用于作为一个锁对象,用于保护临界区的同步。私有的意思是只有这个类自己可以访问这个变量,最终的意思是这个变量的值不能被修改,但是这个对象的属性可以被修改。
  • private ArrayMap<AccessibilityButtonCallback, Handler> mCallbacks; 这一行定义了一个私有的数组映射类型的变量,它的值是一个ArrayMap对象,用于存储无障碍按钮的回调函数和处理器的键值对。私有的意思是只有这个类自己可以访问这个变量,这个变量的值可以被修改,也就是可以添加或删除键值对。
  • AccessibilityButtonController(@NonNull IAccessibilityServiceConnection serviceConnection) { 这一行定义了一个构造函数,它的参数是一个非空的IAccessibilityServiceConnection类型的对象,用于初始化这个类的对象。
  • mServiceConnection = serviceConnection; 这一行是构造函数的一条语句,它的作用是将参数serviceConnection的值赋给变量mServiceConnection,也就是初始化这个类的无障碍服务连接。
  • mLock = new Object(); 这一行是构造函数的另一条语句,它的作用是创建一个新的Object对象,并将其赋给变量mLock,也就是初始化这个类的锁对象。
    public boolean isAccessibilityButtonAvailable() {if (mServiceConnection != null) {try {return mServiceConnection.isAccessibilityButtonAvailable();} catch (RemoteException re) {Slog.w(LOG_TAG, "Failed to get accessibility button availability.", re);re.rethrowFromSystemServer();return false;}}return false;}
  • 这个方法的名字是isAccessibilityButtonAvailable,它的返回值类型是布尔型,也就是true或false,它的作用是判断无障碍按钮是否可用。
  • 这个方法的第一行是一个if语句,它的条件是mServiceConnection不等于null,也就是说,如果这个类的无障碍服务连接对象存在,那么就执行if语句的代码块,否则就执行return false语句,也就是返回无障碍按钮不可用的结果。
  • if语句的代码块是一个try-catch语句,它的作用是处理可能发生的异常情况。try语句的代码块是一条return语句,它的作用是调用mServiceConnection对象的isAccessibilityButtonAvailable方法,并将其返回值作为这个方法的返回值,也就是说,如果mServiceConnection对象能够正常地判断无障碍按钮是否可用,那么就返回它的判断结果。
  • catch语句的代码块是用来捕获RemoteException类型的异常,也就是说,如果mServiceConnection对象在调用isAccessibilityButtonAvailable方法的过程中发生了远程通讯的错误,那么就执行catch语句的代码块。catch语句的代码块有三条语句,它们的作用分别是:
    • 调用Slog类的w方法,用来打印一条警告级别的日志信息,表示获取无障碍按钮可用性失败,并将异常对象re作为参数传递,用来显示异常的详细信息。
    • 调用异常对象re的rethrowFromSystemServer方法,用来将异常重新抛出,让系统服务处理。
    • 返回false,表示无障碍按钮不可用。

总之,这个方法的作用是判断无障碍按钮是否可用,它的逻辑是先检查无障碍服务连接对象是否存在,然后尝试调用它的方法来获取无障碍按钮的可用性,如果发生异常,就打印日志,重新抛出异常,并返回false。

public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {registerAccessibilityButtonCallback(callback, new Handler(Looper.getMainLooper()));}
  • 这个方法的名字是registerAccessibilityButtonCallback,它的参数是一个非空的AccessibilityButtonCallback类型的对象,它的返回值类型是void,也就是没有返回值,它的作用是注册一个无障碍按钮的回调函数。
  • 这个方法的第一行是一条方法调用语句,它的作用是调用AccessibilityButtonController类的另一个重载的方法,也叫registerAccessibilityButtonCallback,但是它的参数有两个,分别是一个AccessibilityButtonCallback类型的对象和一个Handler类型的对象。这个方法调用语句的参数是callback和new Handler(Looper.getMainLooper()),也就是说,它将传入的callback对象和一个新创建的Handler对象作为参数传递给另一个方法。
  • 这个方法的逻辑是利用了方法重载的特性,也就是说,同一个类中可以有多个同名但是参数不同的方法,这样可以提供不同的功能或者简化方法的调用。这个方法的作用是提供了一个简化的方法调用,让用户只需要传入一个callback对象,就可以注册一个无障碍按钮的回调函数,而不需要自己创建一个Handler对象。Handler对象的作用是用来处理消息或者运行任务,Looper对象的作用是用来管理消息队列,getMainLooper方法的作用是获取主线程的Looper对象,也就是说,这个方法调用语句创建了一个与主线程关联的Handler对象,用来处理无障碍按钮的回调函数。

总之,这个方法的作用是注册一个无障碍按钮的回调函数,它的逻辑是调用另一个同名但是参数不同的方法,简化了方法的调用,让用户不需要自己创建一个Handler对象。

    public void registerAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback,@NonNull Handler handler) {Objects.requireNonNull(callback);Objects.requireNonNull(handler);synchronized (mLock) {if (mCallbacks == null) {mCallbacks = new ArrayMap<>();}mCallbacks.put(callback, handler);}}
  • 这个方法的名字是registerAccessibilityButtonCallback,它的参数是两个非空的对象,一个是AccessibilityButtonCallback类型的,一个是Handler类型的,它的返回值类型是void,也就是没有返回值,它的作用是注册一个无障碍按钮的回调函数和一个处理器。
  • 这个方法的第一行和第二行是两条方法调用语句,它们的作用是调用Objects类的requireNonNull方法,分别对callback和handler对象进行非空检查,如果有任何一个对象为空,就抛出一个空指针异常,这样可以保证参数的有效性。
  • 这个方法的第三行是一个同步语句,它的作用是使用mLock对象作为锁,保证同一时间只有一个线程可以执行同步语句的代码块,这样可以避免多线程的并发问题。
  • 同步语句的代码块是一个if语句和一条方法调用语句,它们的作用是:
    • if语句的条件是mCallbacks等于null,也就是说,如果这个类的数组映射对象不存在,那么就执行if语句的代码块,否则就跳过。
    • if语句的代码块是一条赋值语句,它的作用是创建一个新的ArrayMap对象,并将其赋给变量mCallbacks,也就是初始化这个类的数组映射对象。
    • 方法调用语句的作用是调用mCallbacks对象的put方法,将参数callback和handler作为键值对添加到数组映射中,也就是注册一个无障碍按钮的回调函数和处理器。

总之,这个方法的作用是注册一个无障碍按钮的回调函数和处理器,它的逻辑是先对参数进行非空检查,然后使用一个锁对象进行同步,再判断是否需要初始化数组映射对象,最后将参数添加到数组映射中。

    public void unregisterAccessibilityButtonCallback(@NonNull AccessibilityButtonCallback callback) {Objects.requireNonNull(callback);synchronized (mLock) {if (mCallbacks == null) {return;}final int keyIndex = mCallbacks.indexOfKey(callback);final boolean hasKey = keyIndex >= 0;if (hasKey) {mCallbacks.removeAt(keyIndex);}}}
  • 这个方法的名字是unregisterAccessibilityButtonCallback,它的参数是一个非空的AccessibilityButtonCallback类型的对象,它的返回值类型是void,也就是没有返回值,它的作用是取消注册一个无障碍按钮的回调函数。
  • 这个方法的第一行是一条方法调用语句,它的作用是调用Objects类的requireNonNull方法,对callback对象进行非空检查,如果对象为空,就抛出一个空指针异常,这样可以保证参数的有效性。
  • 这个方法的第二行是一个同步语句,它的作用是使用mLock对象作为锁,保证同一时间只有一个线程可以执行同步语句的代码块,这样可以避免多线程的并发问题。
  • 同步语句的代码块是一个if语句和一个if-else语句,它们的作用是:
    • if语句的条件是mCallbacks等于null,也就是说,如果这个类的数组映射对象不存在,那么就执行return语句,也就是直接结束这个方法,不做任何操作。
    • if-else语句的条件是hasKey等于true,也就是说,如果数组映射中存在以callback为键的键值对,那么就执行if语句的代码块,否则就执行else语句的代码块。
    • if语句的代码块是一条方法调用语句,它的作用是调用mCallbacks对象的removeAt方法,将参数keyIndex作为索引,从数组映射中删除对应的键值对,也就是取消注册一个无障碍按钮的回调函数。
    • else语句的代码块是空的,也就是不做任何操作。

总之,这个方法的作用是取消注册一个无障碍按钮的回调函数,它的逻辑是先对参数进行非空检查,然后使用一个锁对象进行同步,再判断是否需要从数组映射中删除对应的键值对。

    void dispatchAccessibilityButtonClicked() {final ArrayMap<AccessibilityButtonCallback, Handler> entries;synchronized (mLock) {if (mCallbacks == null || mCallbacks.isEmpty()) {Slog.w(LOG_TAG, "Received accessibility button click with no callbacks!");return;}// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent// modification.entries = new ArrayMap<>(mCallbacks);}for (int i = 0, count = entries.size(); i < count; i++) {final AccessibilityButtonCallback callback = entries.keyAt(i);final Handler handler = entries.valueAt(i);handler.post(() -> callback.onClicked(this));}}
  • 这个方法的名字是dispatchAccessibilityButtonClicked,它的参数是空的,它的返回值类型是void,也就是没有返回值,它的作用是分发无障碍按钮的点击事件给已注册的回调函数。
  • 这个方法的第一行是一条变量声明语句,它的作用是声明一个数组映射类型的变量,它的值是空的,用于存储回调函数和处理器的键值对。
  • 这个方法的第二行是一个同步语句,它的作用是使用mLock对象作为锁,保证同一时间只有一个线程可以执行同步语句的代码块,这样可以避免多线程的并发问题。
  • 同步语句的代码块是一个if语句和一条赋值语句,它们的作用是:
    • if语句的条件是mCallbacks等于null或者mCallbacks为空,也就是说,如果这个类的数组映射对象不存在或者没有任何键值对,那么就执行if语句的代码块,否则就跳过。
    • if语句的代码块是一条方法调用语句和一条return语句,它们的作用是:
      • 调用Slog类的w方法,用来打印一条警告级别的日志信息,表示收到了无障碍按钮的点击事件,但是没有任何回调函数。
      • 返回,也就是直接结束这个方法,不做任何操作。
    • 赋值语句的作用是用mCallbacks对象的构造函数,创建一个新的ArrayMap对象,并将其赋给变量entries,也就是对mCallbacks对象进行一个浅拷贝,避免在后续的操作中发生并发修改的问题。
  • 这个方法的第三行是一个for循环语句,它的作用是遍历entries对象中的所有键值对,执行相应的操作。for循环语句的条件是i小于count,其中i是一个整型变量,初始值为0,每次循环后自增1,count是一个整型变量,它的值是entries对象的大小,也就是键值对的个数。
  • for循环语句的代码块是三条变量声明语句和一条方法调用语句,它们的作用是:
    • 第一条变量声明语句的作用是声明一个AccessibilityButtonCallback类型的变量,它的值是entries对象中以i为索引的键,也就是一个回调函数对象。
    • 第二条变量声明语句的作用是声明一个Handler类型的变量,它的值是entries对象中以i为索引的值,也就是一个处理器对象。
    • 第三条变量声明语句的作用是声明一个Runnable类型的变量,它的值是一个Lambda表达式,它的作用是调用回调函数对象的onClicked方法,并将这个类的对象作为参数传递,也就是执行回调函数的逻辑。
    • 方法调用语句的作用是调用处理器对象的post方法,并将Runnable对象作为参数传递,也就是将Runnable对象添加到处理器对象的消息队列中,等待执行。

总之,这个方法的作用是分发无障碍按钮的点击事件给已注册的回调函数,它的逻辑是先检查数组映射对象是否存在或为空,然后使用一个锁对象进行同步,再对数组映射对象进行浅拷贝,最后遍历数组映射对象中的所有键值对,通过处理器对象执行回调函数对象的逻辑。

  void dispatchAccessibilityButtonAvailabilityChanged(boolean available) {final ArrayMap<AccessibilityButtonCallback, Handler> entries;synchronized (mLock) {if (mCallbacks == null || mCallbacks.isEmpty()) {Slog.w(LOG_TAG,"Received accessibility button availability change with no callbacks!");return;}// Callbacks may remove themselves. Perform a shallow copy to avoid concurrent// modification.entries = new ArrayMap<>(mCallbacks);}for (int i = 0, count = entries.size(); i < count; i++) {final AccessibilityButtonCallback callback = entries.keyAt(i);final Handler handler = entries.valueAt(i);handler.post(() -> callback.onAvailabilityChanged(this, available));}}
  • 这个方法的名字是dispatchAccessibilityButtonAvailabilityChanged,它的参数是一个布尔型的变量,它的值表示无障碍按钮是否可用,它的返回值类型是void,也就是没有返回值,它的作用是分发无障碍按钮的可用性变化事件给已注册的回调函数。
  • 这个方法的第一行是一条变量声明语句,它的作用是声明一个数组映射类型的变量,它的值是空的,用于存储回调函数和处理器的键值对。
  • 这个方法的第二行是一个同步语句,它的作用是使用mLock对象作为锁,保证同一时间只有一个线程可以执行同步语句的代码块,这样可以避免多线程的并发问题。
  • 同步语句的代码块是一个if语句和一条赋值语句,它们的作用是:
    • if语句的条件是mCallbacks等于null或者mCallbacks为空,也就是说,如果这个类的数组映射对象不存在或者没有任何键值对,那么就执行if语句的代码块,否则就跳过。
    • if语句的代码块是一条方法调用语句和一条return语句,它们的作用是:
      • 调用Slog类的w方法,用来打印一条警告级别的日志信息,表示收到了无障碍按钮的可用性变化事件,但是没有任何回调函数。
      • 返回,也就是直接结束这个方法,不做任何操作。
    • 赋值语句的作用是用mCallbacks对象的构造函数,创建一个新的ArrayMap对象,并将其赋给变量entries,也就是对mCallbacks对象进行一个浅拷贝,避免在后续的操作中发生并发修改的问题。
  • 这个方法的第三行是一个for循环语句,它的作用是遍历entries对象中的所有键值对,执行相应的操作。for循环语句的条件是i小于count,其中i是一个整型变量,初始值为0,每次循环后自增1,count是一个整型变量,它的值是entries对象的大小,也就是键值对的个数。
  • for循环语句的代码块是三条变量声明语句和一条方法调用语句,它们的作用是:
    • 第一条变量声明语句的作用是声明一个AccessibilityButtonCallback类型的变量,它的值是entries对象中以i为索引的键,也就是一个回调函数对象。
    • 第二条变量声明语句的作用是声明一个Handler类型的变量,它的值是entries对象中以i为索引的值,也就是一个处理器对象。
    • 第三条变量声明语句的作用是声明一个Runnable类型的变量,它的值是一个Lambda表达式,它的作用是调用回调函数对象的onAvailabilityChanged方法,并将这个类的对象和参数available作为参数传递,也就是执行回调函数的逻辑。
    • 方法调用语句的作用是调用处理器对象的post方法,并将Runnable对象作为参数传递,也就是将Runnable对象添加到处理器对象的消息队列中,等待执行。

总之,这个方法的作用是分发无障碍按钮的可用性变化事件给已注册的回调函数,它的逻辑是先检查数组映射对象是否存在或为空,然后使用一个锁对象进行同步,再对数组映射对象进行浅拷贝,最后遍历数组映射对象中的所有键值对,通过处理器对象执行回调函数对象的逻辑。

 public static abstract class AccessibilityButtonCallback {public void onClicked(AccessibilityButtonController controller) {}public void onAvailabilityChanged(AccessibilityButtonController controller,boolean available) {}}
  • 这个类的名字是AccessibilityButtonCallback,它是一个抽象的静态的类,它的作用是定义一个无障碍按钮的回调函数的接口,让其他类可以继承它并实现它的方法,以便在无障碍按钮的点击事件或可用性变化事件发生时,执行相应的逻辑。
  • 这个类的第一行是一个类修饰符,它包含了三个关键字:public,static,abstract,它们的含义分别是:
    • public的意思是这个类是公开的,也就是说,任何其他的类都可以访问这个类。
    • static的意思是这个类是静态的,也就是说,这个类不属于任何对象,而是属于AccessibilityButtonController类,可以直接通过AccessibilityButtonController.AccessibilityButtonCallback来引用这个类,而不需要创建一个AccessibilityButtonController对象。
    • abstract的意思是这个类是抽象的,也就是说,这个类不能被实例化,也就是不能用new关键字创建一个对象,而只能被其他的类继承,并实现它的抽象方法。
  • 这个类的第二行和第三行是两个方法定义,它们都是公开的、抽象的方法,它们的作用是声明两个无障碍按钮的回调函数的接口,让其他类可以根据自己的需求重写它们,它们的名字和参数分别是:
    • onClicked,它的参数是一个AccessibilityButtonController类型的对象,它的作用是在无障碍按钮被点击时,执行相应的逻辑,比如启动一个无障碍服务或者执行一个无障碍操作。
    • onAvailabilityChanged,它的参数是一个AccessibilityButtonController类型的对象和一个布尔型的变量,它的作用是在无障碍按钮的可用性发生变化时,执行相应的逻辑,比如更新无障碍按钮的状态或者提示用户无障碍按钮的可用性。

总之,这个类的作用是定义一个无障碍按钮的回调函数的接口,它的逻辑是声明两个抽象的方法,让其他类可以继承它并实现它的方法,以便在无障碍按钮的事件发生时,执行相应的逻辑。

最后的归纳总结

AccessibilityButtonController.java 这个文件是 Android 框架的一部分,它提供了一个控制器类,用于管理系统导航区域中的辅助功能按钮。这个类的主要逻辑和作用如下:

  • 构造方法:接受一个 IAccessibilityServiceConnection 的参数,用于与辅助功能服务进行通信。
  • isAccessibilityButtonAvailable:返回一个布尔值,表示辅助功能按钮是否对调用服务可用。
  • registerAccessibilityButtonCallback:注册一个 AccessibilityButtonCallback 的回调,用于接收辅助功能按钮的交互和状态变化的通知。可以指定一个 Handler 来指定回调执行的线程。
  • unregisterAccessibilityButtonCallback:取消注册一个已经注册的 AccessibilityButtonCallback 的回调。
  • dispatchAccessibilityButtonClicked:分发辅助功能按钮点击事件给所有注册的回调。这个方法应该在服务的主线程上调用。
  • dispatchAccessibilityButtonAvailabilityChanged:分发辅助功能按钮可用性变化事件给所有注册的回调。这个方法应该在服务的主线程上调用。
  • AccessibilityButtonCallback:一个抽象类,定义了两个方法,分别在辅助功能按钮被点击和可用性变化时被调用。子类可以覆盖这些方法来实现自己的逻辑。

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

如若内容造成侵权/违法违规/事实不符,请联系编程老四网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

微信小程序开发(实战案例):本地生活 - 列表页面开发(动态渲染处理)、节流防抖(节流阀应用)

文章目录 本地生活 - 列表页面开发一、将九宫格分类换成navigator组件二、动态设置商品列表页的 title三、动态渲染商品列表页面四、上拉触底加载数据五、添加Loading加载效果六、数据加载节流防抖处理 本地生活 - 列表页面开发 导入我们上次写的 本地生活 - 首页开发的项目 运…

算法------(12)Trie树(字典树)

例题&#xff1a;&#xff08;1&#xff09;Acwing 835. Trie字符串统计 Trie树是一个可以高效存储查询字符串的数据结构。将一个字符串的每一个字符作为一个根节点&#xff0c;从字符串头到字符串尾连接起来。因此我们可以把每一个字符串存储为一个节点&#xff0c;记录其子节…

【软件测试】定位前后端bug总结+Web/APP测试分析

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、Web测试中简单…

2024年全国乙卷高考文科数学备考:历年选择题真题练一练(2014~2023)

今天距离2024年高考还有三个多月的时间&#xff0c;今天我们来看一下2014~2023年全国乙卷高考文科数学的选择题&#xff0c;从过去十年的真题中随机抽取5道题&#xff0c;并且提供解析。后附六分成长独家制作的在线练习集&#xff0c;科学、高效地反复刷这些真题&#xff0c;吃…

go 1.18 不同目录package引用问题

go 1.18开始使用module了 不同的package在vs code中引用的话 需要先开启 是Go1.11版本之后 推出的版本管理工具 有点类似java的 maven工具 可以引入依赖使用 go env -w GO111MODULEon 先把这个打开 然后在创建的vs code工作目录下 执行 module gomdoule module 模块名 会生…

微服务篇之负载均衡

一、Ribbon负载均衡流程 二、Ribbon负载均衡策略 1. RoundRobinRule&#xff1a;简单轮询服务列表来选择服务器。 2. WeightedResponseTimeRule&#xff1a;按照权重来选择服务器&#xff0c;响应时间越长&#xff0c;权重越小。 3. RandomRule&#xff1a;随机选择一个可用的服…

常用的消息中间件RabbitMQ

目录 一、消息中间件 1、简介 2、作用 3、两种模式 1、P2P模式 2、Pub/Sub模式 4、常用中间件介绍与对比 1、Kafka 2、RabbitMQ 3、RocketMQ RabbitMQ和Kafka的区别 二、RabbiMQ集群 RabbiMQ特点 RabbitMQ模式⼤概分为以下三种: 集群中的基本概念&#xff1a; 集…

使用 ES|QL 优化可观察性:简化 Kubernetes 和 OTel 的 SRE 操作和问题解决

作者&#xff1a;Bahubali Shetti 作为一名运营工程师&#xff08;SRE、IT 运营、DevOps&#xff09;&#xff0c;管理技术和数据蔓延是一项持续的挑战。 简单地管理大量高维和高基数数据是令人难以承受的。 作为单一平台&#xff0c;Elastic 帮助 SRE 将无限的遥测数据&#…

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测

分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测 目录 分类预测 | Matlab实现KPCA-ISSA-LSSVM基于核主成分分析和改进的麻雀搜索算法优化最小二乘支持向量机故障诊断分类预测分类效果基本描述程序设计参考资…

JSON:简介与基本使用

目录 什么是JSON&#xff1f; JSON的基本结构 JSON的基本使用 在JavaScript中使用JSON 创建JSON对象 解析JSON字符串 生成JSON字符串 在其他编程语言中使用JSON 总结 什么是JSON&#xff1f; JSON&#xff0c;全称为JavaScript Object Notation&#xff0c;是一种轻量…

XFF伪造 [MRCTF2020]PYWebsite1

打开题目 直接查看源码 看到一个./flag.php 访问一下 购买者的ip已经被记录&#xff0c;本地可以看到flag&#xff0c;那么使用xff或者client-ip伪造一下ip试试 bp抓包 加一个X-Forwarded-For头 得到flag

docker pullpush 生成镜像文件并push 到阿里云

pull docker docker pull ultralytics/ultralytics # 拉取yolov8的镜像仓库 docker run -it ultralytics/ultralytics # 运行镜像 conda create -n gsafety python3.8 # 创建环境 source activate gsafety # 激活环境 pip install -i https://pypi.tuna.tsinghua.edu.cn/simp…

【YOLO系列算法人员摔倒检测】

YOLO系列算法人员摔倒检测 模型和数据集下载YOLO系列算法的人员摔倒检测数据集可视化数据集图像示例&#xff1a; 模型和数据集下载 yolo行人跌倒检测一&#xff1a; 1、训练好的行人跌倒检测权重以及PR曲线&#xff0c;loss曲线等等&#xff0c;map达90%多&#xff0c;在行人跌…

二.西瓜书——线性模型、决策树

第三章 线性模型 1.线性回归 “线性回归”(linear regression)试图学得一个线性模型以尽可能准确地预测实值输出标记. 2.对数几率回归 假设我们认为示例所对应的输出标记是在指数尺度上变化&#xff0c;那就可将输出标记的对数作为线性模型逼近的目标&#xff0c;即 由此&…

一、网络基础知识

1、IP地址和端口号 1.1、IP地址 定义&#xff1a;用于在网络中唯一标识设备的地址。格式&#xff1a;通常由四个数字组成&#xff0c;以点分十进制表示&#xff0c;例如&#xff1a;192.168.0.1。(IPv4)作用&#xff1a;允许网络中的设备相互通信&#xff0c;通过IP地址可以定…

Word第一课

文章目录 1. 文件格式1.1 如何显示文件扩展名1.2 Word文档格式的演变1.3 常见的Word文档格式 3. 文档属性理解文档属性查看文档属性 4. 显示比例方式一&#xff1a; 手动调整方式二&#xff1a; 自动调整 5. 视图、窗口视图 1. 文件格式 1.1 如何显示文件扩展名 文档格式指的…

ThreadLocal“你”真的了解吗?(二)

《ThreadLocal“你”真的了解吗&#xff1f;&#xff08;一&#xff09;》这篇文章梳理了ThreadLocal的基础知识&#xff0c;同时还梳理了java中线程的创建方法以及这两者之间的关系&#xff0c;本篇文章我们将继续梳理与ThreadLocal相关&#xff0c;在上一节也提过的另一组件T…

什么是负载均衡集群?

目录 1、集群是什么&#xff1f; 2、负载均衡集群技术 3、负载均衡集群技术的实现 4、实现效果如图 5、负载均衡分类 6、四层负载均衡&#xff08;基于IP端口的负载均衡&#xff09; 7、七层的负载均衡&#xff08;基于虚拟的URL或主机IP的负载均衡) 8、四层负载与七层…

板块一 Servlet编程:第八节 文件上传下载操作 来自【汤米尼克的JavaEE全套教程专栏】

板块一 Servlet编程&#xff1a;第八节 文件的上传下载操作 一、文件上传&#xff08;1&#xff09;前端内容&#xff08;2&#xff09;后端内容 二、文件下载&#xff08;1&#xff09;前端的超链接下载&#xff08;2&#xff09;后端下载 在之前的内容中我们终于结束了Servle…

C语言每日一题(61)盛最多水的容器

题目链接 力扣 11 盛最多水的容器 题目描述 给定一个长度为 n 的整数数组 height 。有 n 条垂线&#xff0c;第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。 找出其中的两条线&#xff0c;使得它们与 x 轴共同构成的容器可以容纳最多的水。 返回容器可以储存的最大水…
推荐文章