refactor / three state importTask

This commit is contained in:
veliymolfar 2020-03-11 13:29:28 +02:00
parent e5d399b12f
commit adb9464de5
4 changed files with 192 additions and 222 deletions

View file

@ -104,9 +104,6 @@ public class SettingsHelper {
private boolean checkingDuplicates;
private ImportAsyncTask importTask;
private Map<File, ExportAsyncTask> exportAsyncTasks = new HashMap<>();
private CheckDuplicatesTask checkDuplicatesTask;
private List<SettingsItem> importedItems;
private List<SettingsItem> selectedItems;
public interface SettingsImportListener {
void onSettingsImportFinished(boolean succeed, boolean empty, @NonNull List<SettingsItem> items);
@ -1828,36 +1825,52 @@ public class SettingsHelper {
private String latestChanges;
private int version;
private SettingsImportListener listener;
private SettingsImportListener importListener;
private CheckDuplicatesListener duplicatesListener;
private SettingsImporter importer;
private List<SettingsItem> items = new ArrayList<>();
private List<SettingsItem> selectedItems = new ArrayList<>();
private List<SettingsItem> processedItems = new ArrayList<>();
private SettingsItem currentItem;
private AlertDialog dialog;
private State state;
private List<Object> duplicates;
ImportAsyncTask(@NonNull File settingsFile, String latestChanges, int version, @Nullable SettingsImportListener listener) {
this.file = settingsFile;
this.listener = listener;
ImportAsyncTask(@NonNull File file, String latestChanges, int version, @Nullable SettingsImportListener importListener) {
this.file = file;
this.importListener = importListener;
this.latestChanges = latestChanges;
this.version = version;
importer = new SettingsImporter(app);
collectOnly = true;
state = State.COLLECT;
}
ImportAsyncTask(@NonNull File settingsFile, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener listener) {
this.file = settingsFile;
this.listener = listener;
ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, String latestChanges, int version, @Nullable SettingsImportListener importListener) {
this.file = file;
this.importListener = importListener;
this.items = items;
this.latestChanges = latestChanges;
this.version = version;
importer = new SettingsImporter(app);
collectOnly = false;
state = State.IMPORT;
}
ImportAsyncTask(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, @Nullable CheckDuplicatesListener duplicatesListener) {
this.file = file;
this.items = items;
this.duplicatesListener = duplicatesListener;
this.selectedItems = selectedItems;
importer = new SettingsImporter(app);
collectOnly = true;
state = State.CHECK_DUPLICATES;
}
@Override
protected void onPreExecute() {
if (importing) {
finishImport(listener, false, false, items);
finishImport(importListener, false, false, items);
}
importing = true;
importSuspended = false;
@ -1866,7 +1879,8 @@ public class SettingsHelper {
@Override
protected List<SettingsItem> doInBackground(Void... voids) {
if (collectOnly) {
switch (state) {
case COLLECT:
try {
return importer.collectItems(file);
} catch (IllegalArgumentException e) {
@ -1874,7 +1888,22 @@ public class SettingsHelper {
} catch (IOException e) {
LOG.error("Failed to collect items from: " + file.getName(), e);
}
} else {
break;
case CHECK_DUPLICATES:
checkingDuplicates = true;
long startTime = System.currentTimeMillis();
List<Object> duplicatesData = getDuplicatesData(this.selectedItems);
long diffTime = System.currentTimeMillis() - startTime;
if (diffTime < 500 && diffTime >= 0) {
try {
Thread.sleep(500 - diffTime);
} catch (InterruptedException e) {
LOG.error("Error on check duplicates delay" + e);
}
}
this.duplicates = duplicatesData;
return selectedItems;
case IMPORT:
return this.items;
}
return null;
@ -1882,14 +1911,27 @@ public class SettingsHelper {
@Override
protected void onPostExecute(@Nullable List<SettingsItem> items) {
if (items != null) {
if (items != null && !State.CHECK_DUPLICATES.equals(state)) {
this.items = items;
} else {
selectedItems = items;
}
if (collectOnly) {
listener.onSettingsImportFinished(true, false, this.items);
} else if (items != null && items.size() > 0) {
switch (state) {
case COLLECT:
importListener.onSettingsImportFinished(true, false, this.items);
break;
case CHECK_DUPLICATES:
checkingDuplicates = false;
if (duplicatesListener != null) {
duplicatesListener.onDuplicatesChecked(duplicates, this.selectedItems);
}
break;
case IMPORT:
if (items != null && items.size() > 0) {
processNextItem();
}
break;
}
}
private void processNextItem() {
@ -1898,9 +1940,9 @@ public class SettingsHelper {
}
if (items.size() == 0 && !importSuspended) {
if (processedItems.size() > 0) {
new ImportItemsAsyncTask(file, listener, processedItems).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
new ImportItemsAsyncTask(file, importListener, processedItems).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
} else {
finishImport(listener, false, true, items);
finishImport(importListener, false, true, items);
}
return;
}
@ -1942,38 +1984,46 @@ public class SettingsHelper {
return this.file;
}
public void setListener(SettingsImportListener listener) {
this.listener = listener;
}
public void setImportListener(SettingsImportListener importListener) {
this.importListener = importListener;
}
@Nullable
public List<SettingsItem> getSettingsItems() {
return importTask != null ? importTask.getItems() : null;
public void setDuplicatesListener(CheckDuplicatesListener duplicatesListener) {
this.duplicatesListener = duplicatesListener;
}
@Nullable
public File getSettingsFile() {
return importTask != null ? importTask.getFile() : null;
public State getState() {
return this.state;
}
@Nullable
public List<SettingsItem> getImportedItems() {
return importedItems;
public List<Object> getDuplicates() {
return this.duplicates;
}
@Nullable
public List<Object> getDuplicatesItems() {
return checkDuplicatesTask != null ? checkDuplicatesTask.getDuplicates() : null;
public List<SettingsItem> getSelectedItems() {
return this.selectedItems;
}
public void setImportedItems(@Nullable List<SettingsItem> importedItems) {
this.importedItems = importedItems;
private List<Object> getDuplicatesData(List<SettingsItem> items) {
List<Object> duplicateItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof SettingsHelper.ProfileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
}
} else if (item instanceof SettingsHelper.CollectionSettingsItem) {
List duplicates = ((CollectionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.FileSettingsItem) item).getFile());
}
}
}
return duplicateItems;
}
@Nullable
public CheckDuplicatesTask getCheckDuplicatesTask() {
return checkDuplicatesTask;
}
@Nullable
@ -1982,12 +2032,8 @@ public class SettingsHelper {
}
@Nullable
public List<SettingsItem> getSelectedItems() {
return selectedItems;
}
public void setSelectedItems(@Nullable List<SettingsItem> selectedItems) {
this.selectedItems = selectedItems;
public State getImportTaskState() {
return importTask != null ? importTask.getState() : null;
}
public boolean isFileExporting(File file) {
@ -2041,11 +2087,9 @@ public class SettingsHelper {
importing = false;
importSuspended = false;
importTask = null;
checkDuplicatesTask = null;
if (listener != null) {
listener.onSettingsImportFinished(success, empty, items);
}
importedItems = items;
}
@SuppressLint("StaticFieldLeak")
@ -2088,82 +2132,8 @@ public class SettingsHelper {
}
}
@SuppressLint("StaticFieldLeak")
public class CheckDuplicatesTask extends AsyncTask<Void, Void, List<Object>> {
private List<SettingsItem> items;
private List<Object> duplicates;
private CheckDuplicatesListener listener;
private long startTime;
CheckDuplicatesTask(@NonNull List<SettingsItem> items, CheckDuplicatesListener listener) {
this.items = items;
this.listener = listener;
}
@Override
protected void onPreExecute() {
selectedItems = this.items;
checkingDuplicates = true;
checkDuplicatesTask = this;
startTime = System.currentTimeMillis();
}
@Override
protected List<Object> doInBackground(Void... voids) {
long currentTime = System.currentTimeMillis();
List<Object> duplicateItems = getDuplicatesData(this.items);
if (currentTime - startTime < 700) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
LOG.error("Error on check duplicates delay" + e);
}
}
return duplicateItems;
}
@Override
protected void onPostExecute(List<Object> objects) {
duplicates = objects;
if (listener != null) {
listener.onDuplicatesChecked(objects, this.items);
}
checkingDuplicates = false;
}
private List<Object> getDuplicatesData(List<SettingsItem> items) {
List<Object> duplicateItems = new ArrayList<>();
for (SettingsItem item : items) {
if (item instanceof SettingsHelper.ProfileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.ProfileSettingsItem) item).getModeBean());
}
} else if (item instanceof SettingsHelper.CollectionSettingsItem) {
List duplicates = ((CollectionSettingsItem) item).excludeDuplicateItems();
if (!duplicates.isEmpty()) {
duplicateItems.addAll(duplicates);
}
} else if (item instanceof SettingsHelper.FileSettingsItem) {
if (item.exists()) {
duplicateItems.add(((SettingsHelper.FileSettingsItem) item).getFile());
}
}
}
return duplicateItems;
}
public void setListener(CheckDuplicatesListener listener) {
this.listener = listener;
}
List<Object> getDuplicates() {
return duplicates;
}
}
public void checkDuplicates(@NonNull List<SettingsItem> items, CheckDuplicatesListener listener) {
new CheckDuplicatesTask(items, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
public void checkDuplicates(@NonNull File file, @NonNull List<SettingsItem> items, @NonNull List<SettingsItem> selectedItems, CheckDuplicatesListener listener) {
new ImportAsyncTask(file, items, selectedItems, listener).executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
public void importSettings(@NonNull File settingsFile, String latestChanges, int version,
@ -2186,4 +2156,10 @@ public class SettingsHelper {
@NonNull SettingsItem... items) {
exportSettings(fileDir, fileName, listener, new ArrayList<>(Arrays.asList(items)));
}
public enum State {
COLLECT,
CHECK_DUPLICATES,
IMPORT
}
}

View file

@ -19,7 +19,6 @@ import androidx.recyclerview.widget.RecyclerView;
import net.osmand.AndroidUtils;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.activities.MapActivity;
@ -39,19 +38,18 @@ import static net.osmand.plus.settings.ImportSettingsFragment.getSettingsToOpera
public class ImportCompleteFragment extends BaseOsmAndFragment {
public static final String TAG = ImportCompleteFragment.class.getSimpleName();
private static final String FILE_NAME_KEY = "FILE_NAME_KEY";
private OsmandApplication app;
private RecyclerView recyclerView;
private List<SettingsItem> settingsItems;
private String fileName;
private boolean nightMode;
private SettingsHelper settingsHelper;
public static void showInstance(FragmentManager fm, @NonNull List<SettingsItem> settingsItems,
@NonNull String fileName) {
ImportCompleteFragment fragment = new ImportCompleteFragment();
fragment.setSettingsItems(settingsItems);
fragment.setFileName(fileName);
fragment.setRetainInstance(true);
fm.beginTransaction()
.replace(R.id.fragmentContainer, fragment, TAG)
.addToBackStack(IMPORT_SETTINGS_TAG)
@ -61,18 +59,8 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
fileName = savedInstanceState.getString(FILE_NAME_KEY);
}
app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent();
if (settingsItems == null) {
settingsItems = settingsHelper.getImportedItems();
if (settingsItems == null) {
dismissFragment();
}
}
}
@Nullable
@ -120,19 +108,11 @@ public class ImportCompleteFragment extends BaseOsmAndFragment {
}
}
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(FILE_NAME_KEY, fileName);
}
public void dismissFragment() {
FragmentManager fm = getFragmentManager();
if (fm != null) {
fm.popBackStack(IMPORT_SETTINGS_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE);
}
settingsHelper.setImportedItems(null);
settingsHelper.setSelectedItems(null);
}
private void navigateTo(AdditionalDataWrapper.Type type) {

View file

@ -79,24 +79,18 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent();
SettingsHelper.ImportAsyncTask importTask = settingsHelper.getImportTask();
if (importTask != null) {
if (settingsItems == null) {
settingsItems = settingsHelper.getSelectedItems();
settingsItems = importTask.getSelectedItems();
}
if (duplicatesList == null) {
duplicatesList = settingsHelper.getDuplicatesItems();
duplicatesList = importTask.getDuplicates();
}
if (file == null) {
file = settingsHelper.getSettingsFile();
}
SettingsHelper.ImportAsyncTask importAsyncTask = settingsHelper.getImportTask();
List<SettingsItem> importedItems = settingsHelper.getImportedItems();
if (importAsyncTask != null) {
importAsyncTask.setListener(getImportListener());
} else if (importedItems != null) {
FragmentManager fm = getFragmentManager();
if (fm != null) {
ImportCompleteFragment.showInstance(fm, importedItems, file.getName());
file = importTask.getFile();
}
importTask.setImportListener(getImportListener());
}
}
@ -150,20 +144,21 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
return root;
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (duplicatesList != null) {
DuplicatesSettingsAdapter adapter = new DuplicatesSettingsAdapter(app, prepareDuplicates(duplicatesList), nightMode);
list.setLayoutManager(new LinearLayoutManager(getMyApplication()));
list.setAdapter(adapter);
}
if (settingsHelper.isImporting() && !settingsHelper.isCollectOnly()) {
SettingsHelper.State state = settingsHelper.getImportTaskState();
if (settingsHelper.isImporting() && !settingsHelper.isCollectOnly() && state != null && state.equals(SettingsHelper.State.IMPORT)) {
setupImportingUi();
} else {
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
toolbarLayout.setTitle(getString(R.string.import_duplicates_title));
}
private List<Object> prepareDuplicates(List<? super Object> duplicatesList) {
@ -287,7 +282,7 @@ public class ImportDuplicatesFragment extends BaseOsmAndFragment implements View
}
});
FragmentManager fm = getFragmentManager();
if (fm != null) {
if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName());
}
} else if (empty) {

View file

@ -1,7 +1,9 @@
package net.osmand.plus.settings;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.Configuration;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Bundle;
@ -25,6 +27,7 @@ import com.google.android.material.appbar.CollapsingToolbarLayout;
import net.osmand.AndroidUtils;
import net.osmand.IndexConstants;
import net.osmand.PlatformUtil;
import net.osmand.map.ITileSource;
import net.osmand.map.TileSourceManager;
import net.osmand.plus.AppInitializer;
@ -33,6 +36,7 @@ import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.SQLiteTileSource;
import net.osmand.plus.SettingsHelper;
import net.osmand.plus.SettingsHelper.ImportAsyncTask;
import net.osmand.plus.SettingsHelper.SettingsItem;
import net.osmand.plus.UiUtilities;
import net.osmand.plus.base.BaseOsmAndFragment;
@ -43,6 +47,8 @@ import net.osmand.plus.quickaction.QuickAction;
import net.osmand.plus.widgets.TextViewEx;
import org.apache.commons.logging.Log;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
@ -51,7 +57,8 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
implements View.OnClickListener {
public static final String TAG = ImportSettingsFragment.class.getSimpleName();
public static final String IMPORT_SETTINGS_TAG = "import_settings_tag";
public static final Log LOG = PlatformUtil.getLog(ImportSettingsFragment.class.getSimpleName());
static final String IMPORT_SETTINGS_TAG = "import_settings_tag";
private OsmandApplication app;
private ExportImportSettingsAdapter adapter;
private ExpandableListView expandableList;
@ -77,33 +84,11 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}
@Override
public void onCreate(Bundle savedInstanceState) {
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = requireMyApplication();
settingsHelper = app.getSettingsHelper();
nightMode = !app.getSettings().isLightContent();
if (settingsItems == null) {
settingsItems = app.getSettingsHelper().getSettingsItems();
}
if (file == null) {
file = app.getSettingsHelper().getSettingsFile();
}
List<Object> duplicates = settingsHelper.getDuplicatesItems();
if (duplicates == null) {
SettingsHelper.CheckDuplicatesTask checkDuplicatesTask = settingsHelper.getCheckDuplicatesTask();
if (checkDuplicatesTask != null) {
settingsHelper.getCheckDuplicatesTask().setListener(getDuplicatesListener());
}
} else {
FragmentManager fm = getFragmentManager();
if (duplicates.isEmpty()) {
app.getSettingsHelper().importSettings(file, settingsItems, "", 1, getImportListener());
} else {
if (fm != null) {
ImportDuplicatesFragment.showInstance(fm, duplicates, settingsItems, file);
}
}
}
}
@Nullable
@ -133,17 +118,44 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ImportAsyncTask importAsyncTask = settingsHelper.getImportTask();
if (importAsyncTask != null) {
if (settingsItems == null) {
settingsItems = importAsyncTask.getItems();
}
if (file == null) {
file = importAsyncTask.getFile();
}
List<Object> duplicates = importAsyncTask.getDuplicates();
List<SettingsItem> selectedItems = importAsyncTask.getSelectedItems();
if (duplicates == null) {
importAsyncTask.setDuplicatesListener(getDuplicatesListener());
} else if (duplicates.isEmpty()) {
if (selectedItems != null && file != null) {
settingsHelper.importSettings(file, selectedItems, "", 1, getImportListener());
}
}
// else if (!fromPopBackStack) {
// FragmentManager fm = getFragmentManager();
// if (fm != null && file != null && selectedItems != null) {
// ImportDuplicatesFragment.showInstance(fm, duplicates, selectedItems, file);
// }
// }
}
adapter = new ExportImportSettingsAdapter(app, nightMode, true);
if (settingsItems != null) {
adapter.updateSettingsList(getSettingsToOperate(settingsItems));
}
expandableList.setAdapter(adapter);
toolbarLayout.setTitle(getString(R.string.shared_string_import));
SettingsHelper.State state = settingsHelper.getImportTaskState();
if (settingsHelper.isCheckingDuplicates()) {
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
} else if (settingsHelper.isImporting() && !settingsHelper.isCollectOnly()) {
} else if (settingsHelper.isImporting() && !settingsHelper.isCollectOnly() && state != null && state.equals(SettingsHelper.State.IMPORT)) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
} else {
toolbarLayout.setTitle(getString(R.string.shared_string_import));
@ -171,21 +183,26 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
}
private void updateUi(int toolbarTitleRes, int descriptionRes) {
if (file != null) {
String fileName = file.getName();
toolbarLayout.setTitle(getString(toolbarTitleRes));
description.setText(UiUtilities.createSpannableString(
String.format(getString(descriptionRes), file.getName()),
file.getName(),
String.format(getString(descriptionRes), fileName),
fileName,
new StyleSpan(Typeface.BOLD)
));
buttonsContainer.setVisibility(View.GONE);
progressBar.setVisibility(View.VISIBLE);
adapter.clearSettingsList();
}
}
private void importItems() {
updateUi(R.string.shared_string_preparing, R.string.checking_for_duplicate_description);
List<SettingsItem> settingsItems = getSettingsItemsFromData(adapter.getDataToOperate());
settingsHelper.checkDuplicates(settingsItems, getDuplicatesListener());
List<SettingsItem> selectedItems = getSettingsItemsFromData(adapter.getDataToOperate());
if (file != null && settingsItems != null) {
settingsHelper.checkDuplicates(file, settingsItems, selectedItems, getDuplicatesListener());
}
}
private SettingsHelper.SettingsImportListener getImportListener() {
@ -200,7 +217,7 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
public void onRoutingFilesLoaded() {
}
});
if (fm != null) {
if (fm != null && file != null) {
ImportCompleteFragment.showInstance(fm, items, file.getName());
}
} else if (empty) {
@ -220,9 +237,11 @@ public class ImportSettingsFragment extends BaseOsmAndFragment
if (isAdded()) {
updateUi(R.string.shared_string_importing, R.string.importing_from);
}
if (file != null) {
settingsHelper.importSettings(file, items, "", 1, getImportListener());
}
} else {
if (fm != null) {
if (fm != null && file != null) {
if (!isStateSaved()) {
ImportDuplicatesFragment.showInstance(fm, duplicates, items, file);
}