MVP + Интеракторы - PullRequest
       5

MVP + Интеракторы

0 голосов
/ 01 мая 2018

Учитывая следующий поток:

Я хочу, чтобы методы выполнялись этими потоками:

  • OnClick (по системе): ui
  • OnRefresh (1): ui
  • ReadDb (2): рабочий
  • SetData (3): UI

Я мог бы добиться этого, сделав ReadDb async и ожидающими , но это бы заморозило поток пользовательского интерфейса.

Можете ли вы придумать подход, который не предусматривает реализацию Interactors, AsyncTask и т. Д.?

Спасибо.


Редактировать

Я ищу элегантное решение, избегайте упаковок типа new Handler (Looper.getMainLooper()).post(...), RunOnUiThread в каждом методе View и т. Д.

Самый простой подход - использовать taskt и await:

async OnRefresh() {
    data = await m.ReadDb() 
    v.SetData(data)
}

Однако пользовательский интерфейс зависает await m.ReadDb(). Я думал, что, поскольку OnRefresh возвращает void, он вернется и завершит выполнение родительского метода (OnClick). Затем, как только await будет сделано, он будет исполнять v.SetData(d). По какой-то причине я не получаю вывод.

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

На самом деле мой подход был правильным, но реализация не правильная. Я ожидал, что await m.ReadDb() будет запущен в рабочем потоке, но это не так. Причина этого в том, что мне пришлось явно запросить это с Task.Run и await it:

OnRefresh() 
{
    var d = await Task.Run (() => m.ReadDb());
    v.SetData(d)
}

Просто запись await не создает новый поток, поэтому пользовательский интерфейс был заблокирован.

Отметьте мой другой вопрос в SO , где он был мне указан.

0 голосов
/ 01 мая 2018

Примерно так:

class View {
    IPresenter p;

    void onClick() {
        p.OnRefresh()
    }

    void setData() {

    }
}

class Presenter implements Listener {
    void OnRefresh() {
        // You can do it with newThread or anything that does async
        async (
            m.readDB()
        )
    }

    void onComplete(Data data) {
        // or you can put it on Model class.
        new Handler(Looper.getMainLooper()).post(() -> {
            // this will be run on ui (or main) thread.
            v.setData(data);
        })
    }
}

class Model {

    Listener lstr;

    void readDB() {
        // read data..

        // completed
        lstr.onComplete(data)
    }
}

interface Listener {
    void onComplete(Data data)
}

Вы также можете добавить onFailure () и другие методы, также RxJava делает это намного проще, взгляните на это.

Примечание. Еще одна вещь, о которой вам следует беспокоиться, это циклические ссылки, вызванные тем, что View имеет ссылку на докладчика, а докладчик - на просмотр. вам нужно вручную уничтожить ссылку, как только она вам больше не понадобится (вероятно, onDestroy), иначе произойдет утечка памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...