当前位置: 首页 > news >正文

Android 权限(二): 动态权限讲解

1. 前言

        继上一篇文章说到Android权限汇总, 请移步笔者的文章Android 权限(一):权限大全_broadview_java的博客-CSDN博客_android 仅使用中允许权限

先要理清楚权限分类和定义,本篇文章继续说一下动态权限的申请和框架层的实现流程, 以及如何实现赋予系统应用默认的权限的需求.

2. 动态权限申请

        在Android6.0之后,  在首次打开app时的时候,比如微信,钉钉等软件时,会有提示

1)有读取设备上的照片及文字

2)获取手机号,IMEI,IMSI 

3)获取设备的定位信息 

等权限申请的对话框, 需要我们通过手动点击确认.

我们来一步一步分析对话框显示的原理和流程

2.1 检查权限

我们来通过一个Demo演示一下, Activity中的代码如下

public class MainActivity extends AppCompatActivity {private static final int REQUEST_CODE_TEST = 1024;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {if(this.checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {Toast.makeText(this, "请申请权限", Toast.LENGTH_LONG).show();//申请权限的代码// ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_TEST);requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_TEST);}}}//回调方法@Overridepublic void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {super.onRequestPermissionsResult(requestCode, permissions, grantResults);android.util.Log.e("test", "====int requestCode==== :" + requestCode+ " 具体的 permission :" + permissions[0] + "\n"+ "== grantResults数组长度 : " + grantResults.length + "====grantResults对应的int 值:" + grantResults[0]);}
}

代码讲解:

checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) 这个方法是检测是否有具有READ_EXTERNAL_STORAGE 此权限, 返回值 :

    /*** Permission check result: this is returned by {@link #checkPermission}* if the permission has been granted to the given package.*/public static final int PERMISSION_GRANTED = 0;/*** Permission check result: this is returned by {@link #checkPermission}* if the permission has not been granted to the given package.*/public static final int PERMISSION_DENIED = -1;

0:表示已获取该权限,  -1:表示未赋予该权限

我是用Android 10源码追溯的流程,我们来看看此代码的调用流程:

1. frameworks/base/core/java/android/content/ContextWrapper.java

    @Overridepublic int checkSelfPermission(String permission) {return mBase.checkSelfPermission(permission);}

2.frameworks/base/core/java/android/content/Context.java

    @PackageManager.PermissionResultpublic abstract int checkSelfPermission(@NonNull String permission);

3. 我们继续看看Context 的实现类 ContextImpl.java

frameworks/base/core/java/android/app/ContextImpl.java

    @Overridepublic int checkSelfPermission(String permission) {if (permission == null) {throw new IllegalArgumentException("permission is null");}return checkPermission(permission, Process.myPid(), Process.myUid());}

4.紧接着跳转到 ActivityManagerService.java中的方法

