/*
* Copyright (c) 2014-2015 Sean Liu.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.github.baoti.pioneer.ui.splash;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.support.annotation.Keep;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import com.github.baoti.android.presenter.Presenter;
import com.github.baoti.pioneer.app.task.SafeAsyncTask;
import com.github.baoti.pioneer.biz.interactor.AppInteractor;
import com.github.baoti.pioneer.event.app.AppInitializeReportEvent;
import com.github.baoti.pioneer.misc.util.Texts;
import com.github.baoti.pioneer.ui.ForUi;
import com.squareup.otto.Subscribe;
import java.util.concurrent.TimeUnit;
import javax.inject.Inject;
import timber.log.Timber;
/**
* Created by liuyedong on 14-12-23.
*/
public class SplashPresenter extends Presenter<ISplashView> {
private static final long SPLASH_TIME = TimeUnit.SECONDS.toMillis(1);
private static final String STATE_HIDE_BUTTON = "Splash-HideButton";
private InitializeTask task;
private final AppInteractor appInteractor;
private final Handler uiHandler;
private String status;
private long counter;
private boolean hideButton;
private boolean hasNavigated;
private boolean hideButtonInBundle;
private long entryTime;
/**
* 未处理的启动Main界面的操作,当初始化完成后,将不为null,即可以启动了。
*/
private Runnable launchMainPending;
@Inject
public SplashPresenter(AppInteractor interactor, @ForUi Handler handler) {
appInteractor = interactor;
uiHandler = handler;
}
@Override
protected void onLoad(@Nullable Bundle savedInstanceState, boolean reusing) {
super.onLoad(savedInstanceState, reusing);
if (savedInstanceState != null) {
hideButtonInBundle = savedInstanceState.getBoolean(STATE_HIDE_BUTTON, false);
if (hideButtonInBundle) {
getView().hideRetainInBundle();
}
} else {
hideButtonInBundle = false;
entryTime = System.currentTimeMillis();
}
if (task == null) {
task = new InitializeTask();
task.executeOnDefaultThreadPool();
} else {
showStatus(status, false);
}
if (hideButton) {
getView().hideRetainInPresenter();
}
}
@Override
protected void onResume() {
super.onResume();
autoLaunchMain();
}
@Override
protected void onPause() {
pauseAutoLaunchMain();
super.onPause();
}
@Override
protected void onSave(@NonNull Bundle outState) {
outState.putBoolean(STATE_HIDE_BUTTON, hideButtonInBundle);
}
@Override
protected void onClose() {
cancelAutoLaunchMain();
task.cancel(true);
task = null;
super.onClose();
}
private void cancelAutoLaunchMain() {
uiHandler.removeCallbacks(launchMainPending);
launchMainPending = null;
}
private void autoLaunchMain() {
if (launchMainPending != null) {
uiHandler.removeCallbacks(launchMainPending);
long passingTime = System.currentTimeMillis() - entryTime;
long expTime = SPLASH_TIME - passingTime;
Timber.v("expTime: %s", expTime);
uiHandler.postDelayed(launchMainPending, expTime);
}
}
private void pauseAutoLaunchMain() {
uiHandler.removeCallbacks(launchMainPending);
}
public void onGoToMainClicked() {
navigateToMain();
}
private void navigateToMain() {
if (!hasView()) {
return;
}
hasNavigated = true;
cancelAutoLaunchMain();
getView().navigateToMain(false);
}
private void showStatus(String status, boolean update) {
if (!hasView()) {
return;
}
if (update) {
counter++;
}
this.status = status;
getView().showStatus(String.format(
"(%d)\n%s\n%s",
counter,
task == null ? "null" : Texts.filledStr((int) task.countSeconds(), '.'),
status));
}
private void handleInitializeFinished(Boolean success) {
if (hasNavigated) {
Timber.i("Has navigated, do nothing");
} else if (success) {
if (launchMainPending == null) {
launchMainPending = new Runnable() {
@Override
public void run() {
navigateToMain();
}
};
autoLaunchMain();
}
} else {
// post an Exit Event
}
}
public void onRetainInPresenterClicked() {
hideButton = true;
getView().hideRetainInPresenter();
}
public void onRetainInBundleClicked() {
hideButtonInBundle = true;
getView().hideRetainInBundle();
}
class InitializeTask extends SafeAsyncTask<Void, String, Void> {
private long startTime;
public InitializeTask() {
super(true);
}
@Override
protected void onStart() {
startTime = SystemClock.uptimeMillis();
showStatus("正在初始化应用", true);
}
long countSeconds() {
return (SystemClock.uptimeMillis() - startTime) / 1000;
}
@Override
protected Void doTask(Void... params) throws Exception {
appInteractor.initialize();
return null;
}
@Override
protected void onException(Exception exception) {
Timber.e(exception, "Unable initialize app");
handleInitializeFinished(false);
}
@Override
protected void onCancel() {
Timber.i("onCancel");
}
@Override
protected void onSuccess(Void aVoid) {
handleInitializeFinished(true);
}
@Override
protected void onProgressUpdate(String... values) {
showStatus(values[0], true);
}
@Subscribe @Keep
public void onAppInitialize(AppInitializeReportEvent event) {
publishProgress(event.progress);
}
}
}