update () не вызывается внутри Activity, которая является Observer - PullRequest
0 голосов
/ 01 июля 2018

My MainActivity реализует класс Observer. У меня также есть класс с именем ObservedObject, который расширяет класс Observable.

Вот мой кастом Observable, называемый ObservedObject:

class ObservedObject(var value: Boolean) : Observable() {
    init {
        value = false
    }

    fun setVal(vals: Boolean) {
        value = vals
        setChanged()
        notifyObservers()
    }

    fun printVal() {
        Log.i("Value" , "" + value)
    }
}

Вот мой Application, называемый SpeechApp, который содержит мой ObservedObject (на самом деле Observable):

class SpeechApp: Application() {
    var isDictionaryRead = ObservedObject(false)

    override fun onCreate() {
        super.onCreate()
        wordslist = ArrayList()

        Thread {
            execute()
        }.start()
    }

    fun execute() {
        while (/* Condition */) {
            //Log.i("Read" , line)
            /*Does Something Here*/
        }
        isDictionaryRead.setVal(true)
    }
}

В моем MainActivity у меня есть в основном диалог, который должен отображаться после того, как я получу вывод после распознавания речи. Он будет отображаться до тех пор, пока значение isDictionaryRead не изменится на true:

class MainActivity(private val REQ_CODE_SPEECH_INPUT: Int = 100) : AppCompatActivity() , Observer{
    override fun update(o: Observable?, arg: Any?) {
        (o as ObservedObject).printVal()
        dialog.hide()
    }

    private lateinit var app : SpeechApp
    private lateinit var dialog: MaterialDialog

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        dialog = MaterialDialog.Builder(this)
                .title("Please Wait")
                .content("Loading from the Dictionary")
                .progress(true , 0)
                .build()

        app = application as SpeechApp
        app.isDictionaryRead.addObserver(this)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_speech, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        val id = item?.itemId
        when(id) {
            R.id.menu_option_speech -> {
                invokeSpeech()
            }
        }
        return super.onOptionsItemSelected(item)
    }

    private fun invokeSpeech() {
        /* Does Something, Works Fine */

        try {
            startActivityForResult(intent , REQ_CODE_SPEECH_INPUT)
        }
        catch (ex: ActivityNotFoundException) {
            /* Does Something */
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        when (requestCode) {
            REQ_CODE_SPEECH_INPUT -> {
                if (resultCode == Activity.RESULT_OK && null != data) {
                    dialog.show()
                }
            }
        }
        super.onActivityResult(requestCode, resultCode, data)
    }
}

Теперь проблема в том, что когда SpeechApp устанавливает значение isDictionaryRead в true, я ожидаю, что он вызовет метод MainActivity update(), в котором я дал код, чтобы скрыть диалоговое окно. Этот конкретный код не работает, и мое диалоговое окно не исчезает. Куда я иду не так?

PS. Я отправил свой код на Github сейчас, на всякий случай, если кто-нибудь может мне помочь, где я иду не так.

1 Ответ

0 голосов
/ 01 июля 2018

Единственное, о чем я могу подумать, это может вызвать эту проблему: поток execute(), который был запущен в SpeechApp.onCreate, завершил выполнение и вызвал isDictionaryRead.setVal(true) до , когда операция могла вызвать app.isDictionaryRead.addObserver(this) , В результате, notifyObservers вызывается еще до того, как активность начинает наблюдаться, и в результате она не уведомляется. Вот мое предлагаемое решение: Запустите поток execute в методе действия onCreate после добавления его в качестве наблюдателя.

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    dialog = MaterialDialog.Builder(this)
            .title("Please Wait")
            .content("Loading from the Dictionary")
            .progress(true , 0)
            .build()

    app = application as SpeechApp
    app.isDictionaryRead.addObserver(this)
    app.asyncReadDictionary()
}

Затем удалите вызов потока из SpeechApp.onCreate и используйте его вместо

// in SpeechApp
fun asyncReadDictionary() {
    if (!isDictionaryRead.value) {
       Thread { execute() }.start()
    }
}

private fun execute() {
    while (/* Condition */) {
        //Log.i("Read" , line)
        /*Does Something Here*/
    }
    isDictionaryRead.value = true
}

Кроме того, переопределите ObservableObject следующим образом

class ObservedObject : Observable() {
    var value: Boolean = false
        set(newValue) {
            field = newValue
            setChanged()
            notifyObservers()
        }

    fun printVal() {
        Log.i("Value" , "" + value)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...