    @Overridepublic int checkPermission(String permission, int pid, int uid) {if (permission == null) {return PackageManager.PERMISSION_DENIED;}return checkComponentPermission(permission, pid, uid, -1, true);}public static int checkComponentPermission(String permission, int pid, int uid,int owningUid, boolean exported) {if (pid == MY_PID) {return PackageManager.PERMISSION_GRANTED;}return ActivityManager.checkComponentPermission(permission, uid,owningUid, exported);}

5.接着继续调用ActivityManager.java文件中的checkComponentPermission方法

public static int checkComponentPermission(String permission, int uid,int owningUid, boolean exported) {//省略......................try {return AppGlobals.getPackageManager().checkUidPermission(permission, uid);} catch (RemoteException e) {throw e.rethrowFromSystemServer();}}

6.继续调用到 PackageManagerService.java中的checkUidPermission方法

    public int checkUidPermission(String permName, int uid) {final CheckPermissionDelegate checkPermissionDelegate;synchronized (mPackages) {if (mCheckPermissionDelegate == null)  {return checkUidPermissionImpl(permName, uid);}checkPermissionDelegate = mCheckPermissionDelegate;}return checkPermissionDelegate.checkUidPermission(permName, uid,PackageManagerService.this::checkUidPermissionImpl);}private int checkUidPermissionImpl(String permName, int uid) {synchronized (mPackages) {final String[] packageNames = getPackagesForUid(uid);PackageParser.Package pkg = null;final int N = packageNames == null ? 0 : packageNames.length;for (int i = 0; pkg == null && i < N; i++) {pkg = mPackages.get(packageNames[i]);}return mPermissionManager.checkUidPermission(permName, pkg, uid, getCallingUid());}}

7. 接下来继续调用 PermissionManagerService.java去

        public int checkUidPermission(String permName, PackageParser.Package pkg, int uid,int callingUid) {return PermissionManagerService.this.checkUidPermission(permName, pkg, uid, callingUid);}//这里是最终返回判断值的方法
private int checkUidPermission(String permName, PackageParser.Package pkg, int uid,int callingUid) {final int callingUserId = UserHandle.getUserId(callingUid);final boolean isCallerInstantApp =mPackageManagerInt.getInstantAppPackageName(callingUid) != null;final boolean isUidInstantApp =mPackageManagerInt.getInstantAppPackageName(uid) != null;final int userId = UserHandle.getUserId(uid);if (!mUserManagerInt.exists(userId)) {return PackageManager.PERMISSION_DENIED;}if (pkg != null) {if (pkg.mSharedUserId != null) {if (isCallerInstantApp) {return PackageManager.PERMISSION_DENIED;}} else if (mPackageManagerInt.filterAppAccess(pkg, callingUid, callingUserId)) {return PackageManager.PERMISSION_DENIED;}final PermissionsState permissionsState =((PackageSetting) pkg.mExtras).getPermissionsState();if (permissionsState.hasPermission(permName, userId)) {if (isUidInstantApp) {if (mSettings.isPermissionInstant(permName)) {return PackageManager.PERMISSION_GRANTED;}} else {return PackageManager.PERMISSION_GRANTED;}}if (isImpliedPermissionGranted(permissionsState, permName, userId)) {return PackageManager.PERMISSION_GRANTED;}} else {ArraySet<String> perms = mSystemPermissions.get(uid);if (perms != null) {if (perms.contains(permName)) {return PackageManager.PERMISSION_GRANTED;}if (FULLER_PERMISSION_MAP.containsKey(permName)&& perms.contains(FULLER_PERMISSION_MAP.get(permName))) {return PackageManager.PERMISSION_GRANTED;}}}return PackageManager.PERMISSION_DENIED;}

这里是最终判断返回值的方法,  好了,到这里阶段一就完成了. 如果返回PERMISSION_GRANTED, 那没啥事情了, 如果返回PERMISSION_DENIED, 那你就得去动态申请了, 动态申请权限不多,就是固定的几组(在上一篇文章中以介绍说明).   android系统也为我们设计好了动态申请权限的对话框. 我们来说一下它的显示流程.

2.2 申请权限

申请权限是requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, REQUEST_CODE_TEST)方法实现的

1. 跳转到Activity.java中的requestPermissions方法

frameworks/base/core/java/android/app/Activity.java

