Rewrite wikivoyage search logic
This commit is contained in:
parent
7966df89dd
commit
6b5ce98189
2 changed files with 75 additions and 70 deletions
|
@ -16,6 +16,7 @@ import android.widget.EditText;
|
||||||
import android.widget.ImageButton;
|
import android.widget.ImageButton;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
|
|
||||||
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.R;
|
import net.osmand.plus.R;
|
||||||
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
import net.osmand.plus.base.BaseOsmAndDialogFragment;
|
||||||
|
@ -32,6 +33,9 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
|
||||||
private WikivoyageSearchHelper searchHelper;
|
private WikivoyageSearchHelper searchHelper;
|
||||||
private String searchQuery = "";
|
private String searchQuery = "";
|
||||||
|
|
||||||
|
private boolean paused;
|
||||||
|
private boolean cancelPrev;
|
||||||
|
|
||||||
private SearchRecyclerViewAdapter adapter;
|
private SearchRecyclerViewAdapter adapter;
|
||||||
|
|
||||||
private EditText searchEt;
|
private EditText searchEt;
|
||||||
|
@ -78,11 +82,10 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
|
||||||
if (!searchQuery.equalsIgnoreCase(newQuery)) {
|
if (!searchQuery.equalsIgnoreCase(newQuery)) {
|
||||||
searchQuery = newQuery;
|
searchQuery = newQuery;
|
||||||
if (searchQuery.isEmpty()) {
|
if (searchQuery.isEmpty()) {
|
||||||
searchHelper.cancelSearch();
|
cancelSearch();
|
||||||
switchProgressBarVisibility(false);
|
|
||||||
adapter.setItems(null);
|
adapter.setItems(null);
|
||||||
} else {
|
} else {
|
||||||
searchHelper.search(searchQuery);
|
runSearch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,19 +122,16 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
if (searchHelper != null) {
|
paused = false;
|
||||||
searchHelper.registerListener(this);
|
searchHelper.registerListener(this);
|
||||||
}
|
|
||||||
searchEt.requestFocus();
|
searchEt.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
if (searchHelper != null) {
|
paused = true;
|
||||||
searchHelper.unregisterListener(this);
|
searchHelper.unregisterListener(this);
|
||||||
searchHelper.cancelSearch();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -145,6 +145,29 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
|
||||||
switchProgressBarVisibility(false);
|
switchProgressBarVisibility(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void cancelSearch() {
|
||||||
|
cancelPrev = true;
|
||||||
|
if (!paused) {
|
||||||
|
switchProgressBarVisibility(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runSearch() {
|
||||||
|
cancelPrev = true;
|
||||||
|
searchHelper.search(searchQuery, new ResultMatcher<WikivoyageSearchResult>() {
|
||||||
|
@Override
|
||||||
|
public boolean publish(WikivoyageSearchResult object) {
|
||||||
|
cancelPrev = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return paused || cancelPrev;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private void switchProgressBarVisibility(boolean show) {
|
private void switchProgressBarVisibility(boolean show) {
|
||||||
progressBar.setVisibility(show ? View.VISIBLE : View.GONE);
|
progressBar.setVisibility(show ? View.VISIBLE : View.GONE);
|
||||||
clearIb.setVisibility(show ? View.GONE : View.VISIBLE);
|
clearIb.setVisibility(show ? View.GONE : View.VISIBLE);
|
||||||
|
|
|
@ -1,27 +1,23 @@
|
||||||
package net.osmand.plus.wikivoyage.search;
|
package net.osmand.plus.wikivoyage.search;
|
||||||
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.osmand.ResultMatcher;
|
||||||
import net.osmand.plus.OsmandApplication;
|
import net.osmand.plus.OsmandApplication;
|
||||||
import net.osmand.plus.wikivoyage.data.WikivoyageSearchResult;
|
import net.osmand.plus.wikivoyage.data.WikivoyageSearchResult;
|
||||||
|
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.ThreadPoolExecutor;
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
public class WikivoyageSearchHelper {
|
public class WikivoyageSearchHelper {
|
||||||
|
|
||||||
private static final int TIMEOUT_BETWEEN_CHARS = 700;
|
private static final int TIMEOUT_BETWEEN_CHARS = 700;
|
||||||
private static final int SLEEP_TIME = 50;
|
private static final int SLEEP_TIME = 50;
|
||||||
|
|
||||||
private LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
|
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
|
||||||
private ThreadPoolExecutor singleThreadExecutor =
|
|
||||||
new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, workQueue);
|
|
||||||
private AsyncTask<Void, Void, List<WikivoyageSearchResult>> currentTask;
|
|
||||||
|
|
||||||
private OsmandApplication application;
|
private OsmandApplication application;
|
||||||
private Set<SearchListener> listeners = new HashSet<>();
|
private Set<SearchListener> listeners = new HashSet<>();
|
||||||
|
@ -38,17 +34,45 @@ public class WikivoyageSearchHelper {
|
||||||
listeners.remove(listener);
|
listeners.remove(listener);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelSearch() {
|
public void search(final String query, final ResultMatcher<WikivoyageSearchResult> rm) {
|
||||||
workQueue.clear();
|
singleThreadExecutor.submit(new Runnable() {
|
||||||
if (currentTask != null) {
|
@Override
|
||||||
currentTask.cancel(true);
|
public void run() {
|
||||||
|
try {
|
||||||
|
application.runInUIThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (SearchListener listener : listeners) {
|
||||||
|
listener.onSearchStarted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
rm.publish(null);
|
||||||
|
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (System.currentTimeMillis() - startTime <= TIMEOUT_BETWEEN_CHARS) {
|
||||||
|
if (rm.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Thread.sleep(SLEEP_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
public void search(String query) {
|
final List<WikivoyageSearchResult> results = application.getWikivoyageDbHelper().search(query);
|
||||||
cancelSearch();
|
|
||||||
currentTask = new SearchAsyncTask(query);
|
application.runInUIThread(new Runnable() {
|
||||||
currentTask.executeOnExecutor(singleThreadExecutor);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
for (SearchListener listener : listeners) {
|
||||||
|
listener.onSearchFinished(results);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface SearchListener {
|
public interface SearchListener {
|
||||||
|
@ -57,46 +81,4 @@ public class WikivoyageSearchHelper {
|
||||||
|
|
||||||
void onSearchFinished(@Nullable List<WikivoyageSearchResult> results);
|
void onSearchFinished(@Nullable List<WikivoyageSearchResult> results);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SearchAsyncTask extends AsyncTask<Void, Void, List<WikivoyageSearchResult>> {
|
|
||||||
|
|
||||||
private String query;
|
|
||||||
|
|
||||||
SearchAsyncTask(String query) {
|
|
||||||
this.query = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPreExecute() {
|
|
||||||
super.onPreExecute();
|
|
||||||
for (SearchListener listener : listeners) {
|
|
||||||
listener.onSearchStarted();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected List<WikivoyageSearchResult> doInBackground(Void... voids) {
|
|
||||||
long startTime = System.currentTimeMillis();
|
|
||||||
while (System.currentTimeMillis() - startTime <= TIMEOUT_BETWEEN_CHARS) {
|
|
||||||
if (isCancelled()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(SLEEP_TIME);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return application.getWikivoyageDbHelper().search(query);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(List<WikivoyageSearchResult> results) {
|
|
||||||
super.onPostExecute(results);
|
|
||||||
for (SearchListener listener : listeners) {
|
|
||||||
listener.onSearchFinished(results);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue