Android LBS

article/2025/9/20 9:31:18

前言

本文以项目AOSP的源码为参考,描述基于Android的定位服务的实现流程,包括GPS定位,网络定位,GeoCoder等服务。以代码执行流程为主线,一步步分析定位的实现流程。由于Android Binder采用C/S的架构模式,所以本文中就以客户端和服务器来称呼服务获取实体和服务实体。
定位流程图如下:

这里写图片描述
图 1-1

APP Layer Service

在使用user location之前,先了解如下一些概念:

  1. 多路定位
    位置提供者可以是GPS、WiFi、Cell-ID等,它们对定位的精度、速度、能耗等各不相同。

  2. 用户移动
    由于用户可能是在不断的移动,所以需要不断更新用户的位置。

  3. 定位频率
    位置提供者按照指定的频率向位置需求者报告定位数据。

1.1 获取定位服务

得到用户位置,首先要获取LocationManager对象,该对象可以通过getSystemService(Context.LOCATION_SERVICE)获取,如图1-1所以。

这里写图片描述

上图所以,获得LocationManager对象实例locationManager,调用该对象的requestLocationUpdates()方法注册位置更新。该方法需要传递指定位置提供者、最小时间间隔报告位置、最小移动距离报告位置以及被回调的LocationListener。

1.2 权限需求

从NETWORK_PROVIDER 或者GPS_PROVIDER获取位置更新,需要ACCESS_COARSE_LOCATION或者ACCESS_FINE_LOCATION 权限,如果同时用到NETWORK_PROVIDER 和GPS_PROVIDER,仅需要ACCESS_–FINE_LOCATION权限即可,因为该权限包含NETWORK_PROVIDER的权限。
到此,注册位置监听已完成,当有报告位置等变化时,LocationManager回调LocationListener方法。

Frameworks Layer Service

2.1 LocationListener分析

承接上文,分析LocationListener,这是非常简单的一个过程,代码实现也非常简洁,下图所示。

这里写图片描述
图 2-1

上图中,LocationManager回调onLocationChanged()方法,报告位置数据,传递参数Location对象,接着看Location类

这里写图片描述
图 2-2

位置信息被封装到Location的对象中,开发者便可从该对象中提取数据。其它回调方法也比较简单,读者可自行阅读。Location对象的创建过程将在下文中分析。

2.2 LocationManager分析

在本文1.1中提到获取LocationManager对象,该对象实际是怎样操作定位的呢?下面,将深入分析。

2.2.1 LocationManager对象的实例化

以读者阅读源码的嗅觉,LocationManager对象通过get–SystemService(Context.LOCATION_SERVICE)方法获取,可知实际上这是一个基于Android Binder机制的C/S架构。通过阅读Activity的实例化过程可知道该过程会注册一系列的Service,读者如果对这一过程不了解,可自行先阅读相关知识。Service的注册过程在ContextImpl中实现,看下图。

这里写图片描述
图 2-3

上述代码中,ContextImpl实例化时,会注册LocationManager服务,ServiceManager.getService(LOCATION_SERVICE)方法通过Binder机制获取IBinder对象,如果读者不清楚ServiceManager、Binder、IBinder这一个过程,这是一件槽糕的事情,读者需要先行阅读Android Binder机制的知识。继续跟踪阅读ServiceManager.getService(LOCATION_SERVICE)中的LOCATION_SERVICE,如下图。

这里写图片描述
图 2-4

LOCATION_SERVICE的值是从Context中继承的,和getSystemService(Context.LOCATION_SERVICE)中的Context.LOC–ATION_SERVICE是指向同一个变量,因此,客户端和服务器端通过LOCATION_SERVICE关联,从图2-1中创建LocationManager对象可知,客户端对象被封装在LocationManager对象中。关于客户端和服务器端将在下文中进行分析。

小节总结

本小节谈论到Android LBS服务实现基于Binder机制,Location–Manager通过封装客户端对象,从而实现对服务器端的操作。

2.2.2 注册位置服务

获取到LocationManager对象的实例后,在1.1节中,该实例通过如下方式注册LocationListener监听位置变化。

这里写图片描述
图 2-5

跟踪LocationManager的requestLocationUpdates方法,直接看代码。

这里写图片描述
图 2-6

该方法中,会创建一个LocationRequest的实例,不妨再看看LocationRequest是干什么用的,如下图

