Kotlin传递Java定义的MoviesData数据类实现GET请求的报错如何修复
修复方案
第一步:修复MoviesData类,支持跨Activity传递
安卓中跨Activity传递自定义对象需要实现序列化接口,推荐使用Parcelable,修改后代码如下:
import android.os.Parcel; import android.os.Parcelable; import org.jetbrains.annotations.NotNull; import java.util.List; public class MoviesData implements Parcelable { @NotNull public final List<? extends Result> results; public MoviesData(List<? extends Result> results) { this.results = results; } protected MoviesData(Parcel in) { results = in.readArrayList(Result.class.getClassLoader()); } public static final Creator<MoviesData> CREATOR = new Creator<MoviesData>() { @Override public MoviesData createFromParcel(Parcel in) { return new MoviesData(in); } @Override public MoviesData[] newArray(int size) { return new MoviesData[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeList(results); } }
注意你的Result类也需要实现Parcelable接口才能正常序列化。
第二步:修复MainActivity实例构造与页面跳转逻辑
安卓Activity实例由系统创建,不能直接通过自定义构造函数传参,需要用Intent携带数据跳转。构造MoviesData需要传入List<? extends Result>类型的列表,测试阶段可以先传空列表,实际使用时替换为你的数据源即可:
// 构造MoviesData实例,示例传入空列表,实际替换为你的业务数据 val movieData = MoviesData(emptyList()) // 跳转MovieRequest并传递参数 val intent = Intent(this, MovieRequest::class.java).apply { putExtra("MOVIE_DATA", movieData) } startActivity(intent)
第三步:修复MovieRequest.kt代码错误
核心错误包括:自定义Activity构造函数、把参数名当成泛型类型使用、onFailure方法泛型不匹配,修复后代码如下:
open class MovieRequest : AppCompatActivity() { // 声明接收的MoviesData变量 private lateinit var movieData: MoviesData override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 读取Intent传入的参数 movieData = intent.getParcelableExtra<MoviesData>("MOVIE_DATA")!! val request = ServiceBuilder.buildService(TmdbEndpoints::class.java) val call = request.getMovies(getString(R.string.api_key)) // 泛型填写实际返回类型MoviesData,不能使用参数名作为类型 call.enqueue(object : Callback<MoviesData> { override fun onResponse(call: Call<MoviesData>, response: Response<MoviesData>) { if (response.isSuccessful) { progress_bar.visibility = View.GONE recyclerView.apply { setHasFixedSize(true) layoutManager = LinearLayoutManager(this@MovieRequest) adapter = MoviesAdapter(response.body()!!.results) } } } override fun onFailure(call: Call<MoviesData>, t: Throwable) { Toast.makeText(this@MovieRequest, "${t.message}", Toast.LENGTH_SHORT).show() } }) } }
额外说明
如果你不需要使用从MainActivity传入的MoviesData,只是要解析接口返回的列表渲染页面,可以直接删除MainActivity中构造MoviesData、跳转传参的逻辑,也不需要给MovieRequest加参数接收逻辑,直接保留网络请求部分即可正常运行。
内容的提问来源于stack exchange,提问作者petestmart
相关产品推荐
相关产品推荐

