package org.emdev.ui; import org.sufficientlysecure.viewer.R; import org.ebookdroid.ui.about.AboutActivity; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.Menu; import android.view.MenuItem; import android.view.View; import java.util.concurrent.atomic.AtomicLong; import org.emdev.common.log.LogContext; import org.emdev.common.log.LogManager; import org.emdev.ui.actions.ActionEx; import org.emdev.ui.actions.ActionMenuHelper; import org.emdev.ui.actions.ActionMethod; public abstract class AbstractActionActivity<A extends Activity, C extends AbstractActivityController<A>> extends AppCompatActivity implements ActivityEvents { private static final AtomicLong SEQ = new AtomicLong(); public final LogContext LCTX; public final long id; final boolean shouldBeTaskRoot; final int eventMask; protected boolean recreated; C controller; protected AbstractActionActivity(final boolean shouldBeTaskRoot, final int... events) { id = SEQ.getAndIncrement(); LCTX = LogManager.root().lctx(this.getClass().getSimpleName(), true).lctx("" + id, true); this.shouldBeTaskRoot = shouldBeTaskRoot; this.eventMask = ActivityEvents.Helper.merge(events); } @Override public final Object onRetainCustomNonConfigurationInstance() { return getController(); } public final C getController() { if (controller == null) { controller = createController(); } return controller; } protected abstract C createController(); @Override @SuppressWarnings({ "unchecked", "deprecation" }) protected final void onCreate(final Bundle savedInstanceState) { if (shouldBeTaskRoot && !isTaskRoot()) { super.onCreate(savedInstanceState); // Workaround for Android 2.1- if (LCTX.isDebugEnabled()) { LCTX.d("onCreate(): close duplicated activity"); } finish(); return; } if (LCTX.isDebugEnabled()) { LCTX.d("onCreate(): " + savedInstanceState); } // Check if controller was created before final Object last = this.getLastNonConfigurationInstance(); if (last instanceof AbstractActivityController) { this.recreated = true; this.controller = (C) last; this.controller.setManagedComponent((A) this); if (Helper.enabled(this.controller.eventMask, BEFORE_RECREATE)) { if (this.controller.LCTX.isDebugEnabled()) { this.controller.LCTX.d("beforeRecreate(): " + this); } this.controller.beforeRecreate((A) this); } } else { this.recreated = false; this.controller = createController(); if ((this.controller.eventMask & BEFORE_CREATE) == BEFORE_CREATE) { if (this.controller.LCTX.isDebugEnabled()) { this.controller.LCTX.d("beforeCreate(): " + this); } this.controller.beforeCreate((A) this); } } super.onCreate(savedInstanceState); if (Helper.enabled(this.eventMask, ON_CREATE)) { onCreateImpl(savedInstanceState); } if (Helper.enabled(this.controller.eventMask, AFTER_CREATE)) { if (this.controller.LCTX.isDebugEnabled()) { this.controller.LCTX.d("afterCreate(): " + recreated); } this.controller.afterCreate((A) this, recreated); } } protected void onCreateImpl(final Bundle savedInstanceState) { } @Override protected final void onRestart() { if (LCTX.isDebugEnabled()) { LCTX.d("onRestart()"); } super.onRestart(); if (Helper.enabled(this.eventMask, ON_RESTART)) { onRestartImpl(); } if (Helper.enabled(this.controller.eventMask, ON_RESTART)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onRestart(): " + recreated); } controller.onRestart(recreated); } } protected void onRestartImpl() { } @Override protected final void onStart() { if (LCTX.isDebugEnabled()) { LCTX.d("onStart()"); } super.onStart(); if (Helper.enabled(this.eventMask, ON_START)) { onStartImpl(); } if (Helper.enabled(this.controller.eventMask, ON_START)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onStart(): " + recreated); } controller.onStart(recreated); } } protected void onStartImpl() { } @Override protected final void onPostCreate(final Bundle savedInstanceState) { if (LCTX.isDebugEnabled()) { LCTX.d("onCreate(): " + savedInstanceState); } super.onPostCreate(savedInstanceState); if (Helper.enabled(this.eventMask, ON_POST_CREATE)) { onPostCreateImpl(savedInstanceState); } if (Helper.enabled(this.controller.eventMask, ON_POST_CREATE)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("savedInstanceState(): " + savedInstanceState + ", " + recreated); } controller.onPostCreate(savedInstanceState, recreated); } } protected void onPostCreateImpl(final Bundle savedInstanceState) { } @Override protected final void onResume() { if (LCTX.isDebugEnabled()) { LCTX.d("onResume()"); } super.onResume(); if (Helper.enabled(this.eventMask, ON_RESUME)) { onResumeImpl(); } if (Helper.enabled(this.controller.eventMask, ON_RESUME)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onResume(): " + recreated); } controller.onResume(recreated); } } protected void onResumeImpl() { } @Override protected final void onPostResume() { if (LCTX.isDebugEnabled()) { LCTX.d("onPostResume()"); } super.onPostResume(); if (Helper.enabled(this.eventMask, ON_POST_RESUME)) { onPostResumeImpl(); } if (Helper.enabled(this.controller.eventMask, ON_POST_RESUME)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onPostResume(): " + recreated); } controller.onPostResume(recreated); } } protected void onPostResumeImpl() { } @Override protected final void onPause() { final boolean finishing = isFinishing(); if (LCTX.isDebugEnabled()) { LCTX.d("onPause(): " + finishing); } super.onPause(); if (Helper.enabled(this.eventMask, ON_PAUSE)) { onPauseImpl(finishing); } if (Helper.enabled(this.controller.eventMask, ON_PAUSE)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onPause(): " + finishing); } controller.onPause(finishing); } } protected void onPauseImpl(final boolean finishing) { } @Override protected final void onStop() { final boolean finishing = isFinishing(); if (LCTX.isDebugEnabled()) { LCTX.d("onStop(): " + finishing); } super.onStop(); if (Helper.enabled(this.eventMask, ON_STOP)) { onStopImpl(finishing); } if (Helper.enabled(this.controller.eventMask, ON_STOP)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onStop(): " + finishing); } controller.onStop(finishing); } } protected void onStopImpl(final boolean finishing) { } @Override protected final void onDestroy() { if (shouldBeTaskRoot && !isTaskRoot()) { if (LCTX.isDebugEnabled()) { LCTX.d("onDestroy(): close duplicated activity"); } super.onDestroy(); return; } final boolean finishing = isFinishing(); if (LCTX.isDebugEnabled()) { LCTX.d("onDestroy(): " + finishing); } super.onDestroy(); if (Helper.enabled(this.eventMask, ON_DESTROY)) { onDestroyImpl(finishing); } if (Helper.enabled(this.controller.eventMask, ON_DESTROY)) { if (controller.LCTX.isDebugEnabled()) { controller.LCTX.d("onDestroy(): " + finishing); } controller.onDestroy(finishing); } } protected void onDestroyImpl(final boolean finishing) { } @Override public final boolean onPrepareOptionsMenu(final Menu menu) { super.onPrepareOptionsMenu(menu); if (menu != null) { updateMenuItems(menu); } return true; } protected void updateMenuItems(final Menu menu) { } @Override public final boolean onOptionsItemSelected(final MenuItem item) { if (onMenuItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } @Override public boolean onContextItemSelected(final MenuItem item) { if (onMenuItemSelected(item)) { return true; } return super.onContextItemSelected(item); } protected boolean onMenuItemSelected(final MenuItem item) { final int actionId = item.getItemId(); final ActionEx action = getController().getOrCreateAction(actionId); if (action.getMethod().isValid()) { ActionMenuHelper.setActionParameters(item, action); action.run(); return true; } return false; } public final void onButtonClick(final View view) { final int actionId = view.getId(); final ActionEx action = getController().getOrCreateAction(actionId); action.onClick(view); } @Override protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) { if (resultCode == RESULT_CANCELED) { return; } if (data != null) { final int actionId = data.getIntExtra(ActionMenuHelper.ACTIVITY_RESULT_ACTION_ID, 0); if (actionId != 0) { final ActionEx action = getController().getOrCreateAction(actionId); action.putValue(ActionMenuHelper.ACTIVITY_RESULT_CODE, Integer.valueOf(resultCode)); action.putValue(ActionMenuHelper.ACTIVITY_RESULT_DATA, data); action.run(); } } } public final void setActionForView(final int id) { final View view = findViewById(id); final ActionEx action = getController().getOrCreateAction(id); if (view != null && action != null) { view.setOnClickListener(action); } } @ActionMethod(ids = R.id.mainmenu_about) public void showAbout(final ActionEx action) { final Intent i = new Intent(this, AboutActivity.class); startActivity(i); } }