这里写图片描述
图 2-7

LocationRequest的实例创建过程非常简单,封装一些参数,是一个数据类型对象,这个对象携带的数据最终会传到Service使用,下文将会分析。
继续往下分析注册监听位置的过程,LocationRequest对象实例化完成后,调用如下方法

这里写图片描述
图 2-8

该方法的详情如下图

这里写图片描述
图 2-9

此过程会把LocationListener对象和ListenerTransport对象进行一个转换,把LocationListener对象保存到ILocationListener对象中。其中ILocationListener的实现过程也是通过Binder机制,也就是说LocationManager通过Binder请求服务,ListenerTransport通过Binder返回结果,感兴趣的读者可自行阅读。接着代码会调用mService的requestLocationUpdates方法,mService又是个什么东东呢?看下图

这里写图片描述
图 2-10

mService实质是一个ILocationManager对象,ILocationManager对象是做什么的呢?又是在什么时候被实例化的呢?前面2.2.1 中LocationManager对象的实例化过程中,如下图

这里写图片描述
图 2-11

继续查看LocationManager的构造方法,如下图

这里写图片描述
图 2-12

上图可见,在实例化LocationManager时mService被赋值,而从图2-11可知,mService实质是一个客户端对象,通过IBinder句柄从服务器端获取相对应的服务,对于ILocationManager.Stub.asInterface不了解的读者,可以自行先了解Android Binder机制。

本节小结

到此LocationManager的注册位置服务过程已经结束。在LocationManager的实现过程非常简单,实例化一些定位相关的对象后,最终调用客户端对象以服务器端就行交互。

2.2.3 Binder通信过程

上文提到mService调用requestLocationUpdates方法,通过Binder机制的原理可知,mService实质是ILocationManager.Stub.Proxy的对象实例,mService调用requestLocationUpdates方法实质是调用Proxy的requestLocationUpdates方法,查看该方法的实现如下图

这里写图片描述
图 2-13

这里写图片描述
图 2-14

Note:图2-13和图2-14是一个方法中的内容。
该方法接收一个LocationRequest对象和一个ILocationListener对象,这两个对象实例在上文中都有描述,通过request.writeToParcel方法将LocationRequest的实例中的数据转化到Parcel对象中,从而实现Java和C/C++通过JNI进行数据对象的转换。最终调用mRemote.transact方法把_data和_reply推送到底层,同时传递Stub.TRANSACTION_requestLocationUpdates参数,这个参数在后续内容用到,读者暂行记住。mRemote.transact方法后会推送数据到Binder驱动,触发相应的服务,如果读者不了解这个过程,可自行先了解Binder机制原理。

本节小结

本节描述了请求位置变化的Binder通信过程,LocationRequest和ILocationListener的转化过程,最终触发相应的服务器端,下面将分析服务器端的实现。

2.3 LocationManagerService的创建过程

在Android启动的过程中,会初始化一系列服务,这些服务运行在system_process进程中,如果读者不了解这个过程,可自行学习Android启动流程分析和Binder机制的知识。在SystemServer中初始化LocationManagerService,如下图

这里写图片描述
图 2-15

实例化LocationManagerService后,通过Service–Manager.addService方法把定位管理服务添加到service manager管理,注意Context.LOCATION_SERVICE参数,正好与上文中的2.2.1和2.2.2中的参数对应,所以LocationManager实质是与Location–ManagerService通过Binder进行通信。

2.3.1 LocationManagerService的实例化

LocationManagerService的实例化非常简单,如下图

这里写图片描述
图 2-16

LocationManagerService的实例化只是实例化一个AppOpsManager对象对应用进行跟踪,如果读者感兴趣可自行了解AppOpsManager的功能。

2.3.2 实例化Location Provider

LocationManagerService服务初始化完成后,将会继续执行下图的代码

这里写图片描述
图 2-17

locationF是LocationManagerService的对象,查看systemRunning方法,如下图

这里写图片描述
图 2-18

该方法中会创建LocationWorkerHandler对象,如下图

这里写图片描述
图 2-19

LocationWorkerHandler是一个工作线程,处理GPS Provider和Network Provider位置变化发送的message,这个处理过程在后面的内容再进行描述。接着调用loadProvidersLocked加载location provider(下文简称LP),过程如下

这里写图片描述
图 2-20