    public final void requestPermissions(@NonNull String[] permissions, int requestCode) {if (requestCode < 0) {throw new IllegalArgumentException("requestCode should be >= 0");}if (mHasCurrentPermissionsRequest) {Log.w(TAG, "Can request only one set of permissions at a time");// Dispatch the callback with empty arrays which means a cancellation.onRequestPermissionsResult(requestCode, new String[0], new int[0]);return;}//创建跳转的目标activityIntent intent = getPackageManager().buildRequestPermissionsIntent(permissions);startActivityForResult(REQUEST_PERMISSIONS_WHO_PREFIX, intent, requestCode, null);mHasCurrentPermissionsRequest = true;}

2. 注意一下此段代码:buildRequestPermissionsIntent(permissions)

frameworks/base/core/java/android/content/pm/PackageManager.java

    @NonNull@UnsupportedAppUsagepublic Intent buildRequestPermissionsIntent(@NonNull String[] permissions) {if (ArrayUtils.isEmpty(permissions)) {throw new IllegalArgumentException("permission cannot be null or empty");}Intent intent = new Intent(ACTION_REQUEST_PERMISSIONS);intent.putExtra(EXTRA_REQUEST_PERMISSIONS_NAMES, permissions);intent.setPackage(getPermissionControllerPackageName());return intent;}
@SystemApi
public static final String ACTION_REQUEST_PERMISSIONS ="android.content.pm.action.REQUEST_PERMISSIONS";

通过这个ACTION跳转到对应的activity中,  通过在源码工程下全局搜索 然后找到对应的Activity, 我们发现是GrantPermissionsActivity.java

        <activity android:name="com.android.packageinstaller.permission.ui.GrantPermissionsActivity"android:configChanges="keyboardHidden|screenSize"android:excludeFromRecents="true"android:theme="@style/GrantPermissions"android:visibleToInstantApps="true"android:inheritShowWhenLocked="true"><intent-filter android:priority="1"><action android:name="android.content.pm.action.REQUEST_PERMISSIONS" /><category android:name="android.intent.category.DEFAULT" /></intent-filter></activity>

确定是唯一的,出现这个界面对话框时,我们也可以通过adb shell dumpsys window | grep mFocus

命令确定一下Activity找的是不是对的.

知识储备: 在Android(<=9)版本上, 动态申请权限的对话框是集成在 packages/apps/PackageInstaller 模块中, 在Android(>=10)版本上,是在packages/apps/PermissionController中,单独把这块拿出来了

3. 对话框事件处理是在GrantPermissionsViewHandlerImpl.java中,   允许,拒绝, 仅在使用该应用时允许  对应的代码如下:

    @Overridepublic void onClick(View view) {switch (view.getId()) {case R.id.permission_allow_button:if (mResultListener != null) {view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);mResultListener.onPermissionGrantResult(mGroupName, GRANTED_ALWAYS);}break;case R.id.permission_allow_always_button:if (mResultListener != null) {view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);mResultListener.onPermissionGrantResult(mGroupName, GRANTED_ALWAYS);}break;case R.id.permission_allow_foreground_only_button:if (mResultListener != null) {view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);mResultListener.onPermissionGrantResult(mGroupName,GRANTED_FOREGROUND_ONLY);}break;case R.id.permission_deny_button:if (mResultListener != null) {view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);mResultListener.onPermissionGrantResult(mGroupName, DENIED);}break;case R.id.permission_deny_and_dont_ask_again_button:if (mResultListener != null) {view.performAccessibilityAction(AccessibilityNodeInfo.ACTION_CLEAR_ACCESSIBILITY_FOCUS, null);mResultListener.onPermissionGrantResult(mGroupName,DENIED_DO_NOT_ASK_AGAIN);}break;case R.id.permission_more_info_button:Intent intent = new Intent(Intent.ACTION_MANAGE_APP_PERMISSIONS);intent.putExtra(Intent.EXTRA_PACKAGE_NAME, mAppPackageName);intent.putExtra(Intent.EXTRA_USER, mUserHandle);intent.putExtra(ManagePermissionsActivity.EXTRA_ALL_PERMISSIONS, true);mActivity.startActivity(intent);break;}}

3. 赋予应用默认运行时权限

        有些用户觉得app要申请权限比较麻烦,就有定制软件默认就赋予某个应用运行时权限,不弹出对话框,我们看看怎么修改呢?

   先来看frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java中的systemReady()方法

        // If we upgraded grant all default permissions before kicking off.for (int userId : grantPermissionsUserIds) {mDefaultPermissionPolicy.grantDefaultPermissions(userId);}

