任何原因 Kotlin API GET REQUEST code (OKHttp library) get this; java.lang.NullPointerException?
Any reason why Kotlin API GET REQUEST code (OKHttp library) get this; java.lang.NullPointerException?
MainActivity
class MainActivity : AppCompatActivity() {
lateinit var adapter: MainAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView.layoutManager = LinearLayoutManager(this)
fetchJson()
}
private fun fetchJson() {
println("Attempting to FetchJson")
val url = "https://www.noforeignland.com/home/api/v1/places/"
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: okhttp3.Callback {
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
val body = response.body?.string()
println(body)
val gson = GsonBuilder().create()
val homeFeed = gson.fromJson(body, HomeFeed::class.java)
runOnUiThread() {
recyclerView.adapter = MainAdapter(homeFeed)
}
}
override fun onFailure(call: okhttp3.Call, e: IOException) {
println("Failed to execute request")
}
})
}
} class HomeFeed(val properties: List<Properties>)
致命异常
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.odyssey, PID: 21745
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.example.odyssey.adapter.MainAdapter.getItemCount(MainAdapter.kt:19)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4044)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3849)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1915)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:446)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:779)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3080)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2590)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:725)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I/Process: Sending signal. PID: 21745 SIG:
主适配器
class MainAdapter(val homeFeed: HomeFeed) : RecyclerView.Adapter<CustomViewHolder>() {
override fun getItemCount(): Int {
return homeFeed.properties.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent?.context)
val cellForRow = layoutInflater.inflate(R.layout.activity_data, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val propertie = homeFeed.properties.get(position)
holder?.view?.text_view_result?.text = propertie.name
}
}
class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
}
model.Properties
public class Properties {
private String name;
private String icon;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
*当我调试代码时,问题似乎是从;
runOnUiThread() {
recyclerView.adapter = MainAdapter(homeFeed)
}
*因为我收到类型为 okhttp3.Call 的 "Cannot find local variable "call",以及 homeFeed.properties = null *
然后致命异常指向
override fun getItemCount(): Int {
return homeFeed.properties.size
}
这导致了问题,我真的不知道如何解决
有什么建议吗?
HomeFeed-class 与 JSON-表示不匹配。 JSON-表示形式如下:
{"type":"FeatureCollection","features":[{"type":"Feature", "properties:{"name":"John Smith","icon":"Icon":"id":123456}}]}
所以你必须先用一个特征-class 包装属性-class,就像这样):
public class Feature{
public String type;
public Properties properties;
public Feature(String type, Properties properties){
this.type = type;
this.properties = properties;
}
}
HomeFeed-class:
public class HomeFeed{
public List<Feature> features;
public String type;
public HomeFeed(String type, List<Feature> features){
this.features = features;
this.type = type;
}
}
那么应该可以了。
MainActivity
class MainActivity : AppCompatActivity() {
lateinit var adapter: MainAdapter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
recyclerView.layoutManager = LinearLayoutManager(this)
fetchJson()
}
private fun fetchJson() {
println("Attempting to FetchJson")
val url = "https://www.noforeignland.com/home/api/v1/places/"
val request = Request.Builder().url(url).build()
val client = OkHttpClient()
client.newCall(request).enqueue(object: okhttp3.Callback {
override fun onResponse(call: okhttp3.Call, response: okhttp3.Response) {
val body = response.body?.string()
println(body)
val gson = GsonBuilder().create()
val homeFeed = gson.fromJson(body, HomeFeed::class.java)
runOnUiThread() {
recyclerView.adapter = MainAdapter(homeFeed)
}
}
override fun onFailure(call: okhttp3.Call, e: IOException) {
println("Failed to execute request")
}
})
}
} class HomeFeed(val properties: List<Properties>)
致命异常
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.odyssey, PID: 21745
java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
at com.example.odyssey.adapter.MainAdapter.getItemCount(MainAdapter.kt:19)
at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep1(RecyclerView.java:4044)
at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3849)
at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at androidx.constraintlayout.widget.ConstraintLayout.onLayout(ConstraintLayout.java:1915)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:446)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1829)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1673)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1582)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:332)
at android.widget.FrameLayout.onLayout(FrameLayout.java:270)
at com.android.internal.policy.DecorView.onLayout(DecorView.java:779)
at android.view.View.layout(View.java:21912)
at android.view.ViewGroup.layout(ViewGroup.java:6260)
at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:3080)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2590)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1721)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7598)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:966)
at android.view.Choreographer.doCallbacks(Choreographer.java:790)
at android.view.Choreographer.doFrame(Choreographer.java:725)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:951)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I/Process: Sending signal. PID: 21745 SIG:
主适配器
class MainAdapter(val homeFeed: HomeFeed) : RecyclerView.Adapter<CustomViewHolder>() {
override fun getItemCount(): Int {
return homeFeed.properties.size
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomViewHolder {
val layoutInflater = LayoutInflater.from(parent?.context)
val cellForRow = layoutInflater.inflate(R.layout.activity_data, parent, false)
return CustomViewHolder(cellForRow)
}
override fun onBindViewHolder(holder: CustomViewHolder, position: Int) {
val propertie = homeFeed.properties.get(position)
holder?.view?.text_view_result?.text = propertie.name
}
}
class CustomViewHolder(val view: View): RecyclerView.ViewHolder(view) {
}
model.Properties
public class Properties {
private String name;
private String icon;
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIcon() {
return icon;
}
public void setIcon(String icon) {
this.icon = icon;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
*当我调试代码时,问题似乎是从;
runOnUiThread() {
recyclerView.adapter = MainAdapter(homeFeed)
}
*因为我收到类型为 okhttp3.Call 的 "Cannot find local variable "call",以及 homeFeed.properties = null *
然后致命异常指向
override fun getItemCount(): Int {
return homeFeed.properties.size
}
这导致了问题,我真的不知道如何解决 有什么建议吗?
HomeFeed-class 与 JSON-表示不匹配。 JSON-表示形式如下:
{"type":"FeatureCollection","features":[{"type":"Feature", "properties:{"name":"John Smith","icon":"Icon":"id":123456}}]}
所以你必须先用一个特征-class 包装属性-class,就像这样):
public class Feature{
public String type;
public Properties properties;
public Feature(String type, Properties properties){
this.type = type;
this.properties = properties;
}
}
HomeFeed-class:
public class HomeFeed{
public List<Feature> features;
public String type;
public HomeFeed(String type, List<Feature> features){
this.features = features;
this.type = type;
}
}
那么应该可以了。