1) GpsLocationProvider
Gps LP是GPS定位Java层的最后通道,该LP创建过程非常简单
看看构造函数

这里写图片描述
图 2-21

这里写图片描述
图 2-22

这里写图片描述
图 2-23

首先是加载GPS设备的配置,启动ProviderHandler接收LP的数据变化报告,监听SUPL的数据短信或WAP_PUSH。配置加载分两种,一种是Android默认的配置,如下图

这里写图片描述
图 2-24

当然,实质上更多的是用设备厂商的配置,如下图

这里写图片描述
图 2-25

配置数据一般就是SUPL的相关参数,这些参数是为后面AGPS定位服务,主要包括SUPL的服务器地址以及端口号。配置数据加载完毕后,会调用setSuplHostPort方法,如下图

这里写图片描述
图 2-26

最终通过JNI调用本地代码,native_set_agps_server的方法如下

这里写图片描述
图 2-27

上图可以看到,sAGpsInterface不为空时,调用该对象的set_server函数,把agps参数传递给gps driver。关于sAGpsInterface将在下文中赘述。
图 2-23中提到listenForBroadcasts方法中会接收处理发往127.0.0.1:7275的数据短信和mime类型为application/vnd.–omaloc-supl-init的WAP_PUSH,收到信息后在Broadcast中处理,处理过程如下

这里写图片描述
图 2-28

接收到Intents.DATA_SMS_RECEIVED_ACTION)或Intents.WAP_–PUSH_RECEIVED_ACTION时分别调用checkSmsSuplInit(intent)和checkWapSuplInit(intent),如下图

这里写图片描述
图 2-29

两个方法最终统一调用native_agps_ni_message,再看看该函数

这里写图片描述
图 2-30

最后也是调用sGpsNiInterface接口,和上文提到的sAGpsInterface同理,都是HAL与gps driver的通道,在下文在赘述它们。到此可见,SUPL数据的初始化通过Data SMS或WAP_PUSH的方式来实现。上文提到数据短信接收来此127.0.0.1:7275的消息,关于7275端口可参考OMA-SUPL的协议。
到此GpsLocationProvider的构造方法基本分析完毕,但是该lP的初始化还没有完成,因为还有一个static方法,如下图

这里写图片描述
图 2-31

该方法只调用本地的函数,该函数的部分截图如下

这里写图片描述
图 2-32

这里写图片描述
图 2-33

这里写图片描述
图 2-34

从图2-32到图2-34,init_native主要实现三个功能,第一个加载本地代码回调Java的方法,用于底层向上层报告定位的服务,其中报告位置变化的方法为reportLocation,这一过程在下文定位流程中分析。第二个过程是GPS定位中非常关键的一步,首先是通过hw_get_module函数加载GPS模块,GPS_HARDWARE_MODULE_ID的值是“gps”,了解Android的HAL可知,JNI通过HAL的hw_get_module函数建立JNI与HAL的通道,加载硬件模块代码,接着调用GPS模块的open函数打通HAL与硬件驱动的通道device,然后通过get_gps_interface函数返回sGpsInterface的对象,GpsInterface在HAL的gps.h中定义,如下图

这里写图片描述
图 2-35

到此可见,取得sGpsInterface对象,HAL与GPS driver的位置服务通道完全打通,sGpsInterface初始化完成后,如图2-34,将会加载sGpsInterface扩展功能,例如sAgpsInterface,这些Interface和sGpsInterface一样,都是HAL与driver通信的通道,实现不同的功能。

2)LocationProviderProxy
上文论述到GpsLocationProvider初始化的过程,下面将阐述网络LP(LocationProviderProxy)的初始化,从名字上可知这是代理设计模式,那么可以让Android不需要知道当前定位用的是什么网络定位方式,不管是WiFi,GSM,CDMA等等都可以实现定位。下面看LocationProviderProxy的创建过程,如下图:

这里写图片描述
图 2-36

上图中NetWork Provider并不像Gps Provider那样new出一个对象,而是调用static的createAndBind方法,方法中会传递一个Handler的对象,该对象实质是LocationWorkerHandler,和Gps LP一样,会接收后面位置变化的Message。倒数第二个参数config_locationProviderPackageNames,指定了Network Location的提供者,看下图

