From 9a6dafaa79a0244e2e05b8ef5d4bb3873e090ec3 Mon Sep 17 00:00:00 2001 From: Alinson Xavier Date: Sun, 12 Jun 2016 09:23:55 -0400 Subject: [PATCH] Improve documentation --- .../java/org/isoron/uhabits/models/Habit.java | 5 +- .../models/sqlite/records/package-info.java | 23 +++ .../org/isoron/uhabits/tasks/ProgressBar.java | 10 + ...arWrapper.java => AndroidProgressBar.java} | 21 +- .../org/isoron/uhabits/ui/BaseActivity.java | 28 ++- .../java/org/isoron/uhabits/ui/BaseMenu.java | 68 +++++-- .../org/isoron/uhabits/ui/BaseScreen.java | 97 ++++++--- .../isoron/uhabits/ui/BaseSelectionMenu.java | 64 +++++- .../org/isoron/uhabits/ui/BaseSystem.java | 190 ++++++++++-------- .../habits/list/ListHabitsSelectionMenu.java | 4 +- 10 files changed, 352 insertions(+), 158 deletions(-) create mode 100644 app/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java rename app/src/main/java/org/isoron/uhabits/ui/{ProgressBarWrapper.java => AndroidProgressBar.java} (83%) diff --git a/app/src/main/java/org/isoron/uhabits/models/Habit.java b/app/src/main/java/org/isoron/uhabits/models/Habit.java index 7b0e57ff4..00c11d16d 100644 --- a/app/src/main/java/org/isoron/uhabits/models/Habit.java +++ b/app/src/main/java/org/isoron/uhabits/models/Habit.java @@ -259,7 +259,7 @@ public class Habit return id; } - public void setId(Long id) + public void setId(@Nullable Long id) { this.id = id; } @@ -267,12 +267,13 @@ public class Habit /** * Name of the habit */ + @NonNull public String getName() { return name; } - public void setName(String name) + public void setName(@NonNull String name) { this.name = name; } diff --git a/app/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java b/app/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java new file mode 100644 index 000000000..379d6a6e0 --- /dev/null +++ b/app/src/main/java/org/isoron/uhabits/models/sqlite/records/package-info.java @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2016 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +/** + * Provides classes that represent rows in the SQLite database. + */ +package org.isoron.uhabits.models.sqlite.records; \ No newline at end of file diff --git a/app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java b/app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java index 17c3ebbf1..afbfdac7a 100644 --- a/app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java +++ b/app/src/main/java/org/isoron/uhabits/tasks/ProgressBar.java @@ -19,8 +19,18 @@ package org.isoron.uhabits.tasks; +/** + * Simple progress bar, used to indicate the progress of a task. + */ public interface ProgressBar { + /** + * Shows the progress bar. + */ void show(); + + /** + * Hides the progress bar. + */ void hide(); } diff --git a/app/src/main/java/org/isoron/uhabits/ui/ProgressBarWrapper.java b/app/src/main/java/org/isoron/uhabits/ui/AndroidProgressBar.java similarity index 83% rename from app/src/main/java/org/isoron/uhabits/ui/ProgressBarWrapper.java rename to app/src/main/java/org/isoron/uhabits/ui/AndroidProgressBar.java index 44339ebf6..22604c44c 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/ProgressBarWrapper.java +++ b/app/src/main/java/org/isoron/uhabits/ui/AndroidProgressBar.java @@ -19,29 +19,32 @@ package org.isoron.uhabits.ui; -import android.view.View; +import android.view.*; -import org.isoron.uhabits.tasks.ProgressBar; +import org.isoron.uhabits.tasks.*; -public class ProgressBarWrapper implements ProgressBar +/** + * Android implementation of {@link ProgressBar}. + */ +public class AndroidProgressBar implements ProgressBar { private final android.widget.ProgressBar progressBar; - public ProgressBarWrapper(android.widget.ProgressBar progressBar) + public AndroidProgressBar(android.widget.ProgressBar progressBar) { this.progressBar = progressBar; } @Override - public void show() + public void hide() { - progressBar.setIndeterminate(true); - progressBar.setVisibility(View.VISIBLE); + progressBar.setVisibility(View.GONE); } @Override - public void hide() + public void show() { - progressBar.setVisibility(View.GONE); + progressBar.setIndeterminate(true); + progressBar.setVisibility(View.VISIBLE); } } diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java b/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java index bdc066fc9..84e66d61e 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java +++ b/app/src/main/java/org/isoron/uhabits/ui/BaseActivity.java @@ -19,17 +19,25 @@ package org.isoron.uhabits.ui; -import android.content.Intent; -import android.os.Bundle; -import android.support.annotation.Nullable; -import android.support.v7.app.AppCompatActivity; -import android.view.Menu; -import android.view.MenuItem; +import android.content.*; +import android.os.*; +import android.support.annotation.*; +import android.support.v7.app.*; +import android.view.*; -import org.isoron.uhabits.utils.InterfaceUtils; +import org.isoron.uhabits.utils.*; /** * Base class for all activities in the application. + *

+ * This class delegates the responsibilities of an Android activity to other + * classes. For example, callbacks related to menus are forwarded to a {@link + * BaseMenu}, while callbacks related to activity results are forwarded to a + * {@link BaseScreen}. + *

+ * A BaseActivity also installs an {@link java.lang.Thread.UncaughtExceptionHandler} + * to the main thread that logs the exception to the disk before the application + * crashes. */ abstract public class BaseActivity extends AppCompatActivity implements Thread.UncaughtExceptionHandler @@ -48,7 +56,8 @@ abstract public class BaseActivity extends AppCompatActivity { if (menu == null) return false; if (baseMenu == null) return false; - return baseMenu.onCreate(getMenuInflater(), menu); + baseMenu.onCreate(getMenuInflater(), menu); + return true; } @Override @@ -79,7 +88,8 @@ abstract public class BaseActivity extends AppCompatActivity { ex.printStackTrace(); new BaseSystem(this).dumpBugReportToFile(); - } catch (Exception e) + } + catch (Exception e) { // ignored } diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseMenu.java b/app/src/main/java/org/isoron/uhabits/ui/BaseMenu.java index ffa30706a..c3f789345 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/BaseMenu.java +++ b/app/src/main/java/org/isoron/uhabits/ui/BaseMenu.java @@ -19,11 +19,18 @@ package org.isoron.uhabits.ui; -import android.support.annotation.NonNull; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; +import android.support.annotation.*; +import android.view.*; +import javax.annotation.*; + +/** + * Base class for all the menus in the application. + *

+ * This class receives from BaseActivity all callbacks related to menus, such as + * menu creation and click events. It also handles some implementation details + * of creating menus in Android, such as inflating the resources. + */ public abstract class BaseMenu { private final BaseActivity activity; @@ -33,28 +40,59 @@ public abstract class BaseMenu this.activity = activity; } - public final boolean onCreate(@NonNull MenuInflater inflater, - @NonNull Menu menu) + /** + * Declare that the menu has changed, and should be recreated. + */ + public void invalidate() { - menu.clear(); - inflater.inflate(getMenuResourceId(), menu); - onCreate(menu); - return true; + activity.invalidateOptionsMenu(); } + /** + * Called when the menu is first displayed. + *

+ * The given menu is already inflated and ready to receive items. The + * application should override this method and add items to the menu here. + * + * @param menu the menu that is being created. + */ public void onCreate(@NonNull Menu menu) { } + /** + * Called when the menu is first displayed. + *

+ * This method cannot be overridden. The application should override the + * methods onCreate(Menu) and getMenuResourceId instead. + * + * @param inflater a menu inflater, for creating the menu + * @param menu the menu that is being created. + */ + public final void onCreate(@NonNull MenuInflater inflater, + @NonNull Menu menu) + { + menu.clear(); + inflater.inflate(getMenuResourceId(), menu); + onCreate(menu); + } + + /** + * Called whenever an item on the menu is selected. + * + * @param item the item that was selected. + * @return true if the event was consumed, or false otherwise + */ public boolean onItemSelected(@NonNull MenuItem item) { return true; } + /** + * Returns the id of the resource that should be used to inflate this menu. + * + * @return id of the menu resource. + */ + @Resource protected abstract int getMenuResourceId(); - - public void invalidate() - { - activity.invalidateOptionsMenu(); - } } diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java b/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java index d61ffae53..f6df69818 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java +++ b/app/src/main/java/org/isoron/uhabits/ui/BaseScreen.java @@ -19,26 +19,30 @@ package org.isoron.uhabits.ui; -import android.content.Intent; -import android.graphics.Color; -import android.graphics.drawable.ColorDrawable; -import android.net.Uri; -import android.os.Build; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.support.v7.app.ActionBar; -import android.support.v7.app.AppCompatDialogFragment; +import android.content.*; +import android.graphics.*; +import android.graphics.drawable.*; +import android.net.*; +import android.os.*; +import android.support.annotation.*; +import android.support.v7.app.*; import android.support.v7.view.ActionMode; import android.support.v7.widget.Toolbar; -import android.view.Menu; -import android.view.MenuItem; -import android.widget.Toast; +import android.view.*; +import android.widget.*; import org.isoron.uhabits.tasks.ProgressBar; -import org.isoron.uhabits.utils.ColorUtils; +import org.isoron.uhabits.utils.*; -import java.io.File; +import java.io.*; +/** + * Base class for all screens in the application. + *

+ * Screens are responsible for deciding what root views and what menus should be + * attached to the main window. They are also responsible for showing other + * screens and for receiving their results. + */ public abstract class BaseScreen { protected BaseActivity activity; @@ -56,34 +60,72 @@ public abstract class BaseScreen this.activity = activity; } + /** + * Ends the current selection operation. + */ public void finishSelection() { if (selectionMenu == null) return; selectionMenu.finish(); } + /** + * Returns the progress bar that is currently visible on the screen. + *

+ * If the root view attached to the screen does not provide any progress + * bars, returns null. + * + * @return current progress bar, or null if there are none. + */ @Nullable public ProgressBar getProgressBar() { if (rootView == null) return null; - return new ProgressBarWrapper(rootView.getProgressBar()); + return new AndroidProgressBar(rootView.getProgressBar()); } + /** + * Notifies the screen that its contents should be updated. + */ public void invalidate() { if (rootView == null) return; rootView.invalidate(); } + /** + * Called when another Activity has finished, and has returned some result. + * + * @param requestCode the request code originally supplied to {@link + * android.app.Activity#startActivityForResult(Intent, + * int, Bundle)}. + * @param resultCode the result code sent by the other activity. + * @param data an Intent containing extra data sent by the other + * activity. + * @see {@link android.app.Activity#onActivityResult(int, int, Intent)} + */ public void onResult(int requestCode, int resultCode, Intent data) { } + /** + * Sets the menu to be shown by this screen. + *

+ * This menu will be visible if when there is no active selection operation. + * If the provided menu is null, then no menu will be shown. + * + * @param menu the menu to be shown. + */ public void setMenu(@Nullable BaseMenu menu) { activity.setBaseMenu(menu); } + /** + * Sets the root view for this screen. + * + * @param rootView the root view for this screen. + */ public void setRootView(@Nullable BaseRootView rootView) { this.rootView = rootView; @@ -94,7 +136,7 @@ public abstract class BaseScreen } /** - * Set the menu to be shown when a selection is active on the screen. + * Sets the menu to be shown when a selection is active on the screen. * * @param menu the menu to be shown during a selection */ @@ -103,6 +145,11 @@ public abstract class BaseScreen this.selectionMenu = menu; } + /** + * Shows a message on the screen. + * + * @param stringId the string resource id for this message. + */ public void showMessage(@Nullable Integer stringId) { if (stringId == null) return; @@ -134,14 +181,21 @@ public abstract class BaseScreen } /** - * Instructs the screen to start a selection. If a selection menu was - * provided, this menu will be shown instead of the regular one. + * Instructs the screen to start a selection. + *

+ * If a selection menu was provided, this menu will be shown instead of the + * regular one. */ public void startSelection() { activity.startSupportActionMode(new ActionModeWrapper()); } + protected void showDialog(AppCompatDialogFragment dialog, String tag) + { + dialog.show(activity.getSupportFragmentManager(), tag); + } + private void initToolbar() { if (rootView == null) return; @@ -174,11 +228,6 @@ public abstract class BaseScreen } } - protected void showDialog(AppCompatDialogFragment dialog, String tag) - { - dialog.show(activity.getSupportFragmentManager(), tag); - } - private class ActionModeWrapper implements ActionMode.Callback { @Override @@ -203,7 +252,7 @@ public abstract class BaseScreen public void onDestroyActionMode(@Nullable ActionMode mode) { if (selectionMenu == null) return; - selectionMenu.onDestroy(); + selectionMenu.onFinish(); } @Override diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseSelectionMenu.java b/app/src/main/java/org/isoron/uhabits/ui/BaseSelectionMenu.java index 960c826d2..eb5595afc 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/BaseSelectionMenu.java +++ b/app/src/main/java/org/isoron/uhabits/ui/BaseSelectionMenu.java @@ -19,13 +19,22 @@ package org.isoron.uhabits.ui; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; +import android.support.annotation.*; import android.support.v7.view.ActionMode; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; +import android.view.*; +/** + * Base class for all the selection menus in the application. + *

+ * A selection menu is a menu that appears when the screen starts a selection + * operation. It contains actions that modify the selected items, such as delete + * or archive. Since it replaces the toolbar, it also has a title. + *

+ * This class hides many implementation details of creating such menus in + * Android. The interface is supposed to look very similar to {@link BaseMenu}, + * with a few additional methods, such as finishing the selection operation. + * Internally, it uses an {@link ActionMode}. + */ public abstract class BaseSelectionMenu { @Nullable @@ -39,35 +48,69 @@ public abstract class BaseSelectionMenu if (actionMode != null) actionMode.finish(); } + /** + * Declare that the menu has changed, and should be recreated. + */ public void invalidate() { if (actionMode != null) actionMode.invalidate(); } - public final void onCreate(@NonNull MenuInflater menuInflater, + /** + * Called when the menu is first displayed. + *

+ * This method cannot be overridden. The application should override the + * methods onCreate(Menu) and getMenuResourceId instead. + * + * @param inflater a menu inflater, for creating the menu + * @param mode the action mode associated with this menu. + * @param menu the menu that is being created. + */ + public final void onCreate(@NonNull MenuInflater inflater, @NonNull ActionMode mode, @NonNull Menu menu) { this.actionMode = mode; - menuInflater.inflate(getResourceId(), menu); + inflater.inflate(getResourceId(), menu); onCreate(menu); } - public void onDestroy() + /** + * Called when the selection operation is about to finish. + */ + public void onFinish() { } + /** + * Called whenever an item on the menu is selected. + * + * @param item the item that was selected. + * @return true if the event was consumed, or false otherwise + */ public boolean onItemClicked(@NonNull MenuItem item) { return false; } + + /** + * Called whenever the menu is invalidated. + * + * @param menu the menu to be refreshed + * @return true if the menu has changes, false otherwise + */ public boolean onPrepare(@NonNull Menu menu) { return false; } + /** + * Sets the title of the selection menu. + * + * @param title the new title. + */ public void setTitle(String title) { if (actionMode != null) actionMode.setTitle(title); @@ -76,10 +119,9 @@ public abstract class BaseSelectionMenu protected abstract int getResourceId(); /** - * Called when the menu is first created, right after the menu has been - * inflated. + * Called when the menu is first created. * - * @param menu the menu containing the buttons + * @param menu the menu being created */ protected void onCreate(@NonNull Menu menu) { diff --git a/app/src/main/java/org/isoron/uhabits/ui/BaseSystem.java b/app/src/main/java/org/isoron/uhabits/ui/BaseSystem.java index 8dbb04681..a95f90f01 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/BaseSystem.java +++ b/app/src/main/java/org/isoron/uhabits/ui/BaseSystem.java @@ -19,29 +19,31 @@ package org.isoron.uhabits.ui; -import android.content.Context; -import android.os.Environment; -import android.support.annotation.NonNull; -import android.view.WindowManager; - -import org.isoron.uhabits.BuildConfig; -import org.isoron.uhabits.HabitsApplication; -import org.isoron.uhabits.models.HabitList; -import org.isoron.uhabits.tasks.BaseTask; -import org.isoron.uhabits.utils.DateUtils; -import org.isoron.uhabits.utils.FileUtils; -import org.isoron.uhabits.utils.ReminderUtils; -import org.isoron.uhabits.widgets.WidgetManager; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.LinkedList; - -import javax.inject.Inject; - +import android.content.*; +import android.os.*; +import android.support.annotation.*; +import android.view.*; + +import org.isoron.uhabits.*; +import org.isoron.uhabits.models.*; +import org.isoron.uhabits.tasks.*; +import org.isoron.uhabits.utils.*; +import org.isoron.uhabits.widgets.*; + +import java.io.*; +import java.lang.Process; +import java.util.*; + +import javax.inject.*; + +/** + * Base class for all systems class in the application. + *

+ * Classes derived from BaseSystem are responsible for handling events and + * sending requests to the Android operating system. Examples include capturing + * a bug report, obtaining device information, or requesting runtime + * permissions. + */ public class BaseSystem { private Context context; @@ -55,69 +57,16 @@ public class BaseSystem HabitsApplication.getComponent().inject(this); } - public String getLogcat() throws IOException - { - int maxNLines = 250; - StringBuilder builder = new StringBuilder(); - - String[] command = new String[]{"logcat", "-d"}; - Process process = Runtime.getRuntime().exec(command); - - InputStreamReader in = new InputStreamReader(process.getInputStream()); - BufferedReader bufferedReader = new BufferedReader(in); - - LinkedList log = new LinkedList<>(); - - String line; - while ((line = bufferedReader.readLine()) != null) - { - log.addLast(line); - if (log.size() > maxNLines) log.removeFirst(); - } - - for (String l : log) - { - builder.append(l); - builder.append('\n'); - } - - return builder.toString(); - } - - public String getDeviceInfo() - { - if (context == null) return ""; - - StringBuilder b = new StringBuilder(); - WindowManager wm = - (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); - - b.append( - String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME)); - b.append( - String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE)); - b.append(String.format("OS Version: %s (%s)\n", - java.lang.System.getProperty("os.version"), - android.os.Build.VERSION.INCREMENTAL)); - b.append( - String.format("OS API Level: %s\n", android.os.Build.VERSION.SDK)); - b.append(String.format("Device: %s\n", android.os.Build.DEVICE)); - b.append( - String.format("Model (Product): %s (%s)\n", android.os.Build.MODEL, - android.os.Build.PRODUCT)); - b.append( - String.format("Manufacturer: %s\n", android.os.Build.MANUFACTURER)); - b.append(String.format("Other tags: %s\n", android.os.Build.TAGS)); - b.append(String.format("Screen Width: %s\n", - wm.getDefaultDisplay().getWidth())); - b.append(String.format("Screen Height: %s\n", - wm.getDefaultDisplay().getHeight())); - b.append(String.format("SD Card state: %s\n\n", - Environment.getExternalStorageState())); - - return b.toString(); - } - + /** + * Captures a bug report and saves it to a file in the SD card. + *

+ * The contents of the file are generated by the method {@link + * #getBugReport()}. The file is saved in the apps's external private + * storage. + * + * @return the generated file. + * @throws IOException when I/O errors occur. + */ @NonNull public File dumpBugReportToFile() throws IOException { @@ -138,6 +87,14 @@ public class BaseSystem return logFile; } + /** + * Captures and returns a bug report. + *

+ * The bug report contains some device information and the logcat. + * + * @return a String containing the bug report. + * @throws IOException when any I/O error occur. + */ @NonNull public String getBugReport() throws IOException { @@ -146,6 +103,9 @@ public class BaseSystem return deviceInfo + "\n" + logcat; } + /** + * Recreates all application reminders. + */ public void scheduleReminders() { new BaseTask() @@ -159,6 +119,9 @@ public class BaseSystem }.execute(); } + /** + * Refreshes all application widgets. + */ public void updateWidgets() { new BaseTask() @@ -171,4 +134,59 @@ public class BaseSystem } }.execute(); } + + private String getDeviceInfo() + { + if (context == null) return "null context\n"; + + WindowManager wm = + (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); + + return + String.format("App Version Name: %s\n", BuildConfig.VERSION_NAME) + + String.format("App Version Code: %s\n", BuildConfig.VERSION_CODE) + + String.format("OS Version: %s (%s)\n", + System.getProperty("os.version"), Build.VERSION.INCREMENTAL) + + String.format("OS API Level: %s\n", Build.VERSION.SDK) + + String.format("Device: %s\n", Build.DEVICE) + + String.format("Model (Product): %s (%s)\n", Build.MODEL, + Build.PRODUCT) + + String.format("Manufacturer: %s\n", Build.MANUFACTURER) + + String.format("Other tags: %s\n", Build.TAGS) + + String.format("Screen Width: %s\n", + wm.getDefaultDisplay().getWidth()) + + String.format("Screen Height: %s\n", + wm.getDefaultDisplay().getHeight()) + + String.format("External storage state: %s\n\n", + Environment.getExternalStorageState()); + } + + private String getLogcat() throws IOException + { + int maxLineCount = 250; + StringBuilder builder = new StringBuilder(); + + String[] command = new String[]{"logcat", "-d"}; + Process process = Runtime.getRuntime().exec(command); + + InputStreamReader in = new InputStreamReader(process.getInputStream()); + BufferedReader bufferedReader = new BufferedReader(in); + + LinkedList log = new LinkedList<>(); + + String line; + while ((line = bufferedReader.readLine()) != null) + { + log.addLast(line); + if (log.size() > maxLineCount) log.removeFirst(); + } + + for (String l : log) + { + builder.append(l); + builder.append('\n'); + } + + return builder.toString(); + } } diff --git a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsSelectionMenu.java b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsSelectionMenu.java index f38c2d21c..27ae3c4ef 100644 --- a/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsSelectionMenu.java +++ b/app/src/main/java/org/isoron/uhabits/ui/habits/list/ListHabitsSelectionMenu.java @@ -59,10 +59,10 @@ public class ListHabitsSelectionMenu extends BaseSelectionMenu } @Override - public void onDestroy() + public void onFinish() { if (adapter != null) adapter.clearSelection(); - super.onDestroy(); + super.onFinish(); } @Override