@react-native-ohos/react-native-amap3d 3.2.6-rc.1 → 3.2.6-rc.3

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.
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Use these variables when you tailor your ArkTS code. They must be of the const type.
3
+ */
4
+ export const HAR_VERSION = '3.2.6-rc.3';
5
+ export const BUILD_MODE_NAME = 'debug';
6
+ export const DEBUG = true;
7
+ export const TARGET_NAME = 'default';
8
+
9
+ /**
10
+ * BuildProfile Class is used only for compatibility purposes.
11
+ */
12
+ export default class BuildProfile {
13
+ static readonly HAR_VERSION = HAR_VERSION;
14
+ static readonly BUILD_MODE_NAME = BUILD_MODE_NAME;
15
+ static readonly DEBUG = DEBUG;
16
+ static readonly TARGET_NAME = TARGET_NAME;
17
+ }
@@ -3,15 +3,15 @@
3
3
  "devDependencies": {
4
4
  },
5
5
  "name": "@react-native-ohos/react-native-amap3d",
6
- "version": "3.2.6-rc.1",
6
+ "version": "3.2.6-rc.3",
7
7
  "description": "Please describe the basic information.",
8
8
  "main": "index.ets",
9
9
  "author": "",
10
10
  "license": "Apache-2.0",
11
11
  "dependencies": {
12
12
  "@rnoh/react-native-openharmony": "0.72.82",
13
- "@amap/amap_lbs_map3d": "2.2.1",
14
- "@amap/amap_lbs_common": ">=1.2.0",
15
- "@amap/amap_lbs_location": "^1.2.2"
13
+ "@amap/amap_lbs_map3d": "2.2.5",
14
+ "@amap/amap_lbs_common": ">=1.2.3",
15
+ "@amap/amap_lbs_location": "^1.2.3"
16
16
  }
17
17
  }
@@ -25,9 +25,39 @@ import type {
25
25
  UITurboModule,
26
26
  UITurboModuleContext
27
27
  } from '@rnoh/react-native-openharmony/ts';
28
- import { RNOHPackage, TurboModulesFactory } from '@rnoh/react-native-openharmony'
28
+ import { RNOHPackage, TurboModulesFactory, ComponentBuilderContext } from '@rnoh/react-native-openharmony'
29
29
  import { AMap3DModule } from './AMap3DModule';
30
30
  import type { TurboModule } from '@rnoh/react-native-openharmony/ts';
31
+ import { A_MAP_CIRCLE_VIEW_TYPE, AMapCircle } from './View/AMapCircle';
32
+ import { A_MAP_MARKER_TYPE, AMapMarker } from './View/AMapMarker';
33
+ import { A_MAP_POLYGON_TYPE, AMapPolygon } from './View/AMapPolygon';
34
+ import { A_MAP_POLYLINE_TYPE, AMapPolyline } from './View/AMapPolyline';
35
+ import { GOADE_MAP_VIEW_TYPE, AMapView } from './View/MapView';
36
+
37
+ @Builder
38
+ function aMapCircle(ctx: ComponentBuilderContext) {
39
+ AMapCircle({ ctx: ctx.rnComponentContext, tag: ctx.tag })
40
+ }
41
+
42
+ @Builder
43
+ function aMapMarker(ctx: ComponentBuilderContext) {
44
+ AMapMarker({ ctx: ctx.rnComponentContext, tag: ctx.tag })
45
+ }
46
+
47
+ @Builder
48
+ function aMapPolygon(ctx: ComponentBuilderContext) {
49
+ AMapPolygon({ ctx: ctx.rnComponentContext, tag: ctx.tag })
50
+ }
51
+
52
+ @Builder
53
+ function aMapPolyline(ctx: ComponentBuilderContext) {
54
+ AMapPolyline({ ctx: ctx.rnComponentContext, tag: ctx.tag })
55
+ }
56
+
57
+ @Builder
58
+ function aMapView(ctx: ComponentBuilderContext) {
59
+ AMapView({ ctx: ctx.rnComponentContext, tag: ctx.tag })
60
+ }
31
61
 
32
62
  class RNAMap3DTurboModuleFactory extends TurboModulesFactory {
33
63
  createTurboModule(name: string): TurboModule | null {
@@ -67,6 +97,18 @@ export class AMap3DPackage extends RNOHPackage {
67
97
  getDebugName(): string {
68
98
  return 'AMap3DPackage';
69
99
  }
100
+
101
+ createWrappedCustomRNComponentBuilderByComponentNameMap(): Map<string, WrappedBuilder<[ComponentBuilderContext]>> {
102
+ const aMapBuilderMap = new Map<string, WrappedBuilder<[ComponentBuilderContext]>>();
103
+
104
+ aMapBuilderMap.set(GOADE_MAP_VIEW_TYPE, wrapBuilder(aMapView))
105
+ aMapBuilderMap.set(A_MAP_CIRCLE_VIEW_TYPE, wrapBuilder(aMapCircle))
106
+ aMapBuilderMap.set(A_MAP_MARKER_TYPE, wrapBuilder(aMapMarker))
107
+ aMapBuilderMap.set(A_MAP_POLYGON_TYPE, wrapBuilder(aMapPolygon))
108
+ aMapBuilderMap.set(A_MAP_POLYLINE_TYPE, wrapBuilder(aMapPolyline))
109
+
110
+ return aMapBuilderMap;
111
+ }
70
112
  }
71
113
 
72
114
  export const createAMap3DPackage = () => {
@@ -6,6 +6,10 @@ import HashMap from '@ohos.util.HashMap';
6
6
  export default class GlobalCache {
7
7
  public static index: number = 1
8
8
  public static isGO: boolean = false;
9
+ // 记录已销毁的地图组件tag,用于防止异步操作访问已释放资源
10
+ public static destroyedMapTags: Set<number> = new Set();
11
+ // 记录已销毁的Marker组件tag
12
+ public static destroyedMarkerTags: Set<number> = new Set();
9
13
  public static cacheMap: Map<Object | undefined, number> = new Map()
10
14
  public static cacheMapPageDestroy: Map<number, boolean> = new Map()
11
15
  public static mapMarker: Map<number, Array<Marker>> = new Map();//map的tag和 marker集合
@@ -28,11 +28,26 @@ export struct AMapMarker {
28
28
  markerTagAndDescriptorTagArray: Array<HashMap<number, string>> = []
29
29
  @State amapDescriptor: AMapMarkerDescriptor = {} as AMapMarkerDescriptor
30
30
  private unregisterDescriptorChangesListener?: () => void = undefined
31
+ private isDestroyed: boolean = false;
31
32
  static NAME: string = "AMapMarker";
32
-
33
+ /**
34
+ * 检查组件是否仍然有效(未被销毁)
35
+ */
36
+ private isValid(): boolean {
37
+ let currentMapTag = GlobalCache.currentPageMarker.get(this.tag);
38
+ return !this.isDestroyed &&
39
+ !GlobalCache.destroyedMarkerTags.has(this.tag) &&
40
+ (currentMapTag === undefined || !GlobalCache.destroyedMapTags.has(currentMapTag));
41
+ }
33
42
  aboutToAppear(): void {
43
+ // 从销毁列表中移除(处理组件复用场景)
44
+ GlobalCache.destroyedMarkerTags.delete(this.tag);
34
45
  this.unregisterDescriptorChangesListener = this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
35
46
  async (newDescriptor) => {
47
+ // 检查组件是否已销毁
48
+ if (!this.isValid()) {
49
+ return;
50
+ }
36
51
  /*------ 当RN侧属性props有更改 -------*/
37
52
  let currentMapTag = GlobalCache.currentPageMarker.get(this.tag)
38
53
  this.markers = GlobalCache.mapMarker.get(currentMapTag) ?? [];
@@ -43,9 +58,15 @@ export struct AMapMarker {
43
58
 
44
59
  for (let j = 0; j < this.markerTagAndDescriptorTagArray.length; ++j) {
45
60
  this.markerTagAndDescriptorTagArray[j].forEach(async (markerID: string, markerTag: number, map: HashMap<number, string>) => {
61
+ // 异步操作前检查组件是否已销毁
62
+ if (!this.isValid()) {
63
+ return;
64
+ }
46
65
  if (markerTag == this.tag) {
47
66
  for (let i = 0; i < this.markers.length; ++i) {
48
67
  if (this.markers[i].getId() == markerID) {
68
+ // 每次操作前都检查有效性
69
+ if (!this.isValid()) return;
49
70
  this.markers[i].setPosition(new LatLng(mapMarkerProps.position.latitude, mapMarkerProps.position.longitude));
50
71
  this.markers[i].setAnchor(mapMarkerProps.anchor ? mapMarkerProps.anchor.x : 1,
51
72
  mapMarkerProps.anchor ? mapMarkerProps.anchor.y : 0.5);
@@ -59,9 +80,12 @@ export struct AMapMarker {
59
80
  let bitmapDes: BitmapDescriptor | undefined =
60
81
  await BitmapDescriptorFactory.fromRawfilePath(globalContext, resoure);
61
82
  this.markers[i].setIcon(bitmapDes);
83
+ if (!this.isValid()) return;
62
84
  } catch (error) {
85
+ if (!this.isValid()) return;
63
86
  let bitmapDesNull: BitmapDescriptor | undefined =
64
87
  await BitmapDescriptorFactory.fromRawfilePath(globalContext, "common/marker_default.png");
88
+ if (!this.isValid()) return;
65
89
  if (bitmapDesNull) {
66
90
  this.markers[i].setIcon(bitmapDesNull);
67
91
  }
@@ -77,6 +101,14 @@ export struct AMapMarker {
77
101
  )
78
102
  }
79
103
 
104
+ aboutToDisappear(): void {
105
+ // 标记组件为已销毁
106
+ this.isDestroyed = true;
107
+ GlobalCache.destroyedMarkerTags.add(this.tag);
108
+ // 取消订阅
109
+ this.unregisterDescriptorChangesListener?.();
110
+ }
111
+
80
112
  build() {
81
113
  ContentSlot(this.ctx.getContentForTag(this.tag))
82
114
  }
@@ -33,10 +33,25 @@ export struct AMapPolyline {
33
33
  @State amapDescriptor: AMapPolylineDescriptor = {} as AMapPolylineDescriptor
34
34
  static NAME: string = "AMapPolyline";
35
35
  private unregisterDescriptorChangesListener?: () => void = undefined
36
+ // 组件是否已销毁标志
37
+ private isDestroyed: boolean = false;
38
+
39
+ /**
40
+ * 检查组件是否仍然有效(未被销毁)
41
+ */
42
+ private isValid(): boolean {
43
+ let currentMapTag = GlobalCache.currentPagePolyline.get(this.tag);
44
+ return !this.isDestroyed &&
45
+ (currentMapTag === undefined || !GlobalCache.destroyedMapTags.has(currentMapTag));
46
+ }
36
47
 
37
48
  aboutToAppear(): void {
38
49
  this.unregisterDescriptorChangesListener = this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
39
50
  async (newDescriptor) => {
51
+ // 检查组件是否已销毁
52
+ if (!this.isValid()) {
53
+ return;
54
+ }
40
55
  /*------ 当RN侧属性props有更改 -------*/
41
56
  let currentMapTag = GlobalCache.currentPagePolyline.get(this.tag)
42
57
  this.polyLines = GlobalCache.mapPolyLine.get(currentMapTag) ?? [];
@@ -47,9 +62,15 @@ export struct AMapPolyline {
47
62
  for (let j = 0; j < this.polyLineTagAndDescriptorTagArray.length; ++j) {
48
63
  this.polyLineTagAndDescriptorTagArray[j].forEach(async (polyLineID: string, polyLineTag: number,
49
64
  map: HashMap<number, string>) => {
65
+ // 异步操作前检查组件是否已销毁
66
+ if (!this.isValid()) {
67
+ return;
68
+ }
50
69
  if (polyLineTag == this.tag) {
51
70
  for (let i = 0; i < this.polyLines.length; ++i) {
52
71
  if (this.polyLines[i].getId() == polyLineID) {
72
+ // 每次操作前都检查有效性
73
+ if (!this.isValid()) return;
53
74
  this.polyLines[i].setZIndex(mapPolylineProp.zIndex ? mapPolylineProp.zIndex : 1);
54
75
  this.polyLines[i].setDottedLine(mapPolylineProp.dotted ? mapPolylineProp.dotted : false);
55
76
  this.polyLines[i].setGeodesic(mapPolylineProp.geodesic ? mapPolylineProp.geodesic : false);
@@ -84,6 +105,13 @@ export struct AMapPolyline {
84
105
  )
85
106
  }
86
107
 
108
+ aboutToDisappear(): void {
109
+ // 标记组件为已销毁
110
+ this.isDestroyed = true;
111
+ // 取消订阅
112
+ this.unregisterDescriptorChangesListener?.();
113
+ }
114
+
87
115
  build() {
88
116
  }
89
117
  }
@@ -86,8 +86,19 @@ export struct AMapView {
86
86
  private polylines : Array<Polyline> = new Array();
87
87
  private markerTagAndDescriptorTagArray : Array<HashMap<number, string>> = new Array();
88
88
  private polylineTagAndDescriptorTagArray : Array<HashMap<number, string>> = new Array();
89
- private mapListener?: OnLocationChangedListener;
89
+ private mapListener?: OnLocationChangedListener;
90
+ // 组件是否已销毁标志,用于防止异步操作访问已释放资源
91
+ private isDestroyed: boolean = false;
92
+
93
+ /**
94
+ * 检查组件是否仍然有效(未被销毁)
95
+ */
96
+ private isValid(): boolean {
97
+ return !this.isDestroyed && !GlobalCache.destroyedMapTags.has(this.tag);
98
+ }
90
99
  aboutToAppear(): void {
100
+ // 从销毁列表中移除(处理组件复用场景)
101
+ GlobalCache.destroyedMapTags.delete(this.tag);
91
102
  this.cleanupCallback = this.ctx.componentCommandReceiver.registerCommandCallback(
92
103
  this.tag,
93
104
  (command, args: ESObject[]) => {
@@ -102,6 +113,10 @@ export struct AMapView {
102
113
  this.show();
103
114
  this.unregisterDescriptorChangesListener = this.ctx.descriptorRegistry.subscribeToDescriptorChanges(this.tag,
104
115
  (newDescriptor) => {
116
+ // 检查组件是否已销毁,避免访问已释放资源
117
+ if (!this.isValid()) {
118
+ return;
119
+ }
105
120
  if (this.aMap) {
106
121
  GlobalCache.mapPolyLine.clear();
107
122
  /*------ 当RN侧属性props有更改 -------*/
@@ -125,19 +140,29 @@ export struct AMapView {
125
140
  }
126
141
 
127
142
  aboutToDisappear(): void {
143
+ // 首先标记组件为已销毁,阻止后续异步操作
144
+ this.isDestroyed = true;
145
+ GlobalCache.destroyedMapTags.add(this.tag);
128
146
  if (this.mapViewCreateCallback) {
129
147
  MapViewManager.getInstance().unregisterMapViewCreatedCallback(this.mapViewCreateCallback);
130
148
  }
131
149
  this.unregisterDescriptorChangesListener?.()
132
150
  this.cleanupCallback?.()
133
- GlobalCache.maps.get(this.tag)?.clear()
134
- GlobalCache.mapViews.get(this.tag)?.onDestroy();
151
+ // 延迟清理资源,确保正在进行的异步操作有机会检查销毁标志
152
+ setTimeout(() => {
153
+ try {
154
+ GlobalCache.maps.get(this.tag)?.clear()
155
+ GlobalCache.mapViews.get(this.tag)?.onDestroy();
156
+ } catch (error) {
157
+ // 忽略清理过程中的错误
158
+ }
135
159
  GlobalCache.mapMarker.delete(this.tag);
136
160
  GlobalCache.markerTagAndDescriptorTag.delete(this.tag);
137
161
  GlobalCache.mapPolyLine.delete(this.tag);
138
162
  GlobalCache.polyLinesTagAndDescriptorTag.delete(this.tag);
139
163
  GlobalCache.polygonCacheMap.clear();
140
164
  GlobalCache.circleCacheMap.clear();
165
+ }, 500);
141
166
  }
142
167
 
143
168
  locationManager?:AMapLocationManagerImpl
@@ -247,6 +272,10 @@ export struct AMapView {
247
272
  }
248
273
 
249
274
  private mapViewCreateCallback = (mapview?: MapView, mapViewName?: string) => {
275
+ // 检查组件是否已销毁
276
+ if (!this.isValid()) {
277
+ return;
278
+ }
250
279
  if (!mapview) {
251
280
  return;
252
281
  }
@@ -256,7 +285,11 @@ export struct AMapView {
256
285
  mapview.onCreate();
257
286
  GlobalCache.mapViews.set(this.tag, mapview);
258
287
  this.mapView = GlobalCache.mapViews.get(this.tag);
259
- this.mapView.getMapAsync(async (map: AMap) => {
288
+ this.mapView.getMapAsync(async (map:AMap) => {
289
+ // 异步回调中再次检查
290
+ if (!this.isValid()) {
291
+ return;
292
+ }
260
293
  GlobalCache.maps.set(this.tag, map);
261
294
  this.aMap = GlobalCache.maps.get(this.tag);
262
295
  this.aMap.setLocationSource(this);
@@ -472,6 +505,10 @@ export struct AMapView {
472
505
  }
473
506
 
474
507
  private async getOverlay(descriptor: GDMapViewDescriptor) {
508
+ // 检查组件是否已销毁
509
+ if (!this.isValid()) {
510
+ return;
511
+ }
475
512
  let tagName = "";
476
513
  let flag = false;
477
514
  let flagLine = false;
@@ -609,10 +646,16 @@ export struct AMapView {
609
646
 
610
647
  for (let index = 0; index < markerTagAndDescriptorTagArray.length; index++) {
611
648
  markerTagAndDescriptorTagArray[index].forEach(async (value: string, key: number, map: HashMap<number, string>) => {
649
+ // 异步操作前检查组件是否已销毁
650
+ if (!this.isValid()) {
651
+ return;
652
+ }
612
653
  if (markerDescriptor.tag == key) {
613
654
  for (let markerIndex = 0; markerIndex < this.markers.length; markerIndex++) {
614
655
  if (this.markers[markerIndex].getId() == value) {
615
656
  flag = true;
657
+ // 每次操作前都检查有效性
658
+ if (!this.isValid()) return;
616
659
  this.markers[markerIndex].setPosition(new LatLng(mapMarkerProps.position.latitude, mapMarkerProps.position.longitude));
617
660
  this.markers[markerIndex].setAnchor(mapMarkerProps.anchor ? mapMarkerProps.anchor.x : 1,
618
661
  mapMarkerProps.anchor ? mapMarkerProps.anchor.y : 0.5);
@@ -626,14 +669,20 @@ export struct AMapView {
626
669
  let bitmapView : BitmapDescriptor | undefined = await BitmapDescriptorFactory.fromView(() => {
627
670
  this.customMarkerBuilder(markerDescriptor.tag);
628
671
  })
672
+ // 异步操作后再次检查
673
+ if (!this.isValid()) return;
629
674
  this.markers[markerIndex].setIcon(bitmapView);
630
675
  } else {
631
676
  if (mapMarkerProps.icon) {
632
677
  try {
633
678
  await DownloadIcon.updataMakerIcon(this.getUIContext(), this.markers[markerIndex], mapMarkerProps.icon);
679
+ // 异步操作后再次检查
680
+ if (!this.isValid()) return;
634
681
  } catch (error) {
682
+ if (!this.isValid()) return;
635
683
  let bitmapDesNull: BitmapDescriptor | undefined =
636
684
  await BitmapDescriptorFactory.fromRawfilePath(globalContext, "common/marker_default.png");
685
+ if (!this.isValid()) return;
637
686
  if (bitmapDesNull) {
638
687
  this.markers[markerIndex].setIcon(bitmapDesNull);
639
688
  }
@@ -648,6 +697,10 @@ export struct AMapView {
648
697
  }
649
698
 
650
699
  if (!flag) {
700
+ // 检查组件是否已销毁
701
+ if (!this.isValid()) {
702
+ break;
703
+ }
651
704
  let markerOptions = new MarkerOptions();
652
705
  GlobalCache.currentPageMarker.set(markerDescriptor.tag, this.tag)
653
706
  this.markerTag.push(this.ctx.descriptorRegistry.getDescriptor(descriptor.childrenTags[i]).tag);
@@ -662,19 +715,37 @@ export struct AMapView {
662
715
  let bitmapView: BitmapDescriptor | undefined = await BitmapDescriptorFactory.fromView(() => {
663
716
  this.customMarkerBuilder(markerDescriptor.tag);
664
717
  })
718
+ // 异步操作后检查组件是否已销毁
719
+ if (!this.isValid()) {
720
+ break;
721
+ }
665
722
  markerOptions.setIcon(bitmapView);
666
723
  } else {
667
724
  if (mapMarkerProps.icon) {
668
725
  try {
669
726
  await DownloadIcon.updataMakerIcon(this.getUIContext(), markerOptions, mapMarkerProps.icon);
727
+ // 异步操作后检查组件是否已销毁
728
+ if (!this.isValid()) {
729
+ break;
730
+ }
670
731
  } catch (error) {
732
+ if (!this.isValid()) {
733
+ break;
734
+ }
671
735
  let bitmapDesNull: BitmapDescriptor | undefined =
672
736
  await BitmapDescriptorFactory.fromRawfilePath(globalContext, "common/marker_default.png");
737
+ if (!this.isValid()) {
738
+ break;
739
+ }
673
740
  if (bitmapDesNull) {
674
741
  markerOptions.setIcon(bitmapDesNull);
675
742
  }
676
743
  }
677
744
  }
745
+ }
746
+ // 最后添加 marker 前再次检查
747
+ if (!this.isValid()) {
748
+ break;
678
749
  }
679
750
  markerOptions.setDraggable(mapMarkerProps.draggable ? mapMarkerProps.draggable : false);
680
751
  markerOptions.setZIndex(mapMarkerProps.zIndex ? mapMarkerProps.zIndex : 1);
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-native-ohos/react-native-amap3d",
3
- "version": "3.2.6-rc.1",
3
+ "version": "3.2.6-rc.3",
4
4
  "description": "react-native 高德地图组件,支持 harmonyOS",
5
5
  "license": "MIT",
6
6
  "keywords": [