<string-array name="config_locationProviderPackageNames" translatable="false"><!-- The standard AOSP fused location provider --><item>com.android.location.fused</item><item>com.google.android.gms</item><item>com.amap.android.ams</item><item>com.baidu.location.fused</item>
</string-array>

图 2-37

可知,上图中配置了LP为com.android.location.fused、com.google.android.gms、com.baidu.map.location,这三个包名是怎样和系统NetWork LP以及LMS建立通信并提供服务呢?接着看createAndBind方法。

这里写图片描述
图 2-37

该方法很简单,直接new一个LocationProviderProxy对象,生成LPProxy后调用bind方法,该方法很重要,后面再析它,先看Location–ProviderProxy的实例化做了些什么,如下图

这里写图片描述
图 2-38

构造方法里面又创建了一个ServiceWatcher对象mService–Watcher,该对象很重要,是LPProxy和上面图2-37提到的应用通信的桥梁,ServiceWatcher实现了ServiceConnection接口,ServiceWatcher实现了什么功能呢,下面来分析它

这里写图片描述
图 2-39

初始化很简单,所做内容就是把传进来的包名取出来放到一个ArrayList对象initialPackageNames中。回到图2-38中,LPProxy和ServiceWatcher初始化完成后,执行bind方法,接着执行Service–Watcher的start方法,start方法部分代码如下:

这里写图片描述
图 2-40

接着调用bindBestPackageLocked方法,该方法主要实现目标应用程序的(图 2-37中的程序)的检测,检测成功后,调用bind–ToPackageLocked方法,方法实现如下

这里写图片描述
图 2-41

该方法是bind的最后执行方法,这个方法最重要,从上图可以看到,packageName是目标应用程序的包名,mAction是createAndBind方法的第三个参数,参数值为com.android.location.–service.v3.NetworkLocationProvider,然后调用bindServerAsUser方法,至此,网络定位LP的实现思路非常清晰了,网络LP实质提供的数据的是第三方应用,这些应用必须有一个Service,且该Service的名字必须是com.android.location.service.v3.NetworkLocationProvider。上文有提到ServiceWatcher实现了ServiceConnection接口,由Android Service组件可知,bindServerAsUser连接服务成功后,会回调ServiceConnection的onServiceConnected,直接上该方法的实现

这里写图片描述
图 2-42

该方法的代码很少,主要功能是把binder赋值给ServiceWatcher的变量mBinder,并执行Runnable mNewServiceWork,mNewService–Work在调用createAndBind时由倒数第二个参数传入,mNewServiceWork的实现如下

这里写图片描述
图 2-43

这里写图片描述
图 2-44

图2-44声明一个ILocationProvider对象servive,该对象通过调用getService方法实例化,看看getService的实现

这里写图片描述
图 2-45

这里写图片描述
图 2-46

由图2-43可知,mBinder对象是onServiceConnected方法回调的IBinder对象,由图2-46可知,通过句柄IBinder返回一个ILocation–Provider对象实例,到此,可知,目标应用程序的Service不仅必须命名为com.android.location.service.v3.NetworkLocationProvider,且必须有实现ILocationProvider的对象实例,LPProxy通过句柄IBinder获取到的ILocationProvider对象实例,通过Binder机制和应用程序端的ILocationProvider进行通信,这就是我们熟悉的Binder机制了。继续看mNewServiceWork的实现,图2-45中可以看到,ILocationProvider的实例service调用setRequest方法请求位置服务,ILocationProvider和Android的LocationProviderInterface一样,关于setRequest的作用在下文中分析。

本节小结

至此,Gps LP和NetWork LP的实现到此已经结束,回顾内容,Gps LP在初始化时做了很多底层操作,实现过程尤为复杂,主要是打开HAL和芯片通道,检测GPS芯片,初始化芯片,设置定位参数,开始定位。LocationProviderProxy实现LBS服务过程先绑定应用程序的服务,通过服务返回的句柄IBinder,通过句柄获取目标应用程序的ILocationProvider的对象实例,通过该对象实例向目标程序发送LBS服务请求,然后通过WorkSource实现数据报告,最终传送给上层应用程序。

2.4 定位流程在LocationManagerService中的过程

到这里,GPS LP和NetWork LP的创建和运行阐述完毕了,LP的叙述边幅这么长,不知读者是否还记得2.3节前面的内容,上层应用调用requestLocationUpdates到图2-14的mRemote.transact后,通过binder驱动,触发服务,最终执行到服务器端的onTransact方法,如下图(下面的代码是通过Binder机制运行在不同的进程中)

