简体   繁体   中英

Retrofit-Kotlin NullPointerException on non-null object type

I am facing a really weird issue while implementing GitHub API's using Retrofit and Kotlin .

This is my first time working on Andorid Arch and Retrofit so pardon me if i make any mistake in this question.

What exactly is happening is i am calling a GitHub API using Retrofit to fetch user's repositories. One repo have null in description . My app doesn't crash on that time when API returns null, it crashes when i am passing that object in Intent to another Activity . My Data Class is Parcelable .

Below is my Data Class:

data class GitHubRepository(
    var id: String = "",
    var name: String = "",
    var full_name: String = "",
    var owner: GitHubUser = GitHubUser(),
    var description: String = "",            // This is getting null even when it is of non-null type
    var html_url: String = "",
    var watchers_count: String = ""
) : Parcelable {
constructor(parcel: Parcel) : this(
        parcel.readString(),
        parcel.readString(),
        parcel.readString(),
        parcel.readParcelable(GitHubUser::class.java.classLoader),
        parcel.readString(),                // This is where i am getting error
        parcel.readString(),
        parcel.readString())

    override fun writeToParcel(parcel: Parcel, flags: Int) {
        parcel.writeString(id)
        parcel.writeString(name)
        parcel.writeString(full_name)
        parcel.writeParcelable(owner, flags)
        parcel.writeString(description)
        parcel.writeString(html_url)
        parcel.writeString(watchers_count)
    }

    override fun describeContents(): Int {
        return 0
    }

    companion object CREATOR : Parcelable.Creator<GitHubRepository> {
        override fun createFromParcel(parcel: Parcel): GitHubRepository {
            return GitHubRepository(parcel)
        }

        override fun newArray(size: Int): Array<GitHubRepository?> {
            return arrayOfNulls(size)
        }
    }
}

Below is how i am creating Retrofit object:

val BASE_URL = "https://api.github.com/"

private var retrofit: Retrofit? = null

fun getClient(): Retrofit {

    if (retrofit == null) {
        retrofit = Retrofit.Builder()
                .baseUrl(BASE_URL)
                .addConverterFactory(GsonConverterFactory.create())
                .build()
    }

    return retrofit!!
}

Below is My API Request:

@GET("users/{username}/repos")
fun getReposOfUser(
        @Path("username") username: String,
        @Query("page") pageNumber: Int,
        @Query("per_page") perPage: Int = 10
): Call<ArrayList<GitHubRepository>>

API that have null value in description: https://api.github.com/users/kislyuk/repos

Below is the Response:

[
...
{
    "id": 1924281,
    "name": "akutils",
    "full_name": "kislyuk/akutils",
    "owner": {...},
    "private": false,
    "html_url": "https://github.com/kislyuk/akutils",
    "description": null, // This is the null value
    ...
}
...
]

Below is the LogCat in which GitHubModels.kt is my Kotlin file which contains other data classes as well. The one with error is GitHubRepository data class which i displayed above:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.tarunchauhan.githubapp, PID: 18276
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.tarunchauhan.githubapp/com.tarunchauhan.githubapp.activities.RepoDetailsActivity}: java.lang.IllegalStateException: parcel.readString() must not be null
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
        at android.app.ActivityThread.-wrap11(Unknown Source:0)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
        at android.os.Handler.dispatchMessage(Handler.java:105)
        at android.os.Looper.loop(Looper.java:164)
        at android.app.ActivityThread.main(ActivityThread.java:6541)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
     Caused by: java.lang.IllegalStateException: parcel.readString() must not be null
        at com.tarunchauhan.githubapp.models.GitHubRepository.<init>(GitHubModels.kt:29)
        at com.tarunchauhan.githubapp.models.GitHubRepository$CREATOR.createFromParcel(GitHubModels.kt:49)
        at com.tarunchauhan.githubapp.models.GitHubRepository$CREATOR.createFromParcel(GitHubModels.kt:47)
        at android.os.Parcel.readParcelable(Parcel.java:2781)
        at android.os.Parcel.readValue(Parcel.java:2675)
        at android.os.Parcel.readArrayMapInternal(Parcel.java:3042)
        at android.os.BaseBundle.unparcel(BaseBundle.java:257)
        at android.os.Bundle.getParcelable(Bundle.java:888)
        at android.content.Intent.getParcelableExtra(Intent.java:7075)
        at com.tarunchauhan.githubapp.activities.RepoDetailsActivity.onCreate(RepoDetailsActivity.kt:51)
        at android.app.Activity.performCreate(Activity.java:6975)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
        at android.app.ActivityThread.-wrap11(Unknown Source:0) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
        at android.os.Handler.dispatchMessage(Handler.java:105) 
        at android.os.Looper.loop(Looper.java:164) 
        at android.app.ActivityThread.main(ActivityThread.java:6541) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767) 

I even searched for converting all nulls into Strings in API request but couldn't get any solid idea.

Please look into this and let me know any workaround for this.

Thanks :-)

You're probably writing null to your parcelable here: parcel.writeString(description)

You might want to make sure the description is never null using with the following code: parcel.writeString((if (description == null) "" else name))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM