From dab2f54542d151c92dcba04bd9833280e9728e2d Mon Sep 17 00:00:00 2001
From: 18034727885 <973609879@qq.com>
Date: 星期二, 18 八月 2026 13:57:55 +0800
Subject: [PATCH] 修复问题

---
 app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt |   96 +++++++++++++++++++++++++++++++----------------
 1 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt b/app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt
index f9d227b..90b5cb5 100644
--- a/app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt
+++ b/app/src/main/java/com/driver/igotrip/base/gaode/NaviGoogleActivity.kt
@@ -11,7 +11,7 @@
 import com.driver.igotrip.base.MyApplication
 import com.driver.igotrip.base.MyBaseActivity
 import com.google.android.gms.maps.GoogleMap
-import com.google.android.gms.maps.model.LatLng
+import com.google.android.libraries.navigation.ListenableResultFuture
 import com.google.android.libraries.navigation.NavigationApi
 import com.google.android.libraries.navigation.NavigationApi.NavigatorListener
 import com.google.android.libraries.navigation.Navigator
@@ -22,19 +22,26 @@
 import com.google.android.libraries.navigation.SupportNavigationFragment
 import com.google.android.libraries.navigation.Waypoint
 import com.google.android.libraries.navigation.Waypoint.UnsupportedPlaceIdException
