使用Retofit2和Rxjava2进行JSON数据分析。此数据成功获取ArrayList。它的ArrayList Size是九,但它只显示表中的两个Record。 After Two记录其Kotlin.NullPointerException。
JSON数据:
{"success":1,"salesGst":[{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"1","ChallanDate":"2019-03-15 00:00:00","ChallanAmount":"2778.75","TaxTotal":"2778.75","InvoiceType":"Retail Invoice","CGSTTotal":"0.0","PartyGST":"CDE","SGSTTotal":"0.0","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"1","ChallanDate":"2019-03-13 00:00:00","ChallanAmount":"2203.0","TaxTotal":"2118.5","InvoiceType":"Tax Invoice","CGSTTotal":"52.96","PartyGST":"CDE","SGSTTotal":"52.96","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"VIKAS","ChallanNo":"2","ChallanDate":"2019-03-16 00:00:00","ChallanAmount":"6975.0","TaxTotal":"6975.0","InvoiceType":"Retail Invoice","CGSTTotal":"0.0","PartyGST":null,"SGSTTotal":"0.0","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES MH","ChallanNo":"2","ChallanDate":"2019-03-13 00:00:00","ChallanAmount":"420.0","TaxTotal":"403.75","InvoiceType":"Tax Invoice","CGSTTotal":"0.0","PartyGST":"ABC","SGSTTotal":"0.0","IGSTTotal":"20.19"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"3","ChallanDate":"2019-03-14 00:00:00","ChallanAmount":"4788.0","TaxTotal":"4560.0","InvoiceType":"Tax Invoice","CGSTTotal":"114.0","PartyGST":"CDE","SGSTTotal":"114.0","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"4","ChallanDate":"2019-03-15 00:00:00","ChallanAmount":"241.9","TaxTotal":"230.38","InvoiceType":"Tax Invoice","CGSTTotal":"5.76","PartyGST":"CDE","SGSTTotal":"5.76","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"5","ChallanDate":"2019-03-15 00:00:00","ChallanAmount":"5563.68","TaxTotal":"5101.5","InvoiceType":"Tax Invoice","CGSTTotal":"231.28","PartyGST":"CDE","SGSTTotal":"231.28","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES GJ","ChallanNo":"6","ChallanDate":"2019-03-16 00:00:00","ChallanAmount":"13238.0","TaxTotal":"12459.25","InvoiceType":"Tax Invoice","CGSTTotal":"389.29","PartyGST":"CDE","SGSTTotal":"389.29","IGSTTotal":"0.0"},{"Cmp_Name":"ABC","GSTIN":"AAAA","FirmName":"SALES MH","ChallanNo":"7","ChallanDate":"2019-03-16 00:00:00","ChallanAmount":"2074.0","TaxTotal":"1975.0","InvoiceType":"Tax Invoice","CGSTTotal":"0.0","PartyGST":"ABC","SGSTTotal":"0.0","IGSTTotal":"98.75"}]}
在获取如何在TableLayout中显示之后,请指导我。
在ArrayList Nine Record但在Table中只显示Two Record另外七条记录不显示。在第三个记录taxtotal给kotlin.nullpointerException。什么失踪?
private fun displaySalesGSTData(salesGSt : List<SalesGST>) {
salesGST = SalesGST()
tvSalesCompanyName.setText(salesGSt.get(1).Cmp_Name)
tvGSTIN.setText(salesGSt.get(1).GSTIN)
val rowHeader = TableRow(this@Sales)
rowHeader.setBackgroundColor(Color.parseColor("#c0c0c0"))
rowHeader.setLayoutParams(TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT))
val headerText = arrayOf<String>("Sr.No.", "Invoice Type", "Bill No.", "Bill Date", "Firm Name", "GST NO","TAX Total","CGST","SGST","IGST","Net Amount")
for (c in headerText)
{
val tv = TextView(this@Sales)
tv.setLayoutParams(TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT))
tv.setGravity(Gravity.CENTER)
// tv.setBackgroundResource(R.drawable.table_header)
tv.setTextColor(Color.parseColor("#3F51B5"))
tv.setTextSize(18F)
tv.setPadding(5, 5, 5, 5)
tv.setText(c)
rowHeader.addView(tv)
}
tableMarks.addView(rowHeader)
for (j in 0 until salesGSt.size)
{
/*val jsonObject1 = jsonArray.getJSONObject(j)
val date = jsonObject1.getString("ExamDate")
val inputFormatter1 = SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
val date1 = inputFormatter1.parse(date)
val outputFormatter1 = SimpleDateFormat("dd-MMM-yyyy")
ExamDate = outputFormatter1.format(date1)*/
/* String replaceDate = date.replace("/Date(", "").replace(")/", "");
Long getDate = Long.valueOf(replaceDate);
ExamDate = dateFormat.format(getDate);*/
/*Subject = jsonObject1.getString("subject")
ExamName = jsonObject1.getString("ExamName")
TotalMark = jsonObject1.getLong("TotalMarks")
PassingMark = jsonObject1.getLong("PassingMarks")
Mark = jsonObject1.getLong("Marks")*/
var fName : String = salesGSt.get(j).FirmName!!
var invoice : String = salesGSt.get(j).InvoiceType!!
var bill_no : String = salesGSt.get(j).ChallanNo!!
var bill_date : String = salesGSt.get(j).ChallanDate!!
var gst_no : String = salesGSt.get(j).PartyGST!!
var tax_total : Double = salesGSt.get(j).TaxTotal!!.toDouble()
var cgst : String = salesGSt.get(j).CGSTTotal!!
var igst : String = salesGSt.get(j).IGSTTotal!!
var sgst : String = salesGSt.get(j).SGSTTotal!!
var net_amount : String = salesGSt.get(j).ChallanAmount!!
var sr : Int = j + 1
// dara rows
val row = TableRow(this@Sales)
row.setLayoutParams(TableLayout.LayoutParams(TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT))
val colText = arrayOf<String>(sr.toString(),(invoice), bill_no, bill_date, fName, gst_no, tax_total.toString(),cgst,sgst,igst,net_amount)
for (text in colText)
{
val tv = TextView(this@Sales)
tv.setLayoutParams(TableRow.LayoutParams(TableRow.LayoutParams.WRAP_CONTENT,
TableRow.LayoutParams.WRAP_CONTENT))
tv.setGravity(Gravity.CENTER)
// tv.setBackgroundResource(R.drawable.table_shape)
tv.setTextSize(18F)
tv.setTextColor(Color.parseColor("#3F51B5"))
tv.setPadding(5, 5, 5, 5)
tv.setText(text)
row.addView(tv)
}
tableMarks.addView(row)
}
}
第三项,salesGst[2]
,是"PartyGST": null
。您的json反序列化程序库不会处理非空字段,因为它是用Java编写的。我假设你有一个数据类,其中PartGST
被定义为非null,但反序列化器仍将它解析为null。因此,当你访问PartyGST
然后你将收到一个NullPointerException
,因为Kotlin期望它是非null。这是一篇很好的文章,它更详细地解释了:
I've trusted you! You promised no null pointer exceptions!
解决方案是拥有两个模型。 DTO(用于JSON响应),其中所有字段都是可选的,您的内部模型(由您的应用程序使用),您可以在其中定义哪些字段是可选的。然后,您可以使用映射器来处理DTO中字段为空但在内部模型中为非null的情况:
// Models for your API response
data class SalesGstsDTO(val gsts: List<GstDTO>)
data class GstDTO(val name: String?, val surname: String?)
// Internal models used by your app
data class SalesGsts(val gsts: List<Gst>)
data class Gst(val name: String, val surname: String?)
class SalesGstDTOMapper {
fun mapToSalesGsts(salesGstsDTO: SalesGstsDTO): SalesGsts {
val gsts = mutableListOf<Gst>()
salesGstsDTO.gsts.map {
val name = it.name ?: return@map // Skips this item. You could handle this how you wish
val surname = it.surname
val gst = Gst(name, surname)
gsts.add(gst)
}
return SalesGsts(gsts)
}
}
这也允许您将应用程序与JSON响应分离。