跳转到DefaultPermissionGrantPolicy.java中

    public void grantDefaultPermissions(int userId) {grantPermissionsToSysComponentsAndPrivApps(userId);//默认赋予应用的运行时权限grantDefaultSystemHandlerPermissions(userId);grantDefaultPermissionExceptions(userId);synchronized (mLock) {mDefaultPermissionsGrantedUsers.put(userId, userId);}}

 如下这些代码,就是默认赋予运行时权限的地方

 private void grantDefaultSystemHandlerPermissions(int userId) {..................// Downloads providergrantSystemFixedPermissionsToSystemPackage(getDefaultProviderAuthorityPackage("downloads", userId), userId,STORAGE_PERMISSIONS);// Downloads UIgrantSystemFixedPermissionsToSystemPackage(getDefaultSystemHandlerActivityPackage(DownloadManager.ACTION_VIEW_DOWNLOADS, userId),userId, STORAGE_PERMISSIONS);// Storage providergrantSystemFixedPermissionsToSystemPackage(getDefaultProviderAuthorityPackage("com.android.externalstorage.documents", userId),userId, STORAGE_PERMISSIONS);// CertInstallergrantSystemFixedPermissionsToSystemPackage(getDefaultSystemHandlerActivityPackage(Credentials.INSTALL_ACTION, userId), userId,STORAGE_PERMISSIONS);// Dialerif (dialerAppPackageNames == null) {String dialerPackage =getDefaultSystemHandlerActivityPackage(Intent.ACTION_DIAL, userId);grantDefaultPermissionsToDefaultSystemDialerApp(dialerPackage, userId);} else {for (String dialerAppPackageName : dialerAppPackageNames) {grantDefaultPermissionsToDefaultSystemDialerApp(dialerAppPackageName, userId);}}// Sim call managerif (simCallManagerPackageNames != null) {for (String simCallManagerPackageName : simCallManagerPackageNames) {grantDefaultPermissionsToDefaultSystemSimCallManager(simCallManagerPackageName, userId);}}// Use Open Wifiif (useOpenWifiAppPackageNames != null) {for (String useOpenWifiPackageName : useOpenWifiAppPackageNames) {grantDefaultPermissionsToDefaultSystemUseOpenWifiApp(useOpenWifiPackageName, userId);}}// 添加代码,赋予应用默认的运行时权限,不弹出申请对话框.grantPermissionsToSystemPackage("com.android.mytestapp", userId, STORAGE_PERMISSIONS);}

如果你想添加自己的应用默认赋予运行时权限的话,可以这样子修改,如下:

添加包名 和 运行时权限数组

grantPermissionsToSystemPackage("com.android.mytestapp", userId, STORAGE_PERMISSIONS);

相关文章:

Android 权限(二): 动态权限讲解

1. 前言 继上一篇文章说到Android权限汇总, 请移步笔者的文章Android 权限(一)&#xff1a;权限大全_broadview_java的博客-CSDN博客_android 仅使用中允许权限 先要理清楚权限分类和定义,本篇文章继续说一下动态权限的申请和框架层的实现流程, 以及如何实现赋予系统应用默认的…...

【C++】2.类和对象(上)

1.面向过程和面向对象 C语言是面向过程的&#xff0c;关注的是过程&#xff0c;分析出求解问题的步骤&#xff0c;通过函数调用逐步解决问题。C是基于面向对象的&#xff0c;关注的是对象&#xff0c;将一件事情拆分成不同的对象&#xff0c;靠对象之间的交互完成。 2.类的引入…...

扬帆优配|3300点半日游!上证指数冲高回落;再迎重磅利好!

今天早盘&#xff0c;A股冲高回落&#xff0c;上证指数3300点得而复失&#xff0c;深证成指也于12000点无功而返。 盘面上&#xff0c;煤炭、钢铁、房地产、才智政务等板块涨幅居前&#xff0c;酿酒、酒店餐饮、日用化工、IT设备等板块跌幅居前。北上资金净流入7.77亿元。 房地…...

如何编写性能测试计划?一篇文章教你设计符合项目的性能测试计划

上篇文章&#xff0c;我们讲过性能测试计划&#xff0c;接下来我们就来讲讲如何设计符合项目的性能测试计划。到上篇为止&#xff0c;我们了解了性能测试计划中包含的内容&#xff0c;但是&#xff0c;这个颗粒度&#xff0c;我觉得作为一名测试经验不够丰富的性能工程师来说&a…...

第3章 Windows 下安装 Memcached教程

官网上并未提供 Memcached 的 Windows 平台install 包&#xff0c;咱们可以使用以下链接来download &#xff0c;需要根据自己的去下载&#xff1a; 点击下载 在 1.4.5 版本以前 memcached 可以作为一个服务install &#xff0c;而在 1.4.5 及之后的版本删除了该功能。因此咱…...

RXjava中的操作符

要使用Rxjava首先要导入两个包&#xff0c;其中rxandroid是rxjava在android中的扩展 implementation io.reactivex:rxandroid:1.2.1implementation io.reactivex:rxjava:1.2.0Rxjava中的操作符 创建型操作符 interval 创建一个按固定时间间隔发射整数序列的Observable&#xf…...

前端页面jquery规范写法

使用最新版本的 jQuery 最新版本的 jQuery 会改进性能和增加新功能,若不是为了兼容旧浏览器,建议使用最新版本的 jQuery。以下是三条常见的 jQuery 语句,版本越新,性能越好: $(.elem) $(.elem, context) context.find(.elem) 结果 1.6.2 版执行次数远超两个老版本。 jQ…...

【HEC-RAS水动力】HEC-RAS 1D基本原理(恒定流及非恒定流)

一、数据说明 HEC-RAS模型主要由工程文件 (.prj) 文 件 、 河道地形数据文件 ( .g01)、运行文件(p01)、非恒定流文件 ( .u01) 等部分组成。 1. 一般数据 在创建并保存project文件(*.prj)后,其他data文件均会自动以同样的名字保存,但采用不同的后缀来区分各类文件。 &qu…...

2.Gin内容介绍

目录 参考 主要内容 关于Web 创建项目 为什么要用框架 Gin框架介绍 Gin框架安装与使用 安装 第一个Gin示例&#xff1a; RESTful API Gin渲染 HTML渲染 自定义模板函数 静态文件处理 使用模板继承 补充文件路径处理 JSON渲染 XML渲染 YMAL渲染 protobuf渲染…...

python--matplotlib(3)

前言 Matplotlib画图工具的官网地址是 http://matplotlib.org/ Python环境下实现Matlab制图功能的第三方库&#xff0c;需要numpy库的支持&#xff0c;支持用户方便设计出二维、三维数据的图形显示&#xff0c;制作的图形达到出版级的标准。 其他matplotlib文章 python--matpl…...

从源码中探究React中的虚拟DOM

引文 通过本文你将了解到 什么是虚拟DOM&#xff1f;虚拟DOM有什么优势&#xff1f;React的虚拟Dom是如何实现的&#xff1f;React是如何将虚拟Dom转变为真实Dom&#xff1f; 一、概念 虚拟DOM实际上是一种用来模拟DOM结构的javascript对象。当页面变化的时候通过一种算法来…...

容器架构概述

文章目录1. 介绍容器历史2. 描述 Linux 容器架构3. Podman 管理容器1. 介绍容器历史 近年来&#xff0c;容器迅速流行起来。然而&#xff0c;容器背后的技术已经存在了相对较长的时间。2001年&#xff0c;Linux引入了一个名为VServer的项目。VServer 是第一次尝试在高度隔离的…...

掌握MySQL分库分表(四)分库分表中间件Sharding-Jdbc,真实表、逻辑表、绑定表、广播表,常见分片策略

文章目录什么是ShardingSphere-JDBC&#xff1f;Sharding-Jdbc常见概念术语数据节点Node真实表逻辑表绑定表广播表数据库表分片&#xff08;水平库、表&#xff09;分片键 (PartitionKey)行表达式分片策略 InlineShardingStrategy&#xff08;必备&#xff09;标准分片策略Stan…...

2022-06-16_555时基的迷人历史和先天缺陷!

https://www.eet-china.com/news/magazine220608.html 555时基的迷人历史和先天缺陷&#xff01; 发布于2022-06-16 03:39:12 LARRY STABILE 流行数十年的555时基&#xff0c;业内不知晓的工程师应该寥寥无几&#xff01;几乎所有的数字电路教材中&#xff0c;都有该芯片的身影…...

SpringBoot 基础知识汇总

一、环境准备Java&#xff1a;Spring Boot 3.0.2 需要 Java 17&#xff0c;并且与 Java 19 兼容Maven&#xff1a;Apache Maven 3.5 或更高版本兼容二、启动器以下应用程序启动器由 Spring Boot 在该组下提供&#xff1a;org.springframework.boot表 1.Spring 引导应用程序启动…...

centos7下用kvm启动Fedora36 Cloud镜像

环境 os:centos7 Arch: aarch64 安装qemu-kvm yum install qemu-kvm kvm virt-install libvirt systemctl start libvirtd.service创建镜像 下载aarch64架构的Fedora36镜像 wget https://mirrors.tuna.tsinghua.edu.cn/fedora/releases/36/Cloud/aarch64/images/Fedora-Cl…...

修复 K8s SSL/TLS 漏洞(CVE-2016-2183)指南

作者&#xff1a;老 Z&#xff0c;中电信数智科技有限公司山东分公司运维架构师&#xff0c;云原生爱好者&#xff0c;目前专注于云原生运维&#xff0c;云原生领域技术栈涉及 Kubernetes、KubeSphere、DevOps、OpenStack、Ansible 等。 前言 测试服务器配置 主机名IPCPU内存系…...

uniapp 引入彩色symbol和 指令权限

uniapp 引入iconfont图标库彩色symbol 1&#xff0c;先去阿里巴巴矢量图标库登录 然后点击下载至本地 2.下载本地&#xff0c;然后解压文件夹 3.打开终端cmd命令窗口 npm安装全局包npm i -g iconfont-tools 4.终端切换到上面解压的文件夹里面&#xff0c;运行iconfont-too…...

【C语言】初识结构体

Yan-英杰 悟已往之不谏 知来者之可追 目录 一、结构体的声明 二、结构体变量的定义和初始化 三、结构体成员的访问 四、结构体传参 一、结构体的声明 1.结构的基础知识 结构是一些值的集合&#xff0c;这些值称为成员变量。结构的每个成员可以是不同类型的变量。2.结构的…...

前端将base64图片转换成file文件

1、base64转成file具体代码 // base64图片转file的方法&#xff08;base64图片, 设置生成file的文件名&#xff09;function base64ToFile(base64, fileName) {// 将base64按照 , 进行分割 将前缀 与后续内容分隔开let data base64.split(,);// 利用正则表达式 从前缀中获取图…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

python/java环境配置

环境变量放一起 python&#xff1a; 1.首先下载Python Python下载地址&#xff1a;Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个&#xff0c;然后自定义&#xff0c;全选 可以把前4个选上 3.环境配置 1&#xff09;搜高级系统设置 2…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI&#xff0c;使用客户端或是内部自己搭建集成大模型的终端&#xff0c;加速与大型语言模型&#xff08;LLM&#xff09;的结合&#xff0c;同时使用检索增强生成&#xff08;Retrieval Augmented Generation &#…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...