如何在Retrofit的onResponse()方法内设置全局值并传递给覆盖函数?

问题描述 投票:0回答:1

我正在尝试获取一个JSON对象,该对象是travel_history的列表。我正确地设法获取了所有数据。

我的目标是使用本travel_history列表中可用的经点来计算最小距离。而且我也做到了。

现在,我想将此计算的最小距离lat长传递给onMapReady()函数。我尝试了所有可能的方法。我对此进行了搜索,发现我在异步onResponse()方法中调用了calculateDistance(),因此我创建了TravelHistoryInterface(),然后在那里调用DistanceCalculator,但结果相同。

[请帮助我在onMapReady()函数中传递destinationLat destinationLong

P.S .:地图运行正常。我添加了所有必要的方法。其他所有支持功能(例如distanceCalculator())都可以正常工作。

class MapsActivity : AppCompatActivity(), TravelHistoryInterface, OnMapReadyCallback {


private var mTravelLocations: MutableList<Travel_HistoryDTO> = ArrayList()
private var minDistance: Double = 1000000000.0
lateinit var strList1: List<String>
var mylat: Double = 0.0
var mylung: Double = 0.0
var destinationLat: Double = 0.0
var destinationLong: Double = 0.0
private var locationName: String = " "


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_maps)

    apiCall(this)

}    

fun apiCall(@Nullable callback: TravelHistoryInterface?) {

    val apiInterface = ApiInterface.create().getTravelHistory()
    apiInterface.enqueue(
        object : Callback<TravelHistoryListDTO> {
            override fun onFailure(call: Call<TravelHistoryListDTO>, t: Throwable) {
                Log.i("hithere2", "failure")
                if (callback != null){
                    callback.onError(t);
                }
            }

            override fun onResponse(
                call: Call<TravelHistoryListDTO>,
                response: Response<TravelHistoryListDTO>
            ) {
                val travleLocations = response.body()

                if (callback != null){
                    callback.onSuccess(travleLocations);
                }

            }

        }
    )
}

override fun onSuccess(value: TravelHistoryListDTO?) {
    value?.travel_history?.let { calculateDistancePart(it) }
    mTravelLocations= value?.travel_history!!
}

override fun onError(throwable: Throwable) {
    //
}

private fun calculateDistancePart(mmTravel: MutableList<Travel_HistoryDTO>) {
    for (items in mmTravel) {
        val siz: Int = items.latlong.toString().length

        if (items._cn6ca == "15") {
            continue
        }
        for (x in 0 until siz) {
            //trim lat lung
            strList1 = items.latlong.toString().split(',').map { it.trim() }

        }
        if (strList1[0].isEmpty() || strList1[1].isEmpty()) {
            continue
        }

        )

        val thisDistance: Double = DistanceCalculator(
            mylat,
            mylung,
            strList1[0].toDouble(),
            strList1[1].toDouble(),
            "K"
        )
        if (thisDistance < minDistance) {
            Log.i("hahai", thisDistance.toString())
            minDistance = min(minDistance, thisDistance)
            destinationLat = strList1[0].toDouble()
            destinationLong = strList1[1].toDouble()
            locationName = items.address.toString()
        }
    }
}


override fun onMapReady(googleMap: GoogleMap?) {

    Log.i("bhaiproblem", destinationLat.toString() + " " + destinationLong.toString())
    val sydney = LatLng(destinationLat, destinationLong)
    googleMap?.addMarker(MarkerOptions().position(sydney).title(locationName))
    googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f))
  }
}

// TravelHistoryInterface

interface TravelHistoryInterface {
fun onSuccess(@NonNull value: TravelHistoryListDTO?)

fun onError(@NonNull throwable: Throwable)
}
android asynchronous kotlin interface retrofit2
1个回答
0
投票

我已经尽力减少了,您的代码有很多探针,就像您在调用min()一样,即使在检查了哪一个较小的代码之后,也对calculateDistancePart内的循环进行了设置。无缘无故的strList1太多次。

class MapsActivity : AppCompatActivity(), OnMapReadyCallback {

    private val scope = CoroutineScope(Dispatchers.Default)
    private lateinit var fetchJob: Job

    private var mTravelLocations: MutableList<Travel_HistoryDTO> = ArrayList()
    private var minDistance: Double = 1_000_000_000.0
    var mylat: Double = 0.0
    var mylung: Double = 0.0
    var destinationLat: Double = 0.0
    var destinationLong: Double = 0.0
    private var locationName: String = ""


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_maps)

        fetchJob = scope.launch {
            try {
                val result = apiCall()
            } catch (t: Throwable) {
                // do sth with error
            }

            result.travel_history
                ?.let { calculateDistancePart(it) }
                .apply { mTravelLocations = travel_history!! }
        }
    }

    private suspend fun apiCall() = suspendCancellableCoroutine<TravelHistoryListDTO> { cont ->
        ApiInterface.create().getTravelHistory().enqueue(
            object : Callback<TravelHistoryListDTO> {
                override fun onFailure(call: Call<TravelHistoryListDTO>, t: Throwable) {
                    Log.i("hithere2", "failure")
                    cont.resumeWithException(t)
                }

                override fun onResponse(call: Call<TravelHistoryListDTO>, response: Response<TravelHistoryListDTO>) {
                    cont.resumeWith(response.body())
                }
            }
        )
    }

    private fun calculateDistancePart(mmTravel: MutableList<Travel_HistoryDTO>): Double {
        for (items in mmTravel) {
            if (items._cn6ca == "15") continue

            val strList1 = items.latlong.toString().split(',').map { it.trim() }
            if (strList1[0].isEmpty() || strList1[1].isEmpty()) continue

            val thisDistance: Double = DistanceCalculator(
                mylat,
                mylung,
                strList1[0].toDouble(),
                strList1[1].toDouble(),
                "K"
            )
            if (thisDistance < minDistance) {
                Log.i("hahai", thisDistance.toString())
                minDistance = thisDistance
                destinationLat = strList1[0].toDouble()
                destinationLong = strList1[1].toDouble()
                locationName = items.address.toString()
            }
        }
    }


    override fun onMapReady(googleMap: GoogleMap?) {
        Log.i("bhaiproblem", "$destinationLat $destinationLong")
        scope.launch {
            fetchJob.join()
            val sydney = LatLng(destinationLat, destinationLong)
            googleMap?.addMarker(MarkerOptions().position(sydney).title(locationName))
            googleMap?.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 15f))
        }
    }
}

在您的项目中添加协程,通过使其看起来像是同步的(但是异步的),它将减少异步代码的开销,并通过使用CoroutineContext轻松更改线程。

热门问题
推荐问题
最新问题