Search code examples
androidandroid-asynctaskkotlinandroid-dialogfragment

SupportfragmentManager becomes null android kotlin


I am trying to launch a dialogFragment from onPostExecute but the supportFragmentManager for some reason returns null. I have tried launching the dialogFragment from main activity and other fragments and it works perfectly but I am not able to launch it from AsyncTask. Here is the AsyncTask:-

class SubscribeTask: AsyncTask<Void, Void, Void> {
    var mContext: Context
    var mTextView_temp: TextView
    var mTextView_humidity: TextView
    var mWeather_image: ImageView
    var mMessage: JsonObject
    var mResult = JsonObject()
    var mTemp: String = ""
    var mHumidity: String = ""
    var mLdr: Boolean = true
    var mRain: Boolean = false
    var mWeather: Int = 0
    var tester: Boolean = false
    var mFire: Boolean = false

    constructor(context: Context, textView_temp: TextView, textView_humidity: TextView, weather_image: ImageView, message: PNMessageResult){
        mContext = context
        mMessage = message.message.asJsonObject
        mTextView_temp = textView_temp
        mTextView_humidity = textView_humidity
        mWeather_image = weather_image
    }

    override fun doInBackground(vararg p0: Void?): Void? {
        if (mMessage.has("pi")){
            mResult = mMessage.getAsJsonObject("pi")
            mTemp = mResult.get("temp").asString
            mHumidity = mResult.get("humidity").asString
            mLdr = mResult.get("ldr").asBoolean
            mRain = mResult.get("rain").asBoolean
            mFire = mResult.get("fire").asBoolean
            tester = true
            if(mRain){
              mWeather = R.drawable.rainy
            }else if(mLdr){
                mWeather = R.drawable.suny
            }else{
                mWeather = R.drawable.cloudyy
            }
        }
        return null
    }

    override fun onPostExecute(result: Void?) {
        if(tester) {
            mTextView_temp.text = mTemp
            mTextView_humidity.text = mHumidity
            mWeather_image.setImageResource(mWeather)
            if(mFire){
                MainActivity().showAlertDialog("Fire", "There might be a fire in the house", R.drawable.house_fire, "Stop Alarm")
            }
        }
    }

}

Here is the showAlertDialog() function:-

fun showAlertDialog(title: String, content: String, imageid: Int, button: String){
        val fm = supportFragmentManager
        val alertDialogFragment = AlertFragment(title, content, imageid, button).newInstance(title, content, imageid, button)
        alertDialogFragment.show(fm, "fragment_alert")
    }

Here is the dialogFragment:-

class AlertFragment(val mTitle: String, val mContent: String, val mImageId: Int, val mButton: String) : DialogFragment() {

    fun newInstance(title: String, content: String, imageid: Int, button: String): AlertFragment {
        val alertfrag = AlertFragment(title, content, imageid, button)
        val args = Bundle()
        args.putString("title", title)
        alertfrag.arguments = args
        return alertfrag
    }

    override fun onCreateView(inflater: LayoutInflater?, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {
        // Inflate the layout for this fragment
        return inflater!!.inflate(R.layout.fragment_alert, container, false)
    }

    override fun onViewCreated(view: View?, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        title.text = mTitle
        alertContent.text = mContent
        alertImageId.setImageResource(mImageId)
        alertButton.text = mButton
    }
}

Can someone please help me. Answers in Java are also okay.


Solution

  • You can use Observer Pattern for this.

    Create a interface like that

    interface myExecListener {
     fun onFinish(title: String, content: String, imageid: Int, button: 
     String)
     }
    

    Add this lines into SubscribeTask

    class SubscribeTask: AsyncTask<Void, Void, Void>() {
     var listener: myExecListener? = null
    
      fun exec(listener: myExecListener){
        this.listener = listener
        this.execute()
      }
    
      override fun doInBackground(vararg params: Void?): Void? {
    
    
        return null
      }
    
      override fun onPostExecute(result: Void?) {
        super.onPostExecute(result)
        listener?.onFinish("Fire", "There might be a fire in the house", 333, "Stop Alarm")
      }
     }
    

    And execute in your activity

    SubscribeTask().exec(object : myExecListener{
      override fun onFinish(title: String, content: String, imageid: Int, button: String) {
        println("Observer triggered")
        showAlertDialog(title, content, imageid, button)
      }
    })