这里写图片描述
图 2-47

这里写图片描述
图 2-48

Note:图2-15和图2-16是一个方法中的内容
不知读者是否记得上面提到的Stub.TRANSACTION–_requestLocationUpdates参数,所以最终会执行图2-16中case TRANSACTION_requestLocationUpdates的代码。上图中的Location–Request正是LocationManager通过Binder传过来的LocationRequest对象实例,ILocationListener也正是上层应用传递过来的对象实例,从本地代码经过对象转换后,调用LocationManagerService的requestLocationUpdates方法, 最终会执行如下代码

这里写图片描述
图 2-49

这里写图片描述
图 2-50

接着调用LocationProviderListener的setRequest方法,和LocationProviderProxy中提到ILocationProvider实现一样,下面将以GpsLocationProvider为例阐述setRequest的工作过程。直接看代码

这里写图片描述
图 2-51

这里进行一个转发,最终执行下面的代码

这里写图片描述
图 2-52

继续往下看代码

这里写图片描述
图 2-53

匹配GPS定位的方式,然后调用本地的native_set_position_mode把定位模式和参数设置到GPS芯片,如下图

这里写图片描述
图 2-54

在上文提到Gps模块的初始化,在这里设置了定位模式,终于可以调用本地的native_start启动GPS芯片进行定位了,看本地的native_start的实现过程,如下

这里写图片描述
图 2-55

上文中有提到参数在本地方法的初始化,所以调用native_start时,实质执行了android_location_GpsLocationProvider_start的方法,sGpsInterface在GpsLocationProvider的创建过程中有阐述,是HAL和GPS驱动的通道,然后调用sGpsInterface的start方法开始定位,关于定位的过程,是硬件厂商不公开的代码,这些代码在上文中打开GPS模块时HAL加载gps模块的so库。定位成功后会回调location_callback函数,如下

这里写图片描述
图 2-56

在这里会回调到Java代码,如图method_reportLocation会回调到Java的什么方法呢,在上文GpsLocationProvider的创建过程的初始化是有提到,如图2-32,method_reportLocation函数调用实质是调用了Java的reportLocation方法,该方法如下

这里写图片描述
图 2-57

这里写图片描述
图 2-58

然后包定位的数据封装到Location的对象mLocation中,通过mILocationManager的reportLocation方法,mILocationManager是ILocationManager对象实例,该实例在GpsLocationProvider创建时被实例化,上文提到,GpsLocationProvider的创建过程在LocationManagerService中开始,回顾GpsLocationProvider的new过程,如下图

这里写图片描述
图 2-59

上图中的this对象正是mILocationManager的实例,所以,reportLocation.reportLocation是执行LocationManagerService的reportLocation方法,如下

这里写图片描述
图 2-60

这里在再把Locaton对象传出去,mLocationHandler在上文中有描述,以一个工作线程,是LocationWorkerHandler的对象,接收位置的变化。再经过一些处理和判断,最终执行下面的代码

这里写图片描述
图 2-61

上图中mListener正是上层应用通过Binder传送过来的ILocationListener对象实例,然后调用该对象的onLocationChanged方法,即通过Binder回调到图1-1中的方法。

本节小结

Gps定位到此终于结束,本节描述了上层应用通过发送定位请求到LocationManagerService后,LocationManagerService通过GpsLocationProvider调用GPS芯片进行定位的过程。

3 总结

本文详细描述了Android定位的过程,从APP层获取定位的方法,到Frameworks层,在通过Binder机制,连接到LocationManagerService,通过LP获取定位的数据,然后通过层层回调到APP层的过程。通过上文可知,GPS的定位在GpsLocationProvider就可以完成,然而网络定位是依赖第三方应用,实际中设备更多的是用到融合定位,即网络和GPS同时进行定位,这样可以提高定位速度和精度。在GPS定位中,目前大多设备并不是用标准的GPS模式进行定位,而是用AGPS来提高定位的速度和精度。上文中定位过程只是取得经纬度、海拔、速度、精度等数据,然而我们生活中更多的是用地理编码(道路、街道、邮政编号等)来描述位置,GeoCoder正是可以实现把GPS定位的数据转换成生活中通俗的表示。当然,实际中人们使用的都是地图类的应用,当用户看到地图上自己的位置时,地图应用可能已经做了很多工作,包括定位,GeoCoder,POI等众多服务。
感谢读者的信赖,由于作者知识有限,如发现文中有错误的地方,欢迎及时提出来以便更正!


http://chatgpt.dhexx.cn/article/1nNO9MO4.shtml

相关文章

LSB和MSB,LSB first,MSBfirst

LSB LSB(Least Significant Bit)–最低有效位 MSB MSB(Most Significant Bit)–最高有效位 解释 加入下面是一个四位二进制的数值&#xff0c;一般和10进制都认为是左边是最高位&#xff0c;也就是MSB;对应的最右边就是LSB. LSB first和MSB first 这种一般出现先对传感…

OSPF,LSDB,LSA分类

dis cur c ospf //查看OSPF的配置 DD报文选举的是主从关系&#xff0c;不是选举DR和BDR LSA通告网段信息和通告拓扑信息 two-way&#xff1a;双向通信&#xff0c;邻居状态下&#xff0c;选举DR和BDR 进入exstar状态&#xff0c;发送第一个DD报文&#xff0c;DD报文的作用是…

IS-IS P2P网络下LSDB同步过程

P2P链路下IS-IS的LSDB数据库同步过程 抓包如下&#xff1a; 大概过程: IS-IS在P2P网络中邻居建立完成后只发送一次CSNP报文 双方都会发送一次CSNP&#xff0c;包含LSP的摘要信息&#xff0c;意思是告诉对方我有哪些网段信息如果其中一方的LSDB中没有对方的CSNP内的某条路由&a…

【OSPF-一类router、二类network】(根据lsdb画出拓扑)

目录 一、一类LSA-Router 每台交换机会产生一条类型为router的lsa&#xff0c;来描述自身直连网段信息&#xff08;通过dis ospf lsdb&#xff0c;查看router的条目&#xff0c;就能确定该区域内路由器的数目了&#xff09; 查看ospf相关信息的命令 二、二类lsa-network 由…

ISIS—ISIS中LSP(数据库)同步如何保证LSDB可靠性—04

目录 一、LSP基础知识&#xff1a;(链路状态更新&#xff0c;相当于OSPF的LSA) 二、ISIS中LSP&#xff08;数据库&#xff09;同步如何保证LSDB可靠性? ISIS LSP&#xff08;数据库&#xff09;同步机制 ①P2P网络&#xff1a; ②MA网络&#xff1a; ③特例问题&#xf…

【LAB4-Cisco】OSPF邻居建立过程与LSDB分析

实验需求 1、根据拓扑提示&#xff0c;对各路由启用OSPF路由协议并划分相应区域&#xff0c;并验证邻居关系以及数据库信息&#xff0c;从而保证内网全网互通。其中&#xff0c;要求R7上的回环口条目作为外部条目引进来。 2、新加入公司网络的Area 2 区域存在一定的接入安全隐患…

IS-IS LSDB详解(华为设备)

概述&#xff1a; IS-IS协议主要有两大功能&#xff1a;子网依赖功能和子网无关功能。子网依赖功能就是建立和维护邻接关系的功能&#xff0c;而子网无关功能则主要用于执行和管理和管理链路状态信息的交换和路由计算&#xff0c;具体可以分为四个过程。 更新过程。路由决策过…

1.1.6 LSDB同步

邻接关系 邻接建立过程 讲完了报文之后我们具体来看一下是怎么同步的&#xff0c;我们可以看到下图是我们LSDB的过程&#xff1a; 注意&#xff1a; 我们要注意&#xff0c;在到达同步过程之前我们先要达到2-way的状态&#xff0c;就是我们首先要有邻居状态的建立&#xff0c;才…

网络篇 OSPF的LSDB过载保护-52

目录 一、实验原理 二、实验拓扑 三、实验步骤 四、实验过程 总结 实验难度 2 实验复杂度3 一、实验原理 若没有正确规划网络或配置不好&#xff0c;可能出现大量的LSA&#xff0c;这些LSA会消耗掉本地的CPU和内存资源的。在Cisco IOS 12.3(7)和更晚的版本中&#xff0…

OSPF之链路状态数据库LSDB

