Не тост сообщение в onPostExecute в asyncTask - PullRequest
2 голосов
/ 21 февраля 2020

Мое приложение падает на Toast в OnPostExecute.

Я пытался поместить context вместо MainActivity() в качестве контекста в Toast, но оно вызывает то же исключение

исключение составляет

java .lang.NullPointerException: попытка вызвать виртуальный метод 'android .content.res.Resources android .content.Context.getResources ()' для нулевого объекта ссылка

Что происходит? Как мне решить эту проблему?

Я звоню этому AsyncTask от onPostExecute другого AsyncTask

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

AsyncTask находится в 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")
            }


        }
    }
}

Ответы [ 7 ]

2 голосов
/ 21 февраля 2020

MainActivity () дает вам новый экземпляр из MainActivity , который не является текущим запущенным экземпляром из MainActivity .

Вместо этого следует использовать this@MainActivity или applicationContext .

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()
1 голос
/ 21 февраля 2020

Ошибка, по-видимому, заключается в передаче контекста в экземпляр InsertInDateDb.

Если эта задача встроена в другую задачу, это означает, что вам нужно передать контекст еще раньше (путем передачи «this») или как предложено в ответе Мауриси Гуэля Эрнандеса, используйте интерфейс, передавая что-то вроде «OnFinishedListener» вашим AsyncTasks.

Вы бы создали OnFinishedListener в самом начале (например, в MainActivity) с помощью метода "onFinished", в котором вы могли бы использовать Toast. Затем передайте Listener в AsyncTasks соответственно и в конце вызовите метод «onFinished» в postExecute, чтобы запустить его / заставить показать Toast :)

Попытайтесь помнить, что контекст должен быть экземпляр фактически запущенного действия («this»), а не то, что еще не было создано.

1 голос
/ 21 февраля 2020

Я настоятельно рекомендую использовать шаблон наблюдателя для отправки информации об активности из AsyncTask.

Это просто, безопасно и элегантно. Вот образец.

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()
    }
}

Вот интерфейс:

interface WriteToDiskListener {

    fun writeToDiskFinished()
}

И действие или фрагмент:

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

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

Проверка "! IsFinishing" рекомендуется, чтобы избежать исключений в некоторых моменты.

Чтобы вызвать AsyncTask из MainActivity, вам нужно просто сделать это:

WriteToDiskAsync(this).execute()

Надеюсь, это поможет.

Маурисио

1 голос
/ 21 февраля 2020

Заменить MainActivity () контекстом

Toast.makeText(context, "Entry added to date database", Toast.LENGTH_LONG).show()
0 голосов
/ 21 февраля 2020

Создайте объект своей Деятельности, как показано ниже

 lateinit var mActivity: Activity

Теперь установите свою активность на свой объект активности.

mActivity = this@YourActivity

Используйте mActivity для вашего тоста

Toast.makeText(mActivity, "Entry added to date database", Toast.LENGTH_LONG).show()
0 голосов
/ 21 февраля 2020

просто позвоните своему AsynckTask вот так

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

и выпейте за onPostExecute() вот так

 Toast.makeText(
            context,
            "Entry added to date database",
            Toast.LENGTH_LONG
        ).show()
0 голосов
/ 21 февраля 2020

Использовать mainActivityContext для контекста в asysnTask;

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