/** {@inheritDoc} */ @Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); { Debug.print(tag, "new intent", intent); } }
/** {@inheritDoc} */ @Override protected void onRestart() { super.onRestart(); { Debug.print(tag, "restart"); } }
/** * Initialize and return this.database object. * * @return SQLiteDatabase properly initialized. * @throws IOException on error. */ @Override protected SQLiteDatabase getDatabase() throws IOException { Debug.enter(); final SQLiteDatabase database = DatabaseSession.getDatabase(Android.App.INSTANCE); Debug.leave(); return database; }
/** * Initialize and return path, relative from the "home" directory. * * @param path inside $HOME * @return File($HOME, path) properly initialized * @throws IOException on error */ @Override protected File getHome(final String path) throws IOException { // @see http://en.wikipedia.org/wiki/Double-checked_locking. The use of local variable // 'directory' seems // unnecessary. It will make the code 25% faster for some Java VM, and it won't hurt for others File directory = home; if (directory != null) { Debug.print("home", directory.getAbsolutePath()); return ((path == null) || (path.length() <= 0)) ? directory : new File(directory, path); } Debug.enter(); synchronized (LOCK) { directory = home; if (directory != null) { Debug.print("lost getHome singleton race"); } else { // initialize home directory = new File(Android.App.DATA_DIRECTORY_NAME); // next will be very slow restoreMissingFiles(directory); // finally, home home = directory; } } Debug.leave(directory.getAbsolutePath()); return ((path == null) || (path.length() <= 0)) ? directory : new File(directory, path); }
/** * Load {@link Bookmark} instance, creating it if it does not exist. * * @param title the {@link Bookmark}'s title to load. * @return the {@link Bookmark} for the given <code>title</code>, or null if <code>title</code> is * null. */ protected Bookmark loadBookmark(final String title) { Debug.enter(title); Bookmark bookmark = null; final String titleValue = (title != null) ? title.trim() : ""; if (0 < titleValue.length()) { synchronized (AbstractProfileCRUD.LOCK) { String basename = AbstractUserProfileStorage.getBasename(titleValue); final boolean adding = (basename == null); if (adding) { basename = AbstractUserProfileStorage.getBasename(); } final SharedPreferences prefs = AbstractProfile.getSharedPreferences(basename); bookmark = readBookmark(prefs, basename, titleValue); if (adding) { writeBookmark(prefs, bookmark); } } } Debug.leave("loaded", titleValue, (bookmark != null) ? bookmark.title : null); return bookmark; }
/** {@inheritDoc} */ @Override public void flash(final String message) { Debug.enter(tag, message); if (message != null) { Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } Debug.leave(tag); }
/** {@inheritDoc} */ @Override public boolean isTerminated() { Debug.enter(tag); boolean terminated = false; if (wasDestroyed || isFinishing()) { Debug.print(tag, "activity terminated"); terminated = wasDestroyed = true; } Debug.leave(tag, terminated); return terminated; }
/** * Save {@link Bookmark} instance. * * @param bookmark to save. * @return true on success, false otherwise. */ protected boolean saveBookmark(final Bookmark bookmark) { Debug.enter(); boolean success = false; if (bookmark != null && bookmark.title != null) { synchronized (AbstractProfileCRUD.LOCK) { final SharedPreferences prefs = bookmark.getSharedPreferences(); success = writeBookmark(prefs, bookmark); } } Debug.leave("saved?", success, (bookmark != null) ? bookmark.title : null); return success; }
/** {@inheritDoc} */ @Override public void onConfigurationChanged(final Configuration newConfig) { super.onConfigurationChanged(newConfig); { Debug.enter(); try { Debug.print(tag, "configurationChanged", newConfig.locale); Android.App.setLocale(newConfig.locale); } catch (final IOException ex) { Debug.error(ex, tag, "unable to set new locale", newConfig.locale); } Debug.leave(); } }
/** {@inheritDoc} */ @Override protected void onStop() { Debug.print(tag, "stop"); { super.onStop(); } }
/** {@inheritDoc} */ @Override protected void onPause() { Debug.print(tag, "pause"); { super.onPause(); } }
/** {@inheritDoc} */ @Override protected void onRestoreInstanceState(final Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); { Debug.print(tag, "restoreInstanceState"); } }
/** * Called when the application is created. Override this method to initialize our application * singleton and to create and initialize any application state variables or shared resources. */ @Override public void onCreate() { super.onCreate(); { Debug.print("create"); } }
/** {@inheritDoc} */ @Override protected void onSaveInstanceState(final Bundle instanceState) { { Debug.print(tag, "saveInstanceState"); } super.onSaveInstanceState(instanceState); }
/** * Called when a background process have already been terminated and the current foreground * applications are still low on memory. Override this method to clear caches or release * unnecessary resources. */ @Override public void onLowMemory() { super.onLowMemory(); { Debug.print("lowMemory"); DatabaseSession.close(); // to free buffers } }
/** * Called when the application object is terminated. There is no guarantee of this method being * called. */ @Override public void onTerminate() { { Debug.print("terminate"); DatabaseSession.close(); } super.onTerminate(); }
/** {@inheritDoc} */ @Override protected void onDestroy() { { Debug.print(tag, "destroy"); wasDestroyed = true; } super.onDestroy(); }
/** {@inheritDoc} */ @Override protected void onResume() { super.onResume(); { Debug.print(tag, "resume"); if (controller != null) { controller.register(this); } } }
/** {@inheritDoc} */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); { Debug.print(tag, "create"); final Window window = getWindow(); // increase the color range a lot window.setFormat(PixelFormat.RGBA_8888); // activate dithering for all your activity window.addFlags(WindowManager.LayoutParams.FLAG_DITHER); } }
/** * Setup missing application files into the "home directory". * * @param targetDir * @throws IOException * @return true on success */ private boolean restoreMissingFiles(final File targetDir) throws IOException { Debug.enter(); boolean success = false; final SharedPreferences prefs = Settings.INSTANCE.getSharedPreferences(); final String oldTarball = prefs.getString(SettingsStorage.FIELD_TARBALL, null); final String newTarball = getString(R.string.build_tarball); final boolean keepOldFiles = newTarball.equals(oldTarball); try { // extract the tar-ball to recover any missing file, if any final TarArchive tarball = new TarArchive(new GZIPInputStream(tarballFile())); tarball.keepOldFiles = keepOldFiles; tarball.extract(targetDir); tarball.close(); // once the restore is completed successfully, // we need to update the shared preference, if necessary if (!keepOldFiles) { final SharedPreferences.Editor edit = prefs.edit(); edit.putString(SettingsStorage.FIELD_TARBALL, newTarball); success = edit.commit(); } else { success = true; } } catch (final Resources.NotFoundException ex) { // this exception usually would happen from the unit-tests Debug.error(ex, "tarball resources not found", keepOldFiles); // not really a fatal error if keepOldFiles is true if (!keepOldFiles) { Debug.leave(); throw new IOException("Tarball resources missing"); } } catch (final TarArchive.TarHeaderException ex) { Debug.error(ex, "invalid tarball header", keepOldFiles); Debug.leave(); throw new IOException("Invalid tarball format"); } catch (final IOException ex) { Debug.error(ex, "unable to install tarball", keepOldFiles); // not really a fatal error if keepOldFiles is true if (!keepOldFiles) { Debug.leave(); throw ex; } } Debug.leave(success); return success; }
/** {@inheritDoc} */ @Override public void onControllerUpdated() { Debug.print(tag, "model/view/controller updated"); }
/** * Setter - set {@link AbstractController}. * * @param controller to setup. */ protected void setController(final AbstractController controller) { Debug.enter(tag, controller); this.controller = controller; Debug.leave(tag); }
/** * {@link Activity} base class. All activities in the final application should be derived from this * class. * * @see "http://code.google.com/p/android-family-browser/" * @author <a href="mailto:[email protected]">David A Chaves</a> */ public abstract class AbstractActivity extends Activity implements Controllable { /** Internal name, used to distinguish which instance is being used in log messages. */ protected String tag = Debug.getUniqueTag(AbstractActivity.class); /** Handler for posting actions. */ protected final Handler handler = new Handler(); /** Has {@link AbstractActivity#onDestroy} been called? */ private volatile boolean wasDestroyed; /** The Activity controller. */ private AbstractController controller; // ------- // Setters // ------- /** * Setter - set {@link AbstractController}. * * @param controller to setup. */ protected void setController(final AbstractController controller) { Debug.enter(tag, controller); this.controller = controller; Debug.leave(tag); } // -------------------- // Controller interface // -------------------- /** {@inheritDoc} */ @Override public boolean isTerminated() { Debug.enter(tag); boolean terminated = false; if (wasDestroyed || isFinishing()) { Debug.print(tag, "activity terminated"); terminated = wasDestroyed = true; } Debug.leave(tag, terminated); return terminated; } /** {@inheritDoc} */ @Override public void onControllerUpdated() { Debug.print(tag, "model/view/controller updated"); } /** {@inheritDoc} */ @Override public void flash(final String message) { Debug.enter(tag, message); if (message != null) { Toast.makeText(this, message, Toast.LENGTH_LONG).show(); } Debug.leave(tag); } // ---------- // Life Cycle // ---------- /** {@inheritDoc} */ @Override public void onCreate(final Bundle savedInstanceState) { super.onCreate(savedInstanceState); { Debug.print(tag, "create"); final Window window = getWindow(); // increase the color range a lot window.setFormat(PixelFormat.RGBA_8888); // activate dithering for all your activity window.addFlags(WindowManager.LayoutParams.FLAG_DITHER); } } /** {@inheritDoc} */ @Override protected void onStart() { super.onStart(); { Debug.print(tag, "start"); } } /** {@inheritDoc} */ @Override protected void onResume() { super.onResume(); { Debug.print(tag, "resume"); if (controller != null) { controller.register(this); } } } /** {@inheritDoc} */ @Override protected void onPause() { Debug.print(tag, "pause"); { super.onPause(); } } /** {@inheritDoc} */ @Override protected void onStop() { Debug.print(tag, "stop"); { super.onStop(); } } /** {@inheritDoc} */ @Override protected void onRestart() { super.onRestart(); { Debug.print(tag, "restart"); } } /** {@inheritDoc} */ @Override protected void onDestroy() { { Debug.print(tag, "destroy"); wasDestroyed = true; } super.onDestroy(); } // ---------- // Call backs // ---------- /** {@inheritDoc} */ @Override protected void onRestoreInstanceState(final Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); { Debug.print(tag, "restoreInstanceState"); } } /** {@inheritDoc} */ @Override protected void onSaveInstanceState(final Bundle instanceState) { { Debug.print(tag, "saveInstanceState"); } super.onSaveInstanceState(instanceState); } /** {@inheritDoc} */ @Override public void onConfigurationChanged(final Configuration newConfig) { super.onConfigurationChanged(newConfig); { Debug.enter(); try { Debug.print(tag, "configurationChanged", newConfig.locale); Android.App.setLocale(newConfig.locale); } catch (final IOException ex) { Debug.error(ex, tag, "unable to set new locale", newConfig.locale); } Debug.leave(); } } /** {@inheritDoc} */ @Override protected void onNewIntent(final Intent intent) { super.onNewIntent(intent); { Debug.print(tag, "new intent", intent); } } }
/** * Change language for this application only (not system-wide). * * @param locale the new {@link Locale} instance. * @throws IOException on error. */ @Override protected void setLocale(final Locale locale) throws IOException { Debug.enter(locale); DatabaseSession.setLocale(Android.App.INSTANCE, locale); Debug.leave(locale); }