我正在尝试在JSON对象中获取JSON数组并将其存储到称为store的数据类中。
我有一个self.addEventListener("install", function(event) {
console.log("serviceWorker installing…");
const installCompleted=Promise.resolve().then(function() {
console.log("serviceWorker installed");
});
event.waitUntil(installCompleted);
});
self.addEventListener("activate", function(event) {
console.log("serviceWorker activating…");
const activationCompleted=Promise.resolve().then(function() {
console.log("serviceWorker activated");
});
event.waitUntil(activationCompleted);
});
self.addEventListener("DOMContentLoaded", function() {
//code to handle events from nodeJS (server) and notifications
}
,它存储了一个data class Data
引用。 List<Store>
是我真正需要的。现在,通过改造和Kotlin协程,我试图获取商店数据并将其存储在Store
中并访问其大小。
但是,这样做很麻烦,因为当我最后使用var storeData
和async{...}
时,它给了我一个.await()
类型的对象,而我无法访问Deferred
.size
属性
示例JSON数据
List<Store>
StoreViewModel.kt
stores: [
{
address: "7801 Citrus Park Town Center Mall",
city: "Tampa",
name: "Macy's",
latitude: "28.068052",
zipcode: "33625",
storeLogoURL: "https://www.macys.com/img/nav/co_macysLogo3.jpeg",
phone: "813-926-7300",
longitude: "-82.573301",
storeID: "1234",
state: "FL"
},
{...
StoreApiService.kt
import android.app.Application
import android.util.Log
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.brandroidtest.Model.Data
import com.example.brandroidtest.Model.Store
import com.example.brandroidtest.network.StoreAPI
import kotlinx.coroutines.*
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response
class StoreViewModel: ViewModel() {
// Response from server: Either Store Data or Failure Message
private val _response = MutableLiveData<String>()
// Same data but will be used to display in textview in MainListActivity
val response: LiveData<String>
get() = _response
private var viewModelJob = Job()
private val coroutineScope = CoroutineScope( viewModelJob + Dispatchers.Main)
/**
* Call getStoreData() on init so we can display status immediately.
*/
init {
getStoreData()
}
/**
* Sets the value of the response LiveData to the Store API data.
*/
//This is the first attempt, .await() is not accessible in this one
private fun getStoreData() {
coroutineScope.launch {
var data = StoreAPI.retrofitService.getData()
try {
var storeData = data.stores.await()
_response.value = "Success: ${storeData.size} Stores received"
}
catch (t: Throwable){
_response.value = "Failure: " + t.message
t.printStackTrace()
}
}
}
//This method is the other approach that I tried. size is not accessable in this //one
// private fun getStoreData() {
//
// coroutineScope.launch {
// var storeData = async{ StoreAPI.retrofitService.getData()}.await()
// try {
//
// _response.value = "Success: ${storeData.size} Stores received"
// }
// catch (t: Throwable){
// _response.value = "Failure: " + t.message
// t.printStackTrace()
//
// }
//
// }
//
//
// }
override fun onCleared() {
super.onCleared()
viewModelJob.cancel()
}
}
Data.kt
import com.example.brandroidtest.Model.Data
import com.squareup.moshi.Moshi
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
import kotlinx.coroutines.Deferred
import retrofit2.Call
import retrofit2.Retrofit
import retrofit2.converter.moshi.MoshiConverterFactory
import retrofit2.http.GET
private const val URL = "http://sandbox.bottlerocketapps.com/BR_Android_CodingExam_2015_Server/"
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
private val retrofit = Retrofit.Builder()
.addConverterFactory(MoshiConverterFactory.create(moshi))
.baseUrl(URL)
.build()
interface StoreAPIService{
//Initially was using Jake Wharton's library for retrofit2 kotlin coroutines support but it has been deprecated since the support
// addition of the suspend keyword in retrofit 2.6.0
//Suspend does all the task of coroutines for us by just adding it before the function declaration
@GET("stores.json")
suspend fun getData():
Data //return Data object because Data has access to the Store JSON Object/Array
}
object StoreAPI{
val retrofitService: StoreAPIService by lazy {
retrofit.create(StoreAPIService::class.java)
}
}
作为参考,我正在关注Udacity的Kotlin课程开发Android应用程序。