在onStart()中完成方法A()后如何在onResume()中启动方法B()

时间:2019-02-11 03:03:48

标签: android mvp lifecycle

在onStart()内部完成方法A()(工作线程)后,如何在onResume()内部启动方法B()(主线程)

我在onStart()中有loadCards(),在onResume()中有initViews()。

仅在loadCards()完成后才需要运行initViews(),loadCards()是长时间运行的操作,并且具有callback()。

当前问题是initViews()在loadCards()完成之前运行,因此获取空指针。

是否想获得帮助:如何仅在loadCards()(instart内)完成后才运行initViews()(inonResume)?

@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 :(得分:1)

只需将您的initViews();这样放在success

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

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

答案 1 :(得分:0)

在满足特定条件(例如恢复活动)时,您可以使用https://github.com/EliyahuShwartz/ConditionalTasksRunner运行特定任务

此代码是为从另一个类(通常为presenter)运行视图任务而设计的,无需注意Android生命周期。

基本实现将是

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

,然后您便可以在decleration类中的任何位置发布任务。

mResumePendingTasks.runOnConditionMet(Runnable { onListLoadedSuccessfully() })

ConditionalTask​​sRunner的源代码为:

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

请查看源代码以获取完整的示例。