[英]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, 尽可能尝试使用let
, apply
, run
等。例如,
//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.