简体   繁体   English

尝试使用Android Studio在Kotlin中的Retrofit中解析JSON时获取空指针异常

[英]Getting null pointer exception when trying to parse JSON in Retrofit in kotlin with Android studio

I am trying to get a user from Github API. 我正在尝试从Github API获取用户。 API is working well and receiving the response but getting a problem when trying to parse JSON. API运作良好,并且收到响应,但是在尝试解析JSON时遇到问题。 kindly guide me. 请指导我。 I am Fresh with kotlin and Retrofit. 我对Kotlin和Retrofit很满意。 So, please guide me on how to get a proper solution. 因此,请指导我如何获得适当的解决方案。 Here is my JSON Respons. 这是我的JSON响应。

    {
    "login": "photoionized",
    "id": 597302,
    "node_id": "MDQ6VXNlcjU5NzMwMg==",
    "avatar_url": "https://avatars0.githubusercontent.com/u/597302?v=4",
    "gravatar_id": "",
    "url": "https://api.github.com/users/photoionized",
    "html_url": "https://github.com/photoionized",
    "followers_url": "https://api.github.com/users/photoionized/followers",
    "following_url": "https://api.github.com/users/photoionized/following{/other_user}",
    "gists_url": "https://api.github.com/users/photoionized/gists{/gist_id}",
    "starred_url": "https://api.github.com/users/photoionized/starred{/owner}{/repo}",
    "subscriptions_url": "https://api.github.com/users/photoionized/subscriptions",
    "organizations_url": "https://api.github.com/users/photoionized/orgs",
    "repos_url": "https://api.github.com/users/photoionized/repos",
    "events_url": "https://api.github.com/users/photoionized/events{/privacy}",
    "received_events_url": "https://api.github.com/users/photoionized/received_events",
    "type": "User",
    "site_admin": false,
    "name": "Andrew Stucki",
    "company": "Aspera, Inc.",
    "blog": "",
    "location": "Alameda, CA",
    "email": null,
    "hireable": null,
    "bio": null,
    "public_repos": 4,
    "public_gists": 1,
    "followers": 2,
    "following": 0,
    "created_at": "2011-02-02T18:44:31Z",
    "updated_at": "2016-05-12T04:40:54Z"
}

Here is MyApi code 这是MyApi代码

    interface MyApi {
    @GET("users/{username}")
    suspend fun userLogin(
        @Path("username") username: String

    ) : Response<AuthResponse>

    companion object{
        operator fun invoke() : MyApi {
            return Retrofit.Builder()
                .baseUrl("https://api.github.com")
                .addConverterFactory(GsonConverterFactory.create())
                .build()
                .create(MyApi :: class.java)
        }
    }
}

Here is My POKO class 这是我的POKO课

const val CURRENT_USER_ID = 0

@Entity
data class User (
    var id: Int? = null,
    var name: String? = null,
    var email: String? = null,
    var login: String? = null,
    var avatar_url: String? = null,
    var gravatar_id: String? = null,
    var url: String? = null,
    var html_url: String? = null,
    var company: String? = null,
    var followers_url: String? = null,
    var created_at: String? = null,
    var updated_at: String? = null
){
    @PrimaryKey(autoGenerate = false)
    var uid: Int = CURRENT_USER_ID
}

here is User Repository class code 这是用户存储库类代码

   class UserRepository {

    suspend fun userLogin(username: String) : Response<AuthResponse>{
    return MyApi().userLogin(username)

    }
}

here is Auth Response 这是验证响应

data class AuthResponse (
    val isSuccessful : Boolean?,
    val message: String?,
    val user: User?
)

here is AuthViewModel

    class AuthViewModel : ViewModel() {
    var username: String? = null

    var authListener : AuthListener? = null

    fun onLoginButtonClick(view: View){
        authListener?.onStarted()
        if (username.isNullOrEmpty()){
            authListener?.onFailure("Invalid email or password")
            //
            return
        }
        Coroutines.main{
            val response = UserRepository().userLogin(username!!)
            if (response.isSuccessful){
                authListener?.onSuccess(response.body()?.user!!)

            }else{
                authListener?.onFailure("Error Code: ${response.code()}")
            }
        }

    }
}

