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.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) {
|
||||
searchHelper.registerListener(this);
|
||||
}
|
||||
paused = false;
|
||||
searchHelper.registerListener(this);
|
||||
searchEt.requestFocus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
if (searchHelper != null) {
|
||||
searchHelper.unregisterListener(this);
|
||||
searchHelper.cancelSearch();
|
||||
}
|
||||
paused = true;
|
||||
searchHelper.unregisterListener(this);
|
||||
}
|
||||
|
||||
@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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
public void search(String query) {
|
||||
cancelSearch();
|
||||
currentTask = new SearchAsyncTask(query);
|
||||
currentTask.executeOnExecutor(singleThreadExecutor);
|
||||
rm.publish(null);
|
||||
|
||||
long startTime = System.currentTimeMillis();
|
||||
while (System.currentTimeMillis() - startTime <= TIMEOUT_BETWEEN_CHARS) {
|
||||
if (rm.isCancelled()) {
|
||||
return;
|
||||
}
|
||||
Thread.sleep(SLEEP_TIME);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue