expo-gaode-map-navigation 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/build.gradle +3 -0
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapModule.kt +45 -49
- package/android/src/main/java/expo/modules/gaodemap/map/ExpoGaodeMapView.kt +5 -15
- package/android/src/main/java/expo/modules/gaodemap/map/modules/SDKInitializer.kt +143 -14
- package/build/ExpoGaodeMapNaviView.d.ts.map +1 -1
- package/build/ExpoGaodeMapNaviView.js +3 -2
- package/build/ExpoGaodeMapNaviView.js.map +1 -1
- package/build/ExpoGaodeMapNavigationModule.d.ts +2 -7
- package/build/ExpoGaodeMapNavigationModule.d.ts.map +1 -1
- package/build/ExpoGaodeMapNavigationModule.js +19 -2
- package/build/ExpoGaodeMapNavigationModule.js.map +1 -1
- package/build/index.d.ts.map +1 -1
- package/build/index.js +8 -2
- package/build/index.js.map +1 -1
- package/build/map/ExpoGaodeMapModule.d.ts +245 -4
- package/build/map/ExpoGaodeMapModule.d.ts.map +1 -1
- package/build/map/ExpoGaodeMapModule.js +197 -15
- package/build/map/ExpoGaodeMapModule.js.map +1 -1
- package/build/map/ExpoGaodeMapOfflineModule.d.ts.map +1 -1
- package/build/map/ExpoGaodeMapOfflineModule.js +19 -2
- package/build/map/ExpoGaodeMapOfflineModule.js.map +1 -1
- package/build/map/ExpoGaodeMapView.d.ts.map +1 -1
- package/build/map/ExpoGaodeMapView.js +8 -2
- package/build/map/ExpoGaodeMapView.js.map +1 -1
- package/build/map/components/overlays/Circle.d.ts.map +1 -1
- package/build/map/components/overlays/Circle.js +3 -2
- package/build/map/components/overlays/Circle.js.map +1 -1
- package/build/map/components/overlays/Cluster.d.ts.map +1 -1
- package/build/map/components/overlays/Cluster.js +3 -2
- package/build/map/components/overlays/Cluster.js.map +1 -1
- package/build/map/components/overlays/HeatMap.d.ts.map +1 -1
- package/build/map/components/overlays/HeatMap.js +3 -2
- package/build/map/components/overlays/HeatMap.js.map +1 -1
- package/build/map/components/overlays/Marker.d.ts.map +1 -1
- package/build/map/components/overlays/Marker.js +3 -2
- package/build/map/components/overlays/Marker.js.map +1 -1
- package/build/map/components/overlays/MultiPoint.d.ts.map +1 -1
- package/build/map/components/overlays/MultiPoint.js +3 -2
- package/build/map/components/overlays/MultiPoint.js.map +1 -1
- package/build/map/components/overlays/Polygon.d.ts.map +1 -1
- package/build/map/components/overlays/Polygon.js +3 -2
- package/build/map/components/overlays/Polygon.js.map +1 -1
- package/build/map/components/overlays/Polyline.d.ts.map +1 -1
- package/build/map/components/overlays/Polyline.js +3 -2
- package/build/map/components/overlays/Polyline.js.map +1 -1
- package/build/map/types/common.types.d.ts +26 -0
- package/build/map/types/common.types.d.ts.map +1 -1
- package/build/map/types/common.types.js.map +1 -1
- package/build/map/types/native-module.types.d.ts +28 -1
- package/build/map/types/native-module.types.d.ts.map +1 -1
- package/build/map/types/native-module.types.js.map +1 -1
- package/build/map/utils/ErrorHandler.d.ts +6 -0
- package/build/map/utils/ErrorHandler.d.ts.map +1 -1
- package/build/map/utils/ErrorHandler.js +42 -0
- package/build/map/utils/ErrorHandler.js.map +1 -1
- package/build/map/utils/GeoUtils.d.ts.map +1 -1
- package/build/map/utils/GeoUtils.js +6 -2
- package/build/map/utils/GeoUtils.js.map +1 -1
- package/build/map/utils/lazyNativeViewManager.d.ts +3 -0
- package/build/map/utils/lazyNativeViewManager.d.ts.map +1 -0
- package/build/map/utils/lazyNativeViewManager.js +11 -0
- package/build/map/utils/lazyNativeViewManager.js.map +1 -0
- package/ios/ExpoGaodeMapNavigation.podspec +5 -0
- package/ios/map/ExpoGaodeMapModule.swift +27 -40
- package/ios/map/ExpoGaodeMapView.swift +160 -77
- package/ios/map/GaodeMapPrivacyManager.swift +155 -0
- package/ios/map/modules/LocationManager.swift +43 -24
- package/package.json +1 -1
- package/android/src/main/java/expo/modules/gaodemap/map/MapPreloadManager.kt +0 -494
- package/ios/map/MapPreloadManager.swift +0 -348
|
@@ -1,348 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 地图预加载管理器 (iOS)
|
|
3
|
-
* 在后台预先初始化地图实例,提升首次显示速度
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import Foundation
|
|
7
|
-
import AMapFoundationKit
|
|
8
|
-
import AMapNaviKit
|
|
9
|
-
|
|
10
|
-
/// 预加载实例数据
|
|
11
|
-
struct PreloadedMapInstance {
|
|
12
|
-
let mapView: MAMapView
|
|
13
|
-
let timestamp: Date
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
/// 地图预加载管理器
|
|
17
|
-
///
|
|
18
|
-
class MapPreloadManager {
|
|
19
|
-
static let shared = MapPreloadManager()
|
|
20
|
-
|
|
21
|
-
// 动态池大小配置(根据内存自适应)
|
|
22
|
-
private let maxPoolSizeHighMemory = 3 // 高内存设备:>= 500MB
|
|
23
|
-
private let maxPoolSizeMediumMemory = 2 // 中等内存:300-500MB
|
|
24
|
-
private let maxPoolSizeLowMemory = 1 // 低内存设备:150-300MB
|
|
25
|
-
private let minMemoryThresholdMB: UInt64 = 150 // 最低内存要求
|
|
26
|
-
|
|
27
|
-
// 动态 TTL 配置(根据内存压力自适应)
|
|
28
|
-
private let ttlNormal: TimeInterval = 5 * 60 // 正常:5分钟
|
|
29
|
-
private let ttlMemoryPressure: TimeInterval = 2 * 60 // 内存压力:2分钟
|
|
30
|
-
private let ttlLowMemory: TimeInterval = 1 * 60 // 低内存:1分钟
|
|
31
|
-
|
|
32
|
-
private var preloadedMapInstances: [PreloadedMapInstance] = []
|
|
33
|
-
private var isPreloading = false
|
|
34
|
-
private let preloadQueue = DispatchQueue(label: "com.expo.gaodemap.preload", qos: .background)
|
|
35
|
-
private var preloadGroup = DispatchGroup()
|
|
36
|
-
|
|
37
|
-
// 动态配置
|
|
38
|
-
private var currentMaxPoolSize = 2
|
|
39
|
-
private var currentTTL: TimeInterval = 5 * 60
|
|
40
|
-
private var memoryPressureLevel = 0 // 0=正常, 1=压力, 2=严重
|
|
41
|
-
|
|
42
|
-
// 定期清理任务
|
|
43
|
-
private var cleanupTimer: Timer?
|
|
44
|
-
|
|
45
|
-
private init() {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// 注册内存警告监听
|
|
49
|
-
NotificationCenter.default.addObserver(
|
|
50
|
-
self,
|
|
51
|
-
selector: #selector(handleMemoryWarning),
|
|
52
|
-
name: UIApplication.didReceiveMemoryWarningNotification,
|
|
53
|
-
object: nil
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
// 启动定期清理任务
|
|
57
|
-
startPeriodicCleanup()
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/// 启动定期清理过期实例的任务
|
|
61
|
-
private func startPeriodicCleanup() {
|
|
62
|
-
cleanupTimer?.invalidate()
|
|
63
|
-
cleanupTimer = Timer.scheduledTimer(withTimeInterval: 60, repeats: true) { [weak self] _ in
|
|
64
|
-
self?.cleanupExpiredInstances()
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
/// 清理过期的预加载实例(使用动态 TTL)
|
|
69
|
-
private func cleanupExpiredInstances() {
|
|
70
|
-
let now = Date()
|
|
71
|
-
var expiredCount = 0
|
|
72
|
-
|
|
73
|
-
preloadedMapInstances.removeAll { instance in
|
|
74
|
-
let isExpired = now.timeIntervalSince(instance.timestamp) > currentTTL
|
|
75
|
-
if isExpired {
|
|
76
|
-
expiredCount += 1
|
|
77
|
-
}
|
|
78
|
-
return isExpired
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
if expiredCount > 0 {
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/// 处理内存警告
|
|
86
|
-
@objc private func handleMemoryWarning() {
|
|
87
|
-
|
|
88
|
-
clearPool()
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/// 开始预加载地图实例(自适应版本)
|
|
92
|
-
/// - Parameter poolSize: 预加载的地图实例数量(会根据内存自适应调整)
|
|
93
|
-
func startPreload(poolSize: Int) {
|
|
94
|
-
guard !isPreloading else {
|
|
95
|
-
|
|
96
|
-
return
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// 动态计算最优池大小
|
|
100
|
-
let adaptiveMaxPoolSize = calculateAdaptivePoolSize()
|
|
101
|
-
currentMaxPoolSize = adaptiveMaxPoolSize
|
|
102
|
-
|
|
103
|
-
// 动态调整 TTL
|
|
104
|
-
currentTTL = calculateAdaptiveTTL()
|
|
105
|
-
|
|
106
|
-
// 检查内存是否充足
|
|
107
|
-
guard hasEnoughMemory() else {
|
|
108
|
-
|
|
109
|
-
return
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
isPreloading = true
|
|
113
|
-
let targetSize = min(poolSize, adaptiveMaxPoolSize)
|
|
114
|
-
|
|
115
|
-
for _ in 0..<targetSize {
|
|
116
|
-
preloadGroup.enter() // 进入预加载队列
|
|
117
|
-
|
|
118
|
-
preloadQueue.async { [weak self] in
|
|
119
|
-
guard let self = self else { return }
|
|
120
|
-
autoreleasepool {
|
|
121
|
-
// 创建地图视图
|
|
122
|
-
let mapView = self.createPreloadedMapView()
|
|
123
|
-
|
|
124
|
-
// 将地图实例添加到池中(带时间戳)
|
|
125
|
-
DispatchQueue.main.async {
|
|
126
|
-
let instance = PreloadedMapInstance(mapView: mapView, timestamp: Date())
|
|
127
|
-
self.preloadedMapInstances.append(instance)
|
|
128
|
-
self.preloadGroup.leave()
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
// 等待所有实例加载完成
|
|
135
|
-
preloadGroup.notify(queue: DispatchQueue.main) {
|
|
136
|
-
self.isPreloading = false
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
/// 创建预加载的地图视图
|
|
141
|
-
/// - Returns: 预加载的地图视图实例
|
|
142
|
-
private func createPreloadedMapView() -> MAMapView {
|
|
143
|
-
var mapView: MAMapView!
|
|
144
|
-
|
|
145
|
-
// 检查是否已在主线程,避免死锁
|
|
146
|
-
if Thread.isMainThread {
|
|
147
|
-
mapView = MAMapView()
|
|
148
|
-
configureMapView(mapView)
|
|
149
|
-
} else {
|
|
150
|
-
// 确保在主线程中创建 MAMapView
|
|
151
|
-
DispatchQueue.main.sync {
|
|
152
|
-
mapView = MAMapView()
|
|
153
|
-
self.configureMapView(mapView)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return mapView
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/// 配置地图视图的基础属性
|
|
160
|
-
/// - Parameter mapView: 需要配置的地图视图
|
|
161
|
-
private func configureMapView(_ mapView: MAMapView) {
|
|
162
|
-
// 基础配置
|
|
163
|
-
mapView.mapType = .standard
|
|
164
|
-
mapView.showsUserLocation = false
|
|
165
|
-
mapView.showsCompass = false
|
|
166
|
-
mapView.showsScale = false
|
|
167
|
-
mapView.isZoomEnabled = true
|
|
168
|
-
mapView.isScrollEnabled = true
|
|
169
|
-
mapView.isRotateEnabled = true
|
|
170
|
-
|
|
171
|
-
// 预加载中心区域(北京天安门)
|
|
172
|
-
let centerCoordinate = CLLocationCoordinate2D(latitude: 39.9042, longitude: 116.4074)
|
|
173
|
-
mapView.setCenter(centerCoordinate, animated: false)
|
|
174
|
-
mapView.setZoomLevel(12, animated: false)
|
|
175
|
-
|
|
176
|
-
// 设置一个最小的 frame 以触发地图渲染
|
|
177
|
-
mapView.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
|
|
178
|
-
|
|
179
|
-
// 触发地图初始化
|
|
180
|
-
mapView.layoutIfNeeded()
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/// 计算自适应池大小
|
|
184
|
-
/// 根据可用内存动态调整池大小
|
|
185
|
-
private func calculateAdaptivePoolSize() -> Int {
|
|
186
|
-
let availableMB = getAvailableMemoryMB()
|
|
187
|
-
|
|
188
|
-
switch availableMB {
|
|
189
|
-
case 500...:
|
|
190
|
-
return maxPoolSizeHighMemory
|
|
191
|
-
case 300..<500:
|
|
192
|
-
return maxPoolSizeMediumMemory
|
|
193
|
-
case 150..<300:
|
|
194
|
-
return maxPoolSizeLowMemory
|
|
195
|
-
default:
|
|
196
|
-
return 0
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/// 计算自适应 TTL
|
|
201
|
-
/// 根据内存压力动态调整过期时间
|
|
202
|
-
private func calculateAdaptiveTTL() -> TimeInterval {
|
|
203
|
-
let availableMB = getAvailableMemoryMB()
|
|
204
|
-
let totalMB = getTotalMemoryMB()
|
|
205
|
-
let usagePercent = Int((Double(totalMB - availableMB) / Double(totalMB)) * 100)
|
|
206
|
-
|
|
207
|
-
switch usagePercent {
|
|
208
|
-
case 0..<60:
|
|
209
|
-
memoryPressureLevel = 0
|
|
210
|
-
return ttlNormal
|
|
211
|
-
case 60..<80:
|
|
212
|
-
memoryPressureLevel = 1
|
|
213
|
-
return ttlMemoryPressure
|
|
214
|
-
default:
|
|
215
|
-
memoryPressureLevel = 2
|
|
216
|
-
return ttlLowMemory
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
/// 获取可用内存(MB)
|
|
221
|
-
private func getAvailableMemoryMB() -> UInt64 {
|
|
222
|
-
var info = mach_task_basic_info()
|
|
223
|
-
var count = mach_msg_type_number_t(MemoryLayout<mach_task_basic_info>.size) / 4
|
|
224
|
-
|
|
225
|
-
let kerr: kern_return_t = withUnsafeMutablePointer(to: &info) {
|
|
226
|
-
$0.withMemoryRebound(to: integer_t.self, capacity: 1) {
|
|
227
|
-
task_info(mach_task_self_, task_flavor_t(MACH_TASK_BASIC_INFO), $0, &count)
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
if kerr == KERN_SUCCESS {
|
|
232
|
-
let usedMB = UInt64(info.resident_size) / 1024 / 1024
|
|
233
|
-
let totalMB = ProcessInfo.processInfo.physicalMemory / 1024 / 1024
|
|
234
|
-
return totalMB - usedMB
|
|
235
|
-
}
|
|
236
|
-
return 0
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
/// 获取总内存(MB)
|
|
240
|
-
private func getTotalMemoryMB() -> UInt64 {
|
|
241
|
-
return ProcessInfo.processInfo.physicalMemory / 1024 / 1024
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
/// 检查是否有足够的内存
|
|
245
|
-
private func hasEnoughMemory() -> Bool {
|
|
246
|
-
return getAvailableMemoryMB() > minMemoryThresholdMB
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
/// 清空预加载池
|
|
251
|
-
func clearPool() {
|
|
252
|
-
_ = preloadedMapInstances.count
|
|
253
|
-
preloadedMapInstances.removeAll()
|
|
254
|
-
}
|
|
255
|
-
|
|
256
|
-
/// 获取预加载状态(包含动态配置信息)
|
|
257
|
-
/// - Returns: 预加载状态信息
|
|
258
|
-
func getStatus() -> [String: Any] {
|
|
259
|
-
return [
|
|
260
|
-
"poolSize": preloadedMapInstances.count,
|
|
261
|
-
"isPreloading": isPreloading,
|
|
262
|
-
"maxPoolSize": currentMaxPoolSize,
|
|
263
|
-
"currentTTL": currentTTL,
|
|
264
|
-
"memoryPressureLevel": memoryPressureLevel,
|
|
265
|
-
"isAdaptive": true
|
|
266
|
-
]
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
/// 获取性能统计信息(包含内存信息)
|
|
270
|
-
func getPerformanceMetrics() -> [String: Any] {
|
|
271
|
-
let availableMB = getAvailableMemoryMB()
|
|
272
|
-
let totalMB = getTotalMemoryMB()
|
|
273
|
-
let usagePercent = Int((Double(totalMB - availableMB) / Double(totalMB)) * 100)
|
|
274
|
-
|
|
275
|
-
return [
|
|
276
|
-
"currentMaxPoolSize": currentMaxPoolSize,
|
|
277
|
-
"currentTTL": currentTTL,
|
|
278
|
-
"memoryPressureLevel": memoryPressureLevel,
|
|
279
|
-
"availableMemoryMB": availableMB,
|
|
280
|
-
"totalMemoryMB": totalMB,
|
|
281
|
-
"memoryUsagePercent": usagePercent,
|
|
282
|
-
"poolSize": preloadedMapInstances.count
|
|
283
|
-
]
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
/// 获取一个预加载的地图实例(使用动态 TTL)
|
|
287
|
-
/// - Returns: 预加载的地图视图,如果池为空则返回 null
|
|
288
|
-
func getPreloadedMapView() -> MAMapView? {
|
|
289
|
-
let now = Date()
|
|
290
|
-
|
|
291
|
-
// 检查并移除过期实例
|
|
292
|
-
while let instance = preloadedMapInstances.first {
|
|
293
|
-
if now.timeIntervalSince(instance.timestamp) > currentTTL {
|
|
294
|
-
preloadedMapInstances.removeFirst()
|
|
295
|
-
// 可以在这里做一些清理工作,比如清理 delegate
|
|
296
|
-
} else {
|
|
297
|
-
break
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
if !preloadedMapInstances.isEmpty {
|
|
302
|
-
let instance = preloadedMapInstances.removeFirst()
|
|
303
|
-
|
|
304
|
-
// 触发自动补充(延迟执行,避免影响当前页面渲染)
|
|
305
|
-
triggerRefill()
|
|
306
|
-
|
|
307
|
-
return instance.mapView
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// 尝试触发补充,以便下次使用
|
|
311
|
-
triggerRefill()
|
|
312
|
-
|
|
313
|
-
return nil
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
/// 触发自动补充机制
|
|
317
|
-
private func triggerRefill() {
|
|
318
|
-
guard !isPreloading else { return }
|
|
319
|
-
|
|
320
|
-
// 延迟 5 秒后尝试补充,避免抢占当前 UI 资源
|
|
321
|
-
DispatchQueue.main.asyncAfter(deadline: .now() + 5.0) { [weak self] in
|
|
322
|
-
guard let self = self else { return }
|
|
323
|
-
|
|
324
|
-
if !self.isPreloading && self.preloadedMapInstances.count < self.currentMaxPoolSize {
|
|
325
|
-
|
|
326
|
-
self.startPreload(poolSize: self.currentMaxPoolSize)
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
|
-
/// 检查是否有可用的预加载实例
|
|
332
|
-
/// - Returns: 是否有可用实例
|
|
333
|
-
func hasPreloadedMapView() -> Bool {
|
|
334
|
-
return !preloadedMapInstances.isEmpty
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
func cleanup() {
|
|
338
|
-
cleanupTimer?.invalidate()
|
|
339
|
-
cleanupTimer = nil
|
|
340
|
-
clearPool()
|
|
341
|
-
}
|
|
342
|
-
|
|
343
|
-
deinit {
|
|
344
|
-
cleanupTimer?.invalidate()
|
|
345
|
-
NotificationCenter.default.removeObserver(self)
|
|
346
|
-
}
|
|
347
|
-
}
|
|
348
|
-
|