Периодически получать обновленный ответ OkHttp с помощью архитектуры Android: LiveData и обновлять маркеры карты - PullRequest
0 голосов
/ 31 января 2019

Я сделал транспортное приложение, которое показывает местоположение автобусов.В настоящее время я пытаюсь реорганизовать свой код, чтобы я мог плавно анимировать маркеры (места расположения шин) и увидел, что LiveData может быть полезен для очистки моего кода.Я использую OkHttp, чтобы сделать мои запросы, репозиторий, чтобы вернуть mutableList типа BusInfo, а затем создать маркеры из изменяемого списка busInfo.Моя настоящая проблема заключается в том, что мой первый вызов ViewModel работает, но затем, когда я пытаюсь создать новый экземпляр модели представления и получить обновленный daya, я возвращаю те же самые данные из первого экземпляра репозитория, и новый экземпляр не создается,Есть ли какой-нибудь совет о том, как периодически получать новый изменяемый список businfo из моей модели просмотра и обновлять положение маркеров на карте.Кто-нибудь может мне помочь?я достаточно новичок в Kotlin и Android Dev в целом.

class MapsFragment : Fragment(), OnMapReadyCallback {

private var mBusMap = HashMap<String, MarkerOptions>()
private var mBusHashMapUpdated = HashMap<String, MarkerOptions>()

val mBusInfoViewModel: BusInfoViewModel get() =
    ViewModelProviders.of(this).get(BusInfoViewModel::class.java)

private fun createBusMarkers(busMap:HashMap<String, MarkerOptions>,buses: MutableList<BusInfo>) {
    try {
        requireActivity().runOnUiThread {
            buses.forEach { bus ->
                busMap[bus.licenseNum] = createMarker(
                    bus.licenseNum,
                    LatLng(bus.lat, bus.long),
                    createScaledBitmap(R.drawable.bus_icon_green),
                    bus.licenseNum,
                    bus.direction,
                    bus.speed
                )
                busMap.forEach { s, marker ->
                    mMap.addMarker(marker)
                }
            }
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }
}

override fun onMapReady(googleMap: GoogleMap) {
    mMap = googleMap

    mBusInfoViewModel.reposResult.observe(this, android.arch.lifecycle.Observer {
        if (it != null) {
            createBusMarkers(mBusMap, it)
        }
    })
    updateBusesPeriodically()
}

private fun updateBusesPeriodically() {
    val timer = Timer()
    GlobalScope.launch {
        timer.scheduleAtFixedRate(10000, 10000) {                 
            updateBusMarkers()
        }
    }
}
private fun updateBusMarkers() {
        busInfoViewModel.reposResult.observe(this, android.arch.lifecycle.Observer {
            if (it != null) {
                createBusMarkers(mBusHashMapUpdated, it)
            }
        }
...animate each marker moving from old position to new position
)}
    }

Я создал модель представления для возврата списка Mutable типа BusInfo в представление успешного ответа из запроса OkHttp.

class BusInfoViewModel : ViewModel() {
val reposResult = MutableLiveData<MutableList<BusInfo>>()

private var busInfoRepository = BusInfoRepository.instance()

init {
    loadBusInfoListFromUrl()
}

fun loadBusInfoListFromUrl(): MutableList<BusInfo> {
    return busInfoRepository.getBusInfoListFromResponseBody { repos ->
        reposResult.postValue(repos)
    }
}

Я добавил класс репозитория для получения данных из http-запроса и возврата списка шин

class BusInfoRepository {

fun getBusInfoListFromResponseBody(completion: (MutableList<BusInfo>) -> Unit): MutableList<BusInfo> {
    val request = Request.Builder().url(url).build()
    val client = OkHttpClient()
    var buses = mutableListOf<BusInfo>()
    client.newCall(request).enqueue(object : Callback {

        override fun onResponse(call: okhttp3.Call?, response: okhttp3.Response?) {
            val stringResponse = response?.body()?.string()
            buses = createBusesFromResponseBody(stringResponse)
            completion(buses)
        }

        override fun onFailure(call: okhttp3.Call?, e: IOException?) {
            Log.e("Http API call failed", e?.message)
        }
    })
    return buses
}
}

1 Ответ

0 голосов
/ 07 февраля 2019

Я понял, что делал неправильно.Модель представления была создана и вызвано loadBusInfoListFromUrl(), заполнив reposResult.Проблема заключалась в том, что я никогда не обновлял значение reposResult после этого.В методе периодического обновления viewmodel я должен был вызывать mBusInfoViewModel.loadBusInfoListFromUrl() в методе updateBusMarkers.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...