Here is Login Activity 这是登录活动

class LoginActivity : AppCompatActivity(), AuthListener {


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val binding : ActivityLoginBinding = DataBindingUtil.setContentView(this, R.layout.activity_login)
        val viewModel = ViewModelProviders.of(this).get(AuthViewModel :: class.java)
        binding.viewmodel= viewModel
        viewModel.authListener = this
    }
    override fun onStarted() {
        toast("Login Started")
        progress_bar.show()
    }

    override fun onSuccess(user: User) {
        progress_bar.hide()
        toast("${user.login} is found")
    }
    override fun onFailure(message: String) {
        progress_bar.hide()
        toast(message)
    }
}

Here is my Logcat error 这是我的Logcat错误

PID: 15204 PID:15204

kotlin.KotlinNullPointerExceptionat com.isofttechpro.myapplication.ui.auth.AuthViewModel$onLoginButtonClick$1.invokeSuspend(AuthViewModel.kt:23) com.isofttechpro.myapplication.ui.auth.AuthViewModel $ onLoginButtonClick $ 1.invokeSuspend(AuthViewModel.kt:23)的kotlin.KotlinNullPointerException

KotlinNullPointerException occurs when you force unwrap a null value using !! 当您使用!!强制解开null值时,会发生KotlinNullPointerException !! . The error probably lies in the following lines, 错误可能在于以下几行,

val response = UserRepository().userLogin(username!!)
if (response.isSuccessful){
  authListener?.onSuccess(response.body()?.user!!)

Try to not use !! 尽量不要使用!! as much as possible, rather try to use let , apply , run , etc. For example, 尽可能尝试使用letapplyrun等。例如,

//rather than
//authListener?.onSuccess(response.body()?.user!!)
//use
response.body()?.user?.let {
  authListener?.onSuccess(it)
}

Another alternative to that is to use the elvis operator and provide default values. 另一种替代方法是使用elvis运算符并提供默认值。 For example, 例如,

authListener?.onSuccess(response.body()?.user?:"default value")

Firstly, Don't use null to initiate your data class properties. 首先,不要使用null来初始化您的数据类属性。

Secondly, your response is in raw JSON so it doesn't need any parent class to parse. 其次,您的响应使用原始JSON,因此不需要任何父类进行解析。 eg your data class AuthResponse is not required. 例如,不需要您的数据类AuthResponse

Use the below code to parse it to your data model. 使用以下代码将其解析为您的数据模型。

val gson:Gson = Gson()
var user = gson?.fromJson(response.body(), Users::class.java)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 尝试从Async类android中的url解析JSON数据时获取空指针异常 - getting a null pointer exception when trying to parse JSON data from a url in a Async Class android 我正在使用翻新来解析android中的数据,但一直收到null指针异常 - I'm using retrofit to parse data in android but keep getting a null pointer exception 尝试使用json解析在Android中将数据从服务器添加到ListView时获取NULL指针异常 - Getting NULL pointer exception when trying to add data from server to listView using json parsingin android Null 指针异常来自 api 响应在 android 工作室中使用 retrofit - Null pointer exception from api response using retrofit in android studio android studio 新手,遇到空指针异常 - New to android studio and getting a null pointer exception Android Studio Kotlin Null 更新 Firestore 数据库时出现指针异常 - Android Studio Kotlin Null Pointer Exception while updating Firestore Database 尝试打开活动时 Kotlin 空指针异常 - Kotlin Null Pointer Exception when trying to open Activity 尝试解析json文件时出现空指针异常 - Null pointer exception while trying to parse a json file 使用翻新的JSON数组上的空指针异常 - Null pointer Exception on JSON Array using Retrofit Retrofit响应中的Android Null指针异常 - Android Null Pointer Exception in Retrofit response
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM