Skip to content

Commit 64e3c47

Browse files
authored
[sdk] add thread checking (#1316)
* [sdk] Enable main thread checking on the map object when running applications in debug mode. * update changelog
1 parent a35ee8c commit 64e3c47

21 files changed

+1310
-714
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Mapbox welcomes participation and contributions from everyone.
1313
* Remove `MapboxExperimental` annotation from viewport plugin and promote viewport plugin as stable API. ([1425](https://github.com/mapbox/mapbox-maps-android/pull/1425))
1414
* Introduce `addRendererSetupErrorListener`/`removeRendererSetupErrorListener` methods for `MapView` and `MapSurface` to listen to renderer setup errors and give opportunity to control some edge cases. ([1427](https://github.com/mapbox/mapbox-maps-android/pull/1427))
1515
* Introduce transition properties for atmosphere and terrain. ([1451](https://github.com/mapbox/mapbox-maps-android/pull/1451))
16+
* Enable main thread checking on the map/style object when running applications in debug build. This utility class will crash the application if these objects are accessed from a worked thread. It's required to call these object functions on the main thread, otherwise you can hit edge case crashes. This configurations is advised but can be opted out with a Manifest metadata entry of `com.mapbox.maps.ThreadChecker` and corresponding false value. ([#1316](https://github.com/mapbox/mapbox-maps-android/pull/1316)).
1617
* Introduce view annotation `ViewAnnotationManager.setViewAnnotationUpdateMode` / `ViewAnnotationManager.getViewAnnotationUpdateMode` API with following synchronization modes: MAP_SYNCHRONIZED (used by default) and MAP_FIXED_DELAY. ([1415](https://github.com/mapbox/mapbox-maps-android/pull/1415))
1718
* Reduce geometry on globe tile to increase rendering performance. ([#1462](https://github.com/mapbox/mapbox-maps-android/pull/1462))
1819
* Improve rendering performance with deleting layer render data on a worker thread. ([#1462](https://github.com/mapbox/mapbox-maps-android/pull/1462))

app/src/androidTest/java/com/mapbox/maps/testapp/annotation/UpdateAnnotationTest.kt

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.mapbox.maps.testapp.annotation
22

33
import android.graphics.Color
44
import android.os.Handler
5+
import android.os.Looper
56
import androidx.test.ext.junit.runners.AndroidJUnit4
67
import androidx.test.filters.LargeTest
78
import com.mapbox.geojson.Point
@@ -64,43 +65,51 @@ class UpdateAnnotationTest : BaseMapTest() {
6465

6566
override fun loadMap() {
6667
super.loadMap()
67-
pointAnnotationManager = mapView.annotations.createPointAnnotationManager()
68-
pointAnnotationManager.textFont = listOf("Open Sans Regular")
68+
val latch = CountDownLatch(1)
69+
handler = Handler(Looper.getMainLooper())
70+
handler.post {
71+
pointAnnotationManager = mapView.annotations.createPointAnnotationManager()
72+
pointAnnotationManager.textFont = listOf("Open Sans Regular")
6973

70-
pointAnnotation = pointAnnotationManager.create(
71-
PointAnnotationOptions()
72-
.withIconColor(ColorUtils.colorToRgbaString(Color.RED))
73-
.withIconImage("car-15")
74-
.withDraggable(true)
75-
.withIconAnchor(IconAnchor.CENTER)
76-
.withIconHaloBlur(1.0)
77-
.withIconHaloColor(ColorUtils.colorToRgbaString(Color.YELLOW))
78-
.withIconHaloWidth(2.0)
79-
.withIconOffset(listOf(1.0, 2.0))
80-
.withIconOpacity(0.8)
81-
.withIconRotate(0.5)
82-
.withIconSize(5.0)
83-
.withIconHaloColor(ColorUtils.colorToRgbaString(Color.WHITE))
84-
.withSymbolSortKey(1.0)
85-
.withTextAnchor(TextAnchor.TOP)
86-
.withTextColor(ColorUtils.colorToRgbaString(Color.YELLOW))
87-
.withTextField("Car")
88-
.withTextHaloBlur(1.0)
89-
.withTextHaloWidth(5.0)
90-
.withTextJustify(TextJustify.CENTER)
91-
.withTextLetterSpacing(2.0)
92-
.withTextRotate(5.0)
93-
.withTextTransform(TextTransform.UPPERCASE)
94-
.withTextSize(15.0)
95-
.withTextRadialOffset(1.0)
96-
.withTextOffset(listOf(1.0, 2.0))
97-
.withTextMaxWidth(10.0)
98-
.withPoint(Point.fromLngLat(0.0, 0.0))
99-
)
100-
for (i in 0..100) {
101-
// Verify there is no ConcurrentModificationException https://github.com/mapbox/mapbox-maps-android/issues/383
102-
pointAnnotation.textOpacity = 0.8
103-
Thread.sleep(0, 2000)
74+
pointAnnotation = pointAnnotationManager.create(
75+
PointAnnotationOptions()
76+
.withIconColor(ColorUtils.colorToRgbaString(Color.RED))
77+
.withIconImage("car-15")
78+
.withDraggable(true)
79+
.withIconAnchor(IconAnchor.CENTER)
80+
.withIconHaloBlur(1.0)
81+
.withIconHaloColor(ColorUtils.colorToRgbaString(Color.YELLOW))
82+
.withIconHaloWidth(2.0)
83+
.withIconOffset(listOf(1.0, 2.0))
84+
.withIconOpacity(0.8)
85+
.withIconRotate(0.5)
86+
.withIconSize(5.0)
87+
.withIconHaloColor(ColorUtils.colorToRgbaString(Color.WHITE))
88+
.withSymbolSortKey(1.0)
89+
.withTextAnchor(TextAnchor.TOP)
90+
.withTextColor(ColorUtils.colorToRgbaString(Color.YELLOW))
91+
.withTextField("Car")
92+
.withTextHaloBlur(1.0)
93+
.withTextHaloWidth(5.0)
94+
.withTextJustify(TextJustify.CENTER)
95+
.withTextLetterSpacing(2.0)
96+
.withTextRotate(5.0)
97+
.withTextTransform(TextTransform.UPPERCASE)
98+
.withTextSize(15.0)
99+
.withTextRadialOffset(1.0)
100+
.withTextOffset(listOf(1.0, 2.0))
101+
.withTextMaxWidth(10.0)
102+
.withPoint(Point.fromLngLat(0.0, 0.0))
103+
)
104+
for (i in 0..100) {
105+
// Verify there is no ConcurrentModificationException https://github.com/mapbox/mapbox-maps-android/issues/383
106+
pointAnnotation.textOpacity = 0.8
107+
Thread.sleep(0, 2000)
108+
}
109+
latch.countDown()
110+
}
111+
if (!latch.await(3000, TimeUnit.MILLISECONDS)) {
112+
throw TimeoutException()
104113
}
105114
Assert.assertEquals(pointAnnotation, pointAnnotationManager.annotations[0])
106115
}

app/src/androidTest/java/com/mapbox/maps/testapp/annotation/UpdateAnnotationWithMultiManagersTest.kt

Lines changed: 30 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -91,48 +91,56 @@ class UpdateAnnotationWithMultiManagersTest : BaseMapTest() {
9191

9292
Thread {
9393
for (i in 1..updateTimes) {
94-
pointAnnotation.point = Point.fromLngLat(
95-
pointAnnotation.point.longitude() + updateSteps,
96-
pointAnnotation.point.latitude() + updateSteps
97-
)
98-
pointAnnotationManager.update(pointAnnotation)
94+
handler.post {
95+
pointAnnotation.point = Point.fromLngLat(
96+
pointAnnotation.point.longitude() + updateSteps,
97+
pointAnnotation.point.latitude() + updateSteps
98+
)
99+
pointAnnotationManager.update(pointAnnotation)
100+
}
99101
Thread.sleep(10)
100102
}
101103
latch.countDown()
102104
}.start()
103105

104106
Thread {
105107
for (i in 1..updateTimes) {
106-
circleAnnotation.point = Point.fromLngLat(
107-
circleAnnotation.point.longitude() + updateSteps,
108-
circleAnnotation.point.latitude() + updateSteps
109-
)
110-
circleAnnotationManager.update(circleAnnotation)
108+
handler.post {
109+
circleAnnotation.point = Point.fromLngLat(
110+
circleAnnotation.point.longitude() + updateSteps,
111+
circleAnnotation.point.latitude() + updateSteps
112+
)
113+
circleAnnotationManager.update(circleAnnotation)
114+
}
111115
Thread.sleep(10)
112116
}
113117
latch.countDown()
114118
}.start()
115119

116120
Thread {
117121
for (i in 1..updateTimes) {
118-
points[0][0] = Point.fromLngLat(
119-
points[0][0].longitude() + updateSteps,
120-
points[0][0].latitude() + updateSteps
121-
)
122-
polygonAnnotation.points = points
123-
polygonAnnotationManager.update(polygonAnnotation)
122+
handler.post {
123+
points[0][0] = Point.fromLngLat(
124+
points[0][0].longitude() + updateSteps,
125+
points[0][0].latitude() + updateSteps
126+
)
127+
polygonAnnotation.points = points
128+
polygonAnnotationManager.update(polygonAnnotation)
129+
}
124130
Thread.sleep(10)
125131
}
126132
latch.countDown()
127133
}.start()
128134
Thread {
129135
for (i in 1..updateTimes) {
130-
polylinePoints[0] = Point.fromLngLat(
131-
polylinePoints[0].longitude() + updateSteps,
132-
polylinePoints[0].latitude() + updateSteps
133-
)
134-
polylineAnnotation.points = polylinePoints
135-
polylineAnnotationManager.update(polylineAnnotation)
136+
handler.post {
137+
polylinePoints[0] = Point.fromLngLat(
138+
polylinePoints[0].longitude() + updateSteps,
139+
polylinePoints[0].latitude() + updateSteps
140+
)
141+
polylineAnnotation.points = polylinePoints
142+
polylineAnnotationManager.update(polylineAnnotation)
143+
}
136144
Thread.sleep(10)
137145
}
138146
latch.countDown()

0 commit comments

Comments
 (0)