Nitish
Nitish

Reputation: 3155

Android: kotlin synthetic import crashes even if id is present in layout

I am new to Kotlin and in my project I am using kotlins synthetic import feature. It is crashing sometimes throwing KotlinNullPointerException. Here is log:

Fatal Exception: kotlin.KotlinNullPointerException
   at main.fragments.ListingDetailsFragment$getProductComboData$responseListener$1.onResponse(ListingDetailsFragment.kt:1607)
   at main.fragments.ListingDetailsFragment$getProductComboData$responseListener$1.onResponse(ListingDetailsFragment.kt:159)
   at com.android.volley.toolbox.JsonRequest.deliverResponse(JsonRequest.java:83)
   at com.android.volley.ExecutorDelivery$ResponseDeliveryRunnable.run(ExecutorDelivery.java:106)
   at android.os.Handler.handleCallback(Handler.java:790)
   at android.os.Handler.dispatchMessage(Handler.java:99)
   at android.os.Looper.loop(Looper.java:187)
   at android.app.ActivityThread.main(ActivityThread.java:7025)
   at java.lang.reflect.Method.invoke(Method.java)
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:514)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:888)

Code at line no. 1607:

lin_product_combo!!.visibility = View.GONE

This happening after webservice call. Below is the function:

private fun getProductComboData() {
    val params = HashMap<String, String>()
    params["listing_id"] = listingId
    params["category_id"] = listingDetailsModel!!.category_id
    params["condition"] = listingDetailsModel!!.condition
    params["location"] = listingDetailsModel!!.location

    val responseListener = Response.Listener<JSONObject> { response ->
                    try {
            val code = response.getString("code")
            if (code.equals("success", ignoreCase = true)) {
                val data = response.optJSONObject("data")
                if (data != null) {
                    productComboModels!!.clear()
                    if (data.has("currentLid") && data.get("currentLid") is JSONObject) {
                        val currentLidObj = data.getJSONObject("currentLid")
                        val recommendateDataArray = data.getJSONArray("recommendateData")
                        if (recommendateDataArray != null) {
                            val size = recommendateDataArray.length()
                            if (size > 0) {
                                val currentLidModel = BuyListingsModel.getBuyListingModel(currentLidObj)
                                currentLidModel.isItemSelected = true
                                productComboModels!!.add(currentLidModel)
                                for (i in 0 until size) {
                                    val recommendedDataModel = BuyListingsModel
                                            .getBuyListingModel(recommendateDataArray.optJSONObject(i))
                                    recommendedDataModel.isItemSelected = true
                                    productComboModels!!.add(recommendedDataModel)
                                }
                            }
                        }
                    }
                    if (!productComboModels!!.isEmpty()) {
                        frequently_bought_together_title!!.visibility = View.VISIBLE
                        lin_product_combo!!.visibility = View.VISIBLE
                        productComboAdapter!!.notifyDataSetChanged()
                        total_combo_price!!.text = Util
                                .formatCurrencyToRupees(productComboPrice.toString())
                    } else {
                        lin_product_combo!!.visibility = View.GONE
                    }
                }
            } else if (code.equals("failed", ignoreCase = true)) {
                handleError(response)
            }
        } catch (e: JSONException) {
            e.printStackTrace()
        }
    }

    val errorListener = Response.ErrorListener { error -> error.printStackTrace() }
    comboAPICalled = true
    Api.getFrequentlyBoughtTogetherData(params, responseListener, errorListener)
}

These are import statements:

import kotlinx.android.synthetic.main.certification_package_eco_layout.*
import kotlinx.android.synthetic.main.certification_package_history_layout.*
import kotlinx.android.synthetic.main.certification_packages_locked_section.*
import kotlinx.android.synthetic.main.fragment_listing_details_v2.*
import kotlinx.android.synthetic.main.fragment_listing_details_v2.view.*
import kotlinx.android.synthetic.main.layout_discovery_tools_view.*
import kotlinx.android.synthetic.main.layout_fcts_panel.* 
import kotlinx.android.synthetic.main.layout_tco_value_view.*
import kotlinx.android.synthetic.main.ldp_listing_summary_layout.*
import kotlinx.android.synthetic.main.pay_token_amount_layout.*
import kotlinx.android.synthetic.main.product_detail_seller_panel.*
import kotlinx.android.synthetic.main.service_date_time_panel.*

And lin_product_combo is a linear layout that is present in the xml file. Not getting idea for null pointer exception. Same happened for some pther views too.

Upvotes: 0

Views: 811

Answers (2)

GRimmjow
GRimmjow

Reputation: 98

If you use a Fragment you must use the Create View

class Profil_Fragment : Fragment(){


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        val view = inflater.inflate(R.layout.profil_fragment, container, false)

        // Add view
        view.lin_product_combo!!.visibility = View.GONE



        return view
    }


    private fun getProductComboData(){
        ...

        view.lin_product_combo!!.visibility = View.GONE

        ...
    }


}

Upvotes: 0

Zafar Hussain
Zafar Hussain

Reputation: 268

It is good in practice that you have to do this coding in onActivityCreated() not in onCreateView().

basically, onActivityCreated() is called after onCreate() in Activity,

that's why all variable and onClick event must define in onActivityCreated() not in onCreateView().

Thanks, Zafar Hussain

Upvotes: 1

Related Questions