我正在尝试向 SpaceX 发出 API 呼叫,但我的响应一直出错。我的 POJO 是问题所在吗?

I am trying to make an API call to SpaceX, but I keep getting an error on my response. Is my POJO the issue?

所以目前我正在尝试进行 API 调用以从 spacex 获取发射(https://api.spacexdata.com/v3/launches)。我无法判断 POJO 是否生成错误。出于某种原因,我不断收到此错误

E/AndroidRuntime: FATAL EXCEPTION: DefaultDispatcher-worker-1
    Process: com.example.spacex, PID: 13481
    com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path $
        at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:226)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
        at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
        at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
        at retrofit2.OkHttpCall.onResponse(OkHttpCall.java:121)
        at okhttp3.RealCall$AsyncCall.execute(RealCall.java:206)
        at okhttp3.internal.NamedRunnable.run(NamedRunnable.java:32)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:919)

但是当我调用 API 获取最新发布时,我得到了实际响应

I/Choreographer: Skipped 83 frames!  The application may be doing too much work on its main thread.
I/OpenGLRenderer: Davey! duration=1418ms; Flags=0, IntendedVsync=15042096638405, Vsync=15043479971683, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=15043493004500, AnimationStart=15043493189900, PerformTraversalsStart=15043494154700, DrawStart=15043498745100, SyncQueued=15043501592400, SyncStart=15043502485000, IssueDrawCommandsStart=15043502592300, SwapBuffers=15043503508300, FrameCompleted=15043516419500, DequeueBufferDuration=921000, QueueBufferDuration=671000, 
I/System.out: SpaceXResponse(missionName=CRS-20, staticFireDateUtc=2020-03-01T10:20:00.000Z, launchYear=2020, launchDateUtc=2020-03-07T04:50:31.000Z, launchFailureDetails=null, flightNumber=91, isTentative=false, rocket=Rocket(secondStage=SecondStage(payloads=[PayloadsItem(payloadType=Dragon 1.1, payloadMassKg=1977.0, payloadId=CRS-20, nationality=United States, noradId=[], customers=[NASA (CRS)], orbit=ISS, orbitParams=OrbitParams(periapsisKm=null, meanAnomaly=null, inclinationDeg=null, regime=low-earth, argOfPericenter=null, eccentricity=null, apoapsisKm=null, semiMajorAxisKm=null, raan=null, epoch=null, lifespanYears=null, referenceSystem=geocentric, periodMin=null, meanMotion=null, longitude=null), payloadMassLbs=4358.539, reused=true, manufacturer=SpaceX)], block=5.0), rocketId=falcon9, firstStage=FirstStage(cores=[CoresItem(flight=2, landingType=RTLS, gridfins=true, landingIntent=true, legs=true, landSuccess=true, landingVehicle=LZ-1, block=5.0, reused=true, coreSerial=B1059)]), rocketType=FT, rocketName=Falcon 9, fairings=null), missionId=[EE86F74], launchWindow=0, crew=null, launchDateLocal=2020-03-06T23:50:31-05:00, tentativeMaxPrecision=hour, ships=[], launchDateUnix=1583556631, launchSuccess=true, staticFireDateUnix=1583058000, tbd=false, timeline=null, telemetry=Telemetry(flightClub=null), links=Links(missionPatchSmall=https://i.imgur.com/LIrgTnt.png, missionPatch=https://i.imgur.com/LIrgTnt.png, videoLink=https://youtu.be/1MkcWK2PnsU, flickrImages=[], redditRecovery=null, redditMedia=null, redditCampaign=https://www.reddit.com/r/spacex/comments/ezn6n0/crs20_launch_campaign_thread, wikipedia=https://en.wikipedia.org/wiki/SpaceX_CRS-20, redditLaunch=https://www.reddit.com/r/spacex/comments/fe8pcj/rspacex_crs20_official_launch_discussion_updates/, youtubeId=1MkcWK2PnsU, presskit=https://www.spacex.com/sites/spacex/files/crs-20_mission_press_kit.pdf, articleLink=null), details=SpaceX's 20th and final Crew Resupply Mission under the original NASA CRS contract, this mission brings essential supplies to the International Space Station using SpaceX's reusable Dragon spacecraft. It is the last scheduled flight of a Dragon 1 capsule. (CRS-21 and up under the new Commercial Resupply Services 2 contract will use Dragon 2.) The external payload for this mission is the Bartolomeo ISS external payload hosting platform. Falcon 9 and Dragon will launch from SLC-40, Cape Canaveral Air Force Station and the booster will land at LZ-1. The mission will be complete with return and recovery of the Dragon capsule and down cargo., launchSite=LaunchSite(siteName=CCAFS SLC 40, siteId=ccafs_slc_40, siteNameLong=Cape Canaveral Air Force Station Space Launch Complex 40), upcoming=false)

这是我的 ViewModel

class MainViewModel : ViewModel() {
    private val spaceRepo : Repository = Repository(SpaceService.spaceApi)
    val spaceLiveData = liveData(Dispatchers.IO){
        val data = spaceRepo.getLaunch()
        emit(data)
        println(data)
    }
}

这是我的存储库

class Repository(private val apiInterface : SpaceXInterface) {
    suspend fun getLaunch() = apiInterface.fetchLaunches()
}

这是我的服务

object SpaceService{

   private const val BASE_URL : String = "https://api.spacexdata.com/"

   private val retrofit = Retrofit.Builder()
      .baseUrl(BASE_URL)
      .addConverterFactory(GsonConverterFactory.create())
      .addCallAdapterFactory(CoroutineCallAdapterFactory())
      .build()

   val spaceApi: SpaceXInterface = retrofit.create(SpaceXInterface::class.java)
}

这是我的界面

interface SpaceXInterface {

    @GET("v3/launches/latest")
    suspend fun fetchLaunches() : SpaceXResponse

}

这是我的回复 POJO

data class SpaceXResponse(

    @field:SerializedName("mission_name")
    val missionName: String? = null,

    @field:SerializedName("static_fire_date_utc")
    val staticFireDateUtc: String? = null,

    @field:SerializedName("launch_year")
    val launchYear: String? = null,

    @field:SerializedName("launch_date_utc")
    val launchDateUtc: String? = null,

    @field:SerializedName("launch_failure_details")
    val launchFailureDetails: LaunchFailureDetails? = null,

    @field:SerializedName("flight_number")
    val flightNumber: Int? = null,

    @field:SerializedName("is_tentative")
    val isTentative: Boolean? = null,

    @field:SerializedName("rocket")
    val rocket: Rocket? = null,

    @field:SerializedName("mission_id")
    val missionId: List<Any?>? = null,

    @field:SerializedName("launch_window")
    val launchWindow: Int? = null,

    @field:SerializedName("crew")
    val crew: Any? = null,

    @field:SerializedName("launch_date_local")
    val launchDateLocal: String? = null,

    @field:SerializedName("tentative_max_precision")
    val tentativeMaxPrecision: String? = null,

    @field:SerializedName("ships")
    val ships: List<Any?>? = null,

    @field:SerializedName("launch_date_unix")
    val launchDateUnix: Int? = null,

    @field:SerializedName("launch_success")
    val launchSuccess: Boolean? = null,

    @field:SerializedName("static_fire_date_unix")
    val staticFireDateUnix: Int? = null,

    @field:SerializedName("tbd")
    val tbd: Boolean? = null,

    @field:SerializedName("timeline")
    val timeline: Timeline? = null,

    @field:SerializedName("telemetry")
    val telemetry: Telemetry? = null,

    @field:SerializedName("links")
    val links: Links? = null,

    @field:SerializedName("details")
    val details: String? = null,

    @field:SerializedName("launch_site")
    val launchSite: LaunchSite? = null,

    @field:SerializedName("upcoming")
    val upcoming: Boolean? = null
)

错误说它返回一个列表而不是一个对象,你应该改变你的调用

interface SpaceXInterface {
    @GET("v3/launches/latest")
    suspend fun fetchLaunches() : List<SpaceXResponse>
}

并相应地更改其他部分。