ThreadController when used by standalone components
Refs https://github.com/mapbox/mapbox-navigation-android/pull/4816#issuecomment-922948108.

A lot of components in the SDK rely on the `ThreadController` object to provide coroutine scopes for children jobs to run.

Some of the components also rely on `MapboxNavigation#onDestroy` call that cleans up the `ThreadController` children jobs to avoid leaks.

However, if a component is standalone, it can have a different lifecycle than `MapboxNavigation` which can cause various types of leaks and issues. For example, `ThreadController#init` called from the `MapboxNavigation` constructor:
https://github.com/mapbox/mapbox-navigation-android/blob/d5f2041a7ee3ea8001a0762b91c91ed2e9792752/libnavigation-util/src/main/java/com/mapbox/navigation/utils/internal/ThreadController.kt#L62-L65

overrides parent jobs. So if there was a coroutine running via `ThreadController` and only then `MapboxNavigation` was created, calling `MapboxNavigation#onDestroy` would not cancel the previously running coroutine, nor should it, but some components expect it.

I think destroying `MapboxNavigation` should cancel only the coroutines tied to the `MapboxNavigation` object's lifecycle, and each standalone component should have its own cancellation method.

cc @mapbox/navigation-android 
diff --git a/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxRouteLineAndArrowActivity.kt b/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxRouteLineAndArrowActivity.kt
index e52bd2078f..3c875db3d2 100644
--- a/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxRouteLineAndArrowActivity.kt
+++ b/examples/src/main/java/com/mapbox/navigation/examples/core/MapboxRouteLineAndArrowActivity.kt
@@ -481,6 +481,7 @@ class MapboxRouteLineAndArrowActivity : AppCompatActivity(), OnMapLongClickListe
 
     override fun onDestroy() {
         super.onDestroy()
+        routeLineApi.cancel()
         mapboxNavigation.onDestroy()
     }
 
