Rewrite wikivoyage search logic

This commit is contained in:
alex 2018-03-29 13:08:40 +03:00
parent 7966df89dd
commit 6b5ce98189
2 changed files with 75 additions and 70 deletions

View file

@ -16,6 +16,7 @@ import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ProgressBar;
import net.osmand.ResultMatcher;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.R;
import net.osmand.plus.base.BaseOsmAndDialogFragment;
@ -32,6 +33,9 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
private WikivoyageSearchHelper searchHelper;
private String searchQuery = "";
private boolean paused;
private boolean cancelPrev;
private SearchRecyclerViewAdapter adapter;
private EditText searchEt;
@ -78,11 +82,10 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
if (!searchQuery.equalsIgnoreCase(newQuery)) {
searchQuery = newQuery;
if (searchQuery.isEmpty()) {
searchHelper.cancelSearch();
switchProgressBarVisibility(false);
cancelSearch();
adapter.setItems(null);
} else {
searchHelper.search(searchQuery);
runSearch();
}
}
}
@ -119,19 +122,16 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
@Override
public void onResume() {
super.onResume();
if (searchHelper != null) {
paused = false;
searchHelper.registerListener(this);
}
searchEt.requestFocus();
}
@Override
public void onPause() {
super.onPause();
if (searchHelper != null) {
paused = true;
searchHelper.unregisterListener(this);
searchHelper.cancelSearch();
}
}
@Override
@ -145,6 +145,29 @@ public class WikivoyageSearchDialogFragment extends BaseOsmAndDialogFragment imp
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) {
progressBar.setVisibility(show ? View.VISIBLE : View.GONE);
clearIb.setVisibility(show ? View.GONE : View.VISIBLE);

View file

@ -1,27 +1,23 @@
package net.osmand.plus.wikivoyage.search;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import net.osmand.ResultMatcher;
import net.osmand.plus.OsmandApplication;
import net.osmand.plus.wikivoyage.data.WikivoyageSearchResult;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class WikivoyageSearchHelper {
private static final int TIMEOUT_BETWEEN_CHARS = 700;
private static final int SLEEP_TIME = 50;
private LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
private ThreadPoolExecutor singleThreadExecutor =
new ThreadPoolExecutor(1, 1, 0, TimeUnit.MILLISECONDS, workQueue);
private AsyncTask<Void, Void, List<WikivoyageSearchResult>> currentTask;
private ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
private OsmandApplication application;
private Set<SearchListener> listeners = new HashSet<>();
@ -38,17 +34,45 @@ public class WikivoyageSearchHelper {
listeners.remove(listener);
}
public void cancelSearch() {
workQueue.clear();
if (currentTask != null) {
currentTask.cancel(true);
public void search(final String query, final ResultMatcher<WikivoyageSearchResult> rm) {
singleThreadExecutor.submit(new Runnable() {
@Override
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) {
cancelSearch();
currentTask = new SearchAsyncTask(query);
currentTask.executeOnExecutor(singleThreadExecutor);
final List<WikivoyageSearchResult> results = application.getWikivoyageDbHelper().search(query);
application.runInUIThread(new Runnable() {
@Override
public void run() {
for (SearchListener listener : listeners) {
listener.onSearchFinished(results);
}
}
});
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
public interface SearchListener {
@ -57,46 +81,4 @@ public class WikivoyageSearchHelper {
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);
}
}
}
}