как запустить метод B () внутри onResume () после завершения метода A () внутри onStart () - PullRequest
0 голосов
/ 11 февраля 2019

как запустить метод B () (основной поток) внутри onResume () после того, как метод A () (рабочий поток) завершился внутри onStart ()

У меня есть loadCards () внутри onStart () и initViews() внутри onResume ().

Необходимо запускать initViews () только после завершения loadCards (), loadCards () - длительная операция и обратный вызов ().

CurrentПроблема в том, что initViews () запускается до завершения loadCards (), поэтому получите нулевой указатель.

Хотел бы получить помощь: как запустить initViews () (внутри onResume) только после того, как loadCards () (внутри onStart) имеетготово?

@Override
protected void onStart() {
    super.onStart();

    loadCards(new Callback(){
        success(List<Card> cardList){do something}
        fail(){do other thing}
    });
}

@Override
protected void onResume() {
    super.onResume();

    //my problem is here: 
    //how to know if loadCards() has finished? then run initViews.

    initViews();
}

public void loadCards(Callback callback) {
    Runnable runnable = () -> {

        //List<Card> cardList = get list from work thread;

        mAppExecutors.mainThread().execute(() -> {
            if (result == empty) {
                callback.fail();
            } else {
                callback.success(cardList);
            }
        });
    };

    mAppExecutors.diskIO().execute(runnable);
}

void initViews(){}

ожидается: после завершения loadCards () запустите initViews ().

актуально: когда loadCards () все еще работает, initViews () выполняется.

Ответы [ 2 ]

0 голосов
/ 18 февраля 2019

Вы можете использовать https://github.com/EliyahuShwartz/ConditionalTasksRunner для запуска конкретной задачи при выполнении определенного условия (например, при возобновлении действия)

Этот код предназначен для запуска задачи просмотра из другого класса (обычноведущий) без остерегаться жизненного цикла Android.

базовая реализация будет

   private val mResumePendingTasks: ConditionalTasksRunner = object : ConditionalTasksRunner() {
        override val isConditionMet = isResumed
    }

, и тогда вы сможете публиковать задание из любого места внутри класса decleration.

mResumePendingTasks.runOnConditionMet(Runnable { onListLoadedSuccessfully() })

Исходный код ConditionalTasksRunner:

package conditionaltasksrunner.com

import android.os.Handler
import android.os.Looper
import java.util.*

/**
 * Run tasks when a specific condition is met [.isConditionMet]
 * this tasks will run on the [Handler] that create the constructor
 */
abstract class ConditionalTasksRunner {

    private var mPendingTask: MutableSet<Runnable>
    private var mHandler: Handler

    /**
     * @return true if condition is met
     */
    abstract val isConditionMet: Boolean

    protected constructor() {
        mPendingTask = LinkedHashSet()
        mHandler = Handler()
    }

    protected constructor(handler: Handler) {
        mPendingTask = LinkedHashSet()
        mHandler = handler
    }

    /**
     * Run the given task when condition is met.
     * if the condition is met already than the task will invoke immediately
     *
     * @param runnable task to run
     */
    @Synchronized
    fun runOnConditionMet(runnable: Runnable) {
        if (isConditionMet) {
            if (Looper.myLooper() == mHandler.looper)
                runnable.run()
            else
                mHandler.post { runOnConditionMet(runnable) }
        } else {
            mPendingTask.add(runnable)
        }
    }

    /**
     * Remove the task from the pending task queue
     *
     * @param runnable the task to remove
     * @return true if the task was removed successfully
     */
    @Synchronized
    fun remove(runnable: Runnable): Boolean {
        mHandler.removeCallbacks(runnable)
        return mPendingTask.remove(runnable)
    }

    /**
     * Should be called when the condition is met
     */
    @Synchronized
    fun onConditionMet() {
        if (Looper.myLooper() == mHandler.looper) {
            val iterator = mPendingTask.iterator()

            while (iterator.hasNext()) {
                iterator.next().run()
                iterator.remove()
            }
        } else {
            mHandler.post { this.onConditionMet() }
        }
    }

    /**
     * Clear all the pending tasks and remove them from the handler queue
     */
    @Synchronized
    fun clear() {
        for (runnable in mPendingTask)
            mHandler.removeCallbacks(runnable)

        mPendingTask.clear()
    }
}

Пожалуйста, посмотрите исходный код для полного примера.

0 голосов
/ 11 февраля 2019

Просто положите initViews(); внутрь success вот так

@Override
protected void onStart() {
    super.onStart();

    loadCards(new Callback(){
        success(List<Card> cardList){initViews();}
        fail(){do other thing}
    });
}
...