Makarand
Makarand

Reputation: 1123

Coulden't Toast message in onPostExecute in asyncTask

My app is crashing on Toast in OnPostExecute.

I tried to put context insted of MainActivity() as Context in Toast but it's throwing same exception

The exception is

java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.Resources android.content.Context.getResources()' on a null object reference

What is happening? How should I solve it?

I am calling this AsyncTask from onPostExecute of another AsyncTask

 InsertInDateDb( MainActivity(), dateEntity).execute()

AsyncTask is in MainActivity

private class InsertInDateDb(var context: MainActivity, var dateEntity: DateEntity) :
    AsyncTask<Void, Void, Boolean>() {
    override fun doInBackground(vararg p0: Void?): Boolean {
        val dateRoomDatabase: DateRoomDatabase = DateRoomDatabase.getDateDb(context)!!

        val dateEntity1 = dateEntity
        dateRoomDatabase!!.getDateDao().insertDate(dateEntity)
        return true
    }

    override fun onPostExecute(result: Boolean?) {
        if (result!!) {

            try {
                Toast.makeText(
                   MainActivity(),
                    "Entry added to date database",
                    Toast.LENGTH_LONG
                ).show()
            } catch (e: Exception) {
                Log.d("tag", "Exception $e")
            }


        }
    }
}

Upvotes: 2

Views: 222

Answers (7)

Komal
Komal

Reputation: 338

Create object of your Activity like below

 lateinit var mActivity: Activity

Now set your activity to your activity object.

mActivity = this@YourActivity

Use mActivity to your Toast

Toast.makeText(mActivity, "Entry added to date database", Toast.LENGTH_LONG).show()

Upvotes: 0

I highly recommend using the observer pattern to send information to the activity from an AsyncTask.

It's easy, safe and elegant. Here's a sample.

class WriteToDiskAsync(private val writeToDiskListener: WriteToDiskListener) : AsyncTask<Void, Void, File?>() {

    override fun doInBackground(vararg params: Void?): File? {
        //whatever
    }

    override fun onPostExecute(survey: File?) {
        writeToDiskListener.writeToDiskFinished()
    }
}

Here's the interface:

interface WriteToDiskListener {

    fun writeToDiskFinished()
}

And the activity or fragment:

class MainActivity : AppCompatActivity(), WriteToDiskListener {
    //Your stuff...

    override fun writeToDiskFinished() {
        if (!isFinishing) {
            Toast.makeText(this@MainActivity, "Entry added to date database", Toast.LENGTH_LONG).show()
        }
    }
}

The "!isFinishing" check is recommended to avoid exceptions in certain moments.

To call the AsyncTask from the MainActivity you just have to do this:

WriteToDiskAsync(this).execute()

Hope it helps.

Mauricio

Upvotes: 1

Priyanka
Priyanka

Reputation: 3699

just call your AsynckTask like this

    InsertInDateDb(this@MainActivity, dateEntity).execute()

and toast in onPostExecute() like this

 Toast.makeText(
            context,
            "Entry added to date database",
            Toast.LENGTH_LONG
        ).show()

Upvotes: 0

Colibri
Colibri

Reputation: 733

The error seems to be in passing the context to the InsertInDateDb instance.

If this task is embedded in another task, it means you need to pass the context even sooner (by passing "this") or as suggested in Maurici Guell Hernandez' answer, use an interface, passing something like an "OnFinishedListener" to your AsyncTasks.

You'd create the OnFinishedListener right at the beginning (for example in the MainActivity), with an "onFinished" method in which you could Toast. Then pass the Listener to the AsyncTasks respectively and in the end call the "onFinished" method in postExecute, to run it / make it show the Toast :)

Try to keep in mind, that the context needs to be the instance of an actually running activity ("this") and not something that hasn't been created yet.

Upvotes: 1

Roman
Roman

Reputation: 2733

MainActivity() gives you new instance of MainActivity, which is not the current running instance of MainActivity.

You should use this@MainActivity or applicationContext instead.

1. Toast.makeText(this@MainActivity, "Entry added to date database", Toast.LENGTH_LONG).show()

2. Toast.makeText(applicationContext, "Entry added to date database", Toast.LENGTH_LONG).show()

Upvotes: 2

Murat &#199;akır
Murat &#199;akır

Reputation: 159

Use mainActivityContext for context in asysnTask;

var mainActivityContext= null
 override fun onCreate(savedInstanceState: Bundle?) {
mainActivityContext=this
...
..
.
}

Upvotes: 0

JakeB
JakeB

Reputation: 2113

Replace MainActivity() with context

Toast.makeText(context, "Entry added to date database", Toast.LENGTH_LONG).show()

Upvotes: 1

Related Questions