/* * Copyright (C) 2015 OpenSilk Productions LLC * * 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 org.opensilk.common.core.mortar; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import org.opensilk.common.core.util.ObjectUtils; import java.util.UUID; import mortar.MortarScope; import mortar.bundler.BundleServiceRunner; import timber.log.Timber; /** * Even though this in a ui component its in core so simpler apps can pull it * without the bloat of common-ui * * Created by drew on 3/6/15. */ public abstract class MortarActivity extends AppCompatActivity implements HasScope { private String mScopeName; protected MortarScope mActivityScope; protected boolean mIsResumed; protected boolean mConfigurationChangeIncoming; protected abstract void onCreateScope(MortarScope.Builder builder); /** * Allows abstract subclasses to inject additional services * without worrying about their concrete offspring forgetting * to call super */ protected void onPreCreateScope(MortarScope.Builder buidler) { } /** * Called after scope is created but before super.onCreate() * mostly useful for themeing */ protected void onScopeCreated(MortarScope scope) { } @Override protected void onCreate(Bundle savedInstanceState) { mActivityScope = MortarScope.findChild(getApplicationContext(), getScopeName()); if (mActivityScope == null) { MortarScope.Builder builder = MortarScope.buildChild(getApplicationContext()) .withService(BundleServiceRunner.SERVICE_NAME, new BundleServiceRunner()); onPreCreateScope(builder); onCreateScope(builder); mActivityScope = builder.build(getScopeName()); Timber.d("Created new scope %s", mActivityScope.getName()); } else { Timber.d("Reusing old scope %s", mActivityScope.getName()); } onScopeCreated(mActivityScope); super.onCreate(savedInstanceState); BundleServiceRunner.getBundleServiceRunner(this).onCreate(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); BundleServiceRunner.getBundleServiceRunner(this).onSaveInstanceState(outState); } @Override protected void onDestroy() { super.onDestroy(); if (!mConfigurationChangeIncoming) { // Destroy our scope if (mActivityScope != null && !mActivityScope.isDestroyed()) { Timber.d("Destroying activity scope"); mActivityScope.destroy(); } mActivityScope = null; } } @Override protected void onResume() { super.onResume(); mIsResumed = true; } @Override protected void onPause() { super.onPause(); mIsResumed = false; } @Override public Object onRetainCustomNonConfigurationInstance() { mConfigurationChangeIncoming = true; return mScopeName; } @Override public Object getSystemService(String name) { //Note we dont create the scope here since this is usually called //before onCreate and we need to be able to fetch our scope name //on configuration changes return (mActivityScope != null && mActivityScope.hasService(name)) ? mActivityScope.getService(name) : super.getSystemService(name); } @Override public MortarScope getScope() { return mActivityScope; } private String getScopeName() { if (mScopeName == null) { mScopeName = (String) getLastCustomNonConfigurationInstance(); } if (mScopeName == null) { mScopeName = ObjectUtils.<MortarActivity>getClass(this).getSimpleName() + "-" + UUID.randomUUID().toString(); } return mScopeName; } }