+import java.lang.ref.WeakReference
 
 
 class NaviGoogleActivity : MyBaseActivity() {
-    override fun setContentView() {
-        setContentView(R.layout.activity_navgoogle)
-    }
+
+    // 使用弱引用避免匿名内部类泄漏
+    private val activityWeakRef = WeakReference(this)
 
     private var mNavigator: Navigator? = null
     private var mNavFragment: SupportNavigationFragment? = null
     private var mRoutingOptions: RoutingOptions? = null
+    private var pendingRoute: ListenableResultFuture<RouteStatus>? = null
+    private var arrivalListener: Navigator.ArrivalListener? = null
     private var roadSnappedLocationProvider: RoadSnappedLocationProvider? = null
     private val lat by lazy { intent.getDoubleExtra("lat", 0.0) }
     private val lon by lazy { intent.getDoubleExtra("lon", 0.0) }
+
+    override fun setContentView() {
+        setContentView(R.layout.activity_navgoogle)
+    }
 
     override fun initView() {
         showTitle(false)
@@ -58,9 +65,10 @@
              */
             @SuppressLint("MissingPermission")
             override fun onNavigatorReady(navigator: Navigator) {
+                val activity = activityWeakRef.get() ?: return
                 Log.e(Const.GoogleDriver.TAG, "Navigator ready.")
-                mNavigator = navigator
-                mNavFragment =
+                activity.mNavigator = navigator
+                activity.mNavFragment =
                     supportFragmentManager.findFragmentById(R.id.navigation_fragment) as SupportNavigationFragment
 
                 // Set the last digit of the car's license plate to get route restrictions
@@ -68,23 +76,22 @@
                 // mNavigator.setLicensePlateRestrictionInfo(getLastDigit(), "BZ");
 
                 // Set the camera to follow the device location with 'TILTED' driving view.
-                mNavFragment?.getMapAsync {
+                activity.mNavFragment?.getMapAsync {
                     it.followMyLocation(GoogleMap.CameraPerspective.TILTED)
-
                 }
-                mNavFragment
                 // Set the travel mode (DRIVING, WALKING, CYCLING, or TWO_WHEELER).
-                mRoutingOptions = RoutingOptions()
-                mRoutingOptions?.travelMode(RoutingOptions.TravelMode.DRIVING)
-
-                navigator.addArrivalListener {
-                    finish()
+                activity.mRoutingOptions = RoutingOptions()
+                activity.mRoutingOptions?.travelMode(RoutingOptions.TravelMode.DRIVING)
+                // 保存 ArrivalListener 以便后续移除
+                activity.arrivalListener = Navigator.ArrivalListener {
+                    activity.finish()
                 }
+                navigator.addArrivalListener(activity.arrivalListener!!)
 
                 // Navigate to a place
-                navigateToPlace(lat, lon)
+                activity.navigateToPlace(lat, lon)
 
-                initLocationListener()
+                activity.initLocationListener()
             }
 
             /**
@@ -92,24 +99,25 @@
              * @param errorCode The error code returned by the navigator.
              */
             override fun onError(@NavigationApi.ErrorCode errorCode: Int) {
+                val activity = activityWeakRef.get() ?: return
                 when (errorCode) {
-                    NavigationApi.ErrorCode.NOT_AUTHORIZED -> displayMessage(
+                    NavigationApi.ErrorCode.NOT_AUTHORIZED -> activity.displayMessage(
                         "Error loading Navigation SDK: Your API key is "
                                 + "invalid or not authorized to use the Navigation SDK."
                     )
 
-                    NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> displayMessage(
+                    NavigationApi.ErrorCode.TERMS_NOT_ACCEPTED -> activity.displayMessage(
                         ("Error loading Navigation SDK: User did not accept "
                                 + "the Navigation Terms of Use.")
                     )
 
-                    NavigationApi.ErrorCode.NETWORK_ERROR -> displayMessage("Error loading Navigation SDK: Network error.")
-                    NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING -> displayMessage(
+                    NavigationApi.ErrorCode.NETWORK_ERROR -> activity.displayMessage("Error loading Navigation SDK: Network error.")
+                    NavigationApi.ErrorCode.LOCATION_PERMISSION_MISSING -> activity.displayMessage(
                         ("Error loading Navigation SDK: Location permission "
                                 + "is missing.")
                     )
 
-                    else -> displayMessage("Error loading Navigation SDK: $errorCode")
+                    else -> activity.displayMessage("Error loading Navigation SDK: $errorCode")
                 }
             }
 
@@ -121,42 +129,45 @@
         val destination: Waypoint = try {
             Waypoint.builder().setLatLng(lat, lon).build()
         } catch (e: UnsupportedPlaceIdException) {
+            e.printStackTrace()
             displayMessage("Error starting navigation: Place ID is not supported.")
             return
         }
 
         // Create a future to await the result of the asynchronous navigator task.
-        val pendingRoute = mNavigator!!.setDestination(destination, mRoutingOptions)
+        pendingRoute = mNavigator?.setDestination(destination, mRoutingOptions)
 
         // Define the action to perform when the SDK has determined the route.
-        pendingRoute.setOnResultListener { code ->
+        pendingRoute?.setOnResultListener { code ->
+            // 使用弱引用避免 Activity 泄漏
+            val activity = activityWeakRef.get() ?: return@setOnResultListener
             when (code) {
                 RouteStatus.OK -> {
                     // Hide the toolbar to maximize the navigation UI.
-                    if (actionBar != null) {
-                        actionBar!!.hide()
+                    if (activity.actionBar != null) {
+                        activity.actionBar!!.hide()
                     }
 
                     // Enable voice audio guidance (through the device speaker).
-                    mNavigator!!.setAudioGuidance(
+                    activity.mNavigator?.setAudioGuidance(
                         Navigator.AudioGuidance.VOICE_ALERTS_AND_GUIDANCE
                     )
 
                     // Simulate vehicle progress along the route for demo/debug builds.
                     if (BuildConfig.DEBUG) {
-                        mNavigator!!.simulator.simulateLocationsAlongExistingRoute(
+                        activity.mNavigator?.simulator?.simulateLocationsAlongExistingRoute(
                             SimulationOptions().speedMultiplier(5f)
                         )
                     }
 
                     // Start turn-by-turn guidance along the current route.
-                    mNavigator!!.startGuidance()
+                    activity.mNavigator?.startGuidance()
                 }
 
-                RouteStatus.NO_ROUTE_FOUND -> displayMessage("Error starting navigation: No route found.")
-                RouteStatus.NETWORK_ERROR -> displayMessage("Error starting navigation: Network error.")
-                RouteStatus.ROUTE_CANCELED -> displayMessage("Error starting navigation: Route canceled.")
-                else -> displayMessage(
+                RouteStatus.NO_ROUTE_FOUND -> activity.displayMessage("Error starting navigation: No route found.")
+                RouteStatus.NETWORK_ERROR -> activity.displayMessage("Error starting navigation: Network error.")
+                RouteStatus.ROUTE_CANCELED -> activity.displayMessage("Error starting navigation: Route canceled.")
+                else -> activity.displayMessage(
                     "Error starting navigation: "
                             + code.toString()
                 )
@@ -166,7 +177,7 @@
 
     override fun onEventMainThread(event: BaseEvent?) {
         if (event?.code == BaseEvent.RELOAD_NAVI) {
-            navigateToPlace(event!!.msg.toDouble(), event.msgTwo.toDouble())
+            navigateToPlace(event.msg.toDouble(), event.msgTwo.toDouble())
         }
     }
 
@@ -196,8 +207,27 @@
 
     override fun onDestroy() {
         super.onDestroy()
+        // 1. 停止导航
         mNavigator?.stopGuidance()
+
+        // 2. 移除 ArrivalListener
+        arrivalListener?.let { mNavigator?.removeArrivalListener(it) }
+
+        // 3. 取消待定路由请求
+        pendingRoute?.cancel(true)
+
+        // 4. 移除位置监听
         removeLocationListener()
+
+        // 5. 释放 Navigator(如果有 shutdown 方法)
+        // mNavigator?.shutdown()
+
+        // 清空引用
+        mNavigator = null
+        mNavFragment = null
+        mRoutingOptions = null
+        pendingRoute = null
+        arrivalListener = null
     }
 
     //初始化定位监听

--
Gitblit v1.7.1