OSPF链路状态数据库 原理概述&#xff1a; OSPF是一种基于链路状态的动态路由协议&#xff0c;每台 OSPF 路由器都会生成相关的LSA&#xff0c;并将这些LSA通告出去。路由器收到LSA后&#xff0c;会将它们存放在链路状态数据库LSDB中。 LSA有多种不同的类型&#xff0c;不同类型…

ORACLE生成自增唯一序列值的函数

“F_NEXT_VAL” 函数名 VAL 变量值 PRAGMA AUTONOMOUS_TRANSACTION 声明为自治事务 CREATE OR REPLACE FUNCTION "F_NEXT_VAL" RETURN INTEGER ASpragma autonomous_transaction;VAL INTEGER; BEGINSELECT t."VALUE" INTO VAL FROM SYS_SEQUECE t WHERE t…

Mysql和Oracle实现序列自增

/*ORACLE设置自增序列 oracle本身不支持如mysql的AUTO_INCREMENT自增方式&#xff0c;我们可以用序列加触发器的形式实现&#xff0c; 假如有一个表 T_WORKMATES&#xff0c;我们需要让学号PNO自增*/ --创建序列 SEQ_PNO CREATE SEQUENCE SEQ_PNO minvalue 1 --最小值为1 n…

如何实现 Oracle 的自增序列,两步轻松搞定

在实际项目开发过程中&#xff0c;设计数据库表时经常遇到需要主键自增的场景。那如何实现Oracle的主键自增呢&#xff0c;这里我们记录一种最常用的方式&#xff1a;sequence trigger。 就是利用Oralce的序号和触发器来实现字段的自增&#xff0c;下面直接来看一个完整的例子…

oracle中设置表的主键字段为自增序列(实例)

oracle中设置表的主键字段为自增序列&#xff08;实例&#xff09; 1、首先创建一个表&#xff08;如日志表&#xff09; //删除库表中存在的日志表 drop table S_LOG_INFO cascade constraints; //新建日志表 create table S_LOG_INFO (PRIMARYKEY NUMBER …

oracle数据库新建表增加表序列,设置id自增

1&#xff0c;oracle数据库增加新表时&#xff0c;设置表id为自增 最小1 最大9999999999 CREATE SEQUENCE “数据库名称”.“SEQ_表名称” MINVALUE 1 MAXVALUE 9999999999 INCREMENT BY 1 START WITH 100000014 NOCACHE NOORDER NOCYCLE 2&#xff0c;向数据库插入数据时&…

Oracle自增序列探秘:一篇文章教你读懂

目录 1&#xff1a;什么是Oracle 自增长序列 2 &#xff1a;创建数据-->实现自增长序列 2.1 创建序列 2.2 使用序列 3 &#xff1a;查询数据-->实现自增长序列 1&#xff1a;什么是Oracle 自增长序列 Oracle自增长序列是一种生成唯一数字的方法&#xff0c;可以用于创…

oracle 序列,程序中实现自增

文章目录 1. 序列作用和含义2. 序列的使用2.1 直接使用序列2.2 配合触发器隐式使用2.3 修改删除序列 1. 序列作用和含义 序列是用于生成唯一、连续序号的对象&#xff1b;可以是升序的&#xff0c;也可以是降序的&#xff1b; 使用create sequence语句创建序列 create sequen…

oracle自增序列

1.创建表TABLESPACETEST -- Create table create table TABLESPACETEST (contract_no VARCHAR2(100) primary key,contract_start_dt DATE,contract_end_dt DATE,loan_amt NUMBER(20,6),loan_bal NUMBER(20,6) ) tablespace SYSTEM;2.创建自增序列&…

【PWA】关于PWA的实操以及使用经验总结

关于PWA的实操以及使用经验总结 什么是PWA如何给项目加上PWA优缺点增强我们的 PWA写在后面 关于标题的说明&#xff1a; 实操&#xff1a; 实际操作 PWA &#xff1a; Progressive Web App 什么是PWA PWA 是渐进式 Web 应用&#xff0c; 类似于原生 App 的体验。 当我们在手机…

为什么 PWA 还没有“干掉”原生应用?

摘要&#xff1a;PWA 即渐进式网页应用&#xff0c;是 Web 应用的一种&#xff0c;具有安全、渐进式、响应式、无需网络、类应用程序、保持最新、可检测、可重新接入、可安装、可分享这 10 个要素&#xff0c;但 PWA 至今仍没有成为应用的默认格式。 原文链接&#xff1a;https…