diff --git a/examples/src/main/java/com/mapbox/navigation/examples/core/MultiLegRouteExampleActivity.kt b/examples/src/main/java/com/mapbox/navigation/examples/core/MultiLegRouteExampleActivity.kt
index 4ea65abea4..1b81f22ebf 100644
--- a/examples/src/main/java/com/mapbox/navigation/examples/core/MultiLegRouteExampleActivity.kt
+++ b/examples/src/main/java/com/mapbox/navigation/examples/core/MultiLegRouteExampleActivity.kt
@@ -214,6 +214,7 @@ class MultiLegRouteExampleActivity : AppCompatActivity() {
 
     override fun onDestroy() {
         super.onDestroy()
+        routeLineApi.cancel()
         viewBinding.mapView.onDestroy()
         mapboxNavigation.onDestroy()
     }
diff --git a/examples/src/main/java/com/mapbox/navigation/examples/core/ReplayHistoryActivity.kt b/examples/src/main/java/com/mapbox/navigation/examples/core/ReplayHistoryActivity.kt
index d5033a76ee..9466e7524b 100644
--- a/examples/src/main/java/com/mapbox/navigation/examples/core/ReplayHistoryActivity.kt
+++ b/examples/src/main/java/com/mapbox/navigation/examples/core/ReplayHistoryActivity.kt
@@ -115,6 +115,7 @@ class ReplayHistoryActivity : AppCompatActivity() {
 
     override fun onDestroy() {
         super.onDestroy()
+        routeLineApi.cancel()
         findViewById<MapView>(R.id.mapView).onDestroy()
         mapboxNavigation.onDestroy()
         if (::locationComponent.isInitialized) {
diff --git a/libnavui-maps/api/current.txt b/libnavui-maps/api/current.txt
index e3a8636b45..528e75c8b0 100644
--- a/libnavui-maps/api/current.txt
+++ b/libnavui-maps/api/current.txt
@@ -710,6 +710,7 @@ package com.mapbox.navigation.ui.maps.route.line.api {
 
   public final class MapboxRouteLineApi {
     ctor public MapboxRouteLineApi(com.mapbox.navigation.ui.maps.route.line.model.MapboxRouteLineOptions routeLineOptions);
+    method public void cancel();
     method public void clearRouteLine(com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer<com.mapbox.bindgen.Expected<com.mapbox.navigation.ui.maps.route.line.model.RouteLineError,com.mapbox.navigation.ui.maps.route.line.model.RouteLineClearValue>> consumer);
     method public void findClosestRoute(com.mapbox.geojson.Point target, com.mapbox.maps.MapboxMap mapboxMap, float padding, com.mapbox.navigation.ui.base.util.MapboxNavigationConsumer<com.mapbox.bindgen.Expected<com.mapbox.navigation.ui.maps.route.line.model.RouteNotFound,com.mapbox.navigation.ui.maps.route.line.model.ClosestRouteValue>> resultConsumer);
     method public com.mapbox.api.directions.v5.models.DirectionsRoute? getPrimaryRoute();
diff --git a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt
index a65bf81b55..1a56501e8f 100644
--- a/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt
+++ b/libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt
@@ -670,6 +670,15 @@ class MapboxRouteLineApi(
         }
     }
 
+    /**
+     * Invoke the function to cancel any job invoked through this API.
+     */
+    fun cancel() {
+        jobControl.job.children.forEach {
+            it.cancel()
+        }
+    }
+
     private suspend fun findClosestRoute(
         target: Point,
         mapboxMap: MapboxMap,
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingActivity.kt b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingActivity.kt
index e53db4de94..481fdcdf44 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingActivity.kt
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingActivity.kt
@@ -113,6 +113,7 @@ class InactiveRouteStylingActivity : AppCompatActivity() {
     override fun onDestroy() {
         super.onDestroy()
         mapboxNavigation.onDestroy()
+        routeLineApi.cancel()
     }
 
     private fun initNavigation() {
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingWithRestrictionsActivity.kt b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingWithRestrictionsActivity.kt
index f775af43d3..2d58253c08 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingWithRestrictionsActivity.kt
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingWithRestrictionsActivity.kt
@@ -123,6 +123,7 @@ class InactiveRouteStylingWithRestrictionsActivity : AppCompatActivity() {
     override fun onDestroy() {
         super.onDestroy()
         mapboxNavigation.onDestroy()
+        routeLineApi.cancel()
     }
 
     private fun initNavigation() {
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/MapboxRouteLineActivity.java b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/MapboxRouteLineActivity.java
index c6874e8d65..6292c7c8d0 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/MapboxRouteLineActivity.java
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/MapboxRouteLineActivity.java
@@ -299,6 +299,7 @@ public class MapboxRouteLineActivity extends AppCompatActivity implements OnMapL
   @Override
   protected void onDestroy() {
     super.onDestroy();
+    mapboxRouteLineApi.cancel();
     if (predictiveCacheController != null) {
       predictiveCacheController.onDestroy();
     }
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteRestrictionsActivity.kt b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteRestrictionsActivity.kt
index 5d179d7a51..bce218b3ee 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteRestrictionsActivity.kt
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteRestrictionsActivity.kt
@@ -135,6 +135,7 @@ class RouteRestrictionsActivity : AppCompatActivity() {
     override fun onDestroy() {
         super.onDestroy()
         mapboxNavigation.onDestroy()
+        routeLineApi.cancel()
     }
 
     private fun initStyle() {
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteTrafficUpdateActivity.kt b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteTrafficUpdateActivity.kt
index a15a5dbdda..f6b7b57a4a 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteTrafficUpdateActivity.kt
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteTrafficUpdateActivity.kt
@@ -76,6 +76,7 @@ class RouteTrafficUpdateActivity : AppCompatActivity() {
 
     override fun onDestroy() {
         super.onDestroy()
+        routeLineApi.cancel()
         binding.mapView.onDestroy()
     }
 
diff --git a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/TrafficGradientActivity.kt b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/TrafficGradientActivity.kt
index faad4163f9..410fe4e438 100644
--- a/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/TrafficGradientActivity.kt
+++ b/qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/TrafficGradientActivity.kt
@@ -55,6 +55,11 @@ class TrafficGradientActivity : AppCompatActivity() {
         initStyle()
     }
 
+    override fun onDestroy() {
+        super.onDestroy()
+        routeLineApi.cancel()
+    }
+
     private fun initGradientSelector() {
         binding.gradientOptionHard.setOnClickListener {
             options = options.toBuilder(this)
['qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingWithRestrictionsActivity.kt', 'qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteRestrictionsActivity.kt', 'examples/src/main/java/com/mapbox/navigation/examples/core/MultiLegRouteExampleActivity.kt', 'libnavui-maps/src/main/java/com/mapbox/navigation/ui/maps/route/line/api/MapboxRouteLineApi.kt', 'qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/InactiveRouteStylingActivity.kt', 'libnavui-maps/api/current.txt', 'qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/MapboxRouteLineActivity.java', 'examples/src/main/java/com/mapbox/navigation/examples/core/ReplayHistoryActivity.kt', 'qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/RouteTrafficUpdateActivity.kt', 'qa-test-app/src/main/java/com/mapbox/navigation/qa_test_app/view/TrafficGradientActivity.kt', 'examples/src/main/java/com/mapbox/navigation/examples/core/MapboxRouteLineAndArrowActivity.kt']