[Android] [PATCH] Threaded SQLite search
Geoffrey Métais
geoffrey.metais at gmail.com
Wed Nov 26 14:27:29 CET 2014
---
.../src/org/videolan/vlc/MediaDatabase.java | 24 ++++++++++
vlc-android/src/org/videolan/vlc/MediaLibrary.java | 11 +++++
.../src/org/videolan/vlc/gui/SearchFragment.java | 55 +++++++++-------------
.../org/videolan/vlc/gui/tv/SearchFragment.java | 41 ++++++++--------
4 files changed, 76 insertions(+), 55 deletions(-)
diff --git a/vlc-android/src/org/videolan/vlc/MediaDatabase.java b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
index bb701e4..b0ca809 100644
--- a/vlc-android/src/org/videolan/vlc/MediaDatabase.java
+++ b/vlc-android/src/org/videolan/vlc/MediaDatabase.java
@@ -343,6 +343,30 @@ public class MediaDatabase {
return files;
}
+ public synchronized ArrayList<String> searchMedia(String filter, int type){
+
+ ArrayList<String> mediaList = new ArrayList<String>();
+
+ String[] queryColumns = new String[]{MEDIA_LOCATION, MEDIA_TITLE, MEDIA_ALBUM, MEDIA_ARTIST, MEDIA_TYPE};
+ String queryString = MEDIA_TITLE+" LIKE ? OR "+MEDIA_ALBUM+" LIKE ? OR "+MEDIA_ARTIST+" LIKE ?";
+ String [] queryArgs;
+ if (type != Media.TYPE_ALL) {
+ queryString = "( " + queryString + " ) AND " + MEDIA_TYPE + "=?";
+ queryArgs = new String[]{"%"+filter+"%", "%"+filter+"%", "%"+filter+"%", String.valueOf(type)};
+ } else
+ queryArgs = new String[]{"%"+filter+"%", "%"+filter+"%", "%"+filter+"%"};
+
+ Cursor cursor = mDb.query(MEDIA_TABLE_NAME,
+ queryColumns, queryString, queryArgs, null, null, null, null);
+ if (cursor.moveToFirst()){
+ do {
+ mediaList.add(cursor.getString(0));
+ }while (cursor.moveToNext());
+ cursor.close();
+ }
+ return mediaList;
+ }
+
public synchronized HashMap<String, Media> getMedias() {
Cursor cursor;
diff --git a/vlc-android/src/org/videolan/vlc/MediaLibrary.java b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
index 613239a..4a495bd 100644
--- a/vlc-android/src/org/videolan/vlc/MediaLibrary.java
+++ b/vlc-android/src/org/videolan/vlc/MediaLibrary.java
@@ -115,6 +115,17 @@ public class MediaLibrary {
mUpdateHandler.remove(handler);
}
+ public ArrayList<Media> searchMedia(String query, int type){
+ ArrayList<Media> mediaList = new ArrayList<Media>();
+ ArrayList<String> pathList = MediaDatabase.getInstance().searchMedia(query, type);
+ if (!pathList.isEmpty()){
+ for (String path : pathList) {
+ mediaList.add(getMediaItem(path));
+ }
+ }
+ return mediaList;
+ }
+
public ArrayList<Media> getVideoItems() {
ArrayList<Media> videoItems = new ArrayList<Media>();
mItemListLock.readLock().lock();
diff --git a/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java b/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
index 64a8d27..da8c950 100644
--- a/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
+++ b/vlc-android/src/org/videolan/vlc/gui/SearchFragment.java
@@ -21,7 +21,6 @@
package org.videolan.vlc.gui;
import java.util.ArrayList;
-import java.util.Locale;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaDatabase;
@@ -32,6 +31,7 @@ import org.videolan.vlc.gui.video.VideoPlayerActivity;
import android.content.Context;
import android.os.Bundle;
+import android.os.Handler;
import android.support.v4.app.ListFragment;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
@@ -56,6 +56,8 @@ public class SearchFragment extends ListFragment {
private SearchResultAdapter mResultAdapter;
private LinearLayout mListHeader;
+ final private Handler mHandler = new Handler();
+
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
((ActionBarActivity) getActivity()).getSupportActionBar().setTitle(R.string.search);
@@ -99,40 +101,27 @@ public class SearchFragment extends ListFragment {
imm.hideSoftInputFromWindow(getView().getWindowToken(), 0);
}
- private void search(CharSequence key, int type) {
-
- // set result adapter to the list
+ private void search(final String key, final int type) {
mResultAdapter.clear();
- String[] keys = key.toString().split("\\s+");
- ArrayList<Media> allItems = MediaLibrary.getInstance().getMediaItems();
- int results = 0;
- for (int i = 0; i < allItems.size(); i++) {
- Media item = allItems.get(i);
- if (type != Media.TYPE_ALL && type != item.getType())
- continue;
- boolean add = true;
- String name = item.getTitle().toLowerCase(Locale.getDefault());
- String MRL = item.getLocation().toLowerCase(Locale.getDefault());
- for (int k = 0; k < keys.length; k++) {
- String s = keys[k].toLowerCase(Locale.getDefault());
- if (!(name.contains(s) || MRL.contains(s))) {
- add = false;
- break;
- }
- }
-
- if (add) {
- mResultAdapter.add(item);
- results++;
+ new Thread(new Runnable() {
+ public void run() {
+ final ArrayList<Media> mediaList = MediaLibrary.getInstance().searchMedia(key, type);
+ mHandler.post(new Runnable() {
+ public void run() {
+ int count = mediaList.size();
+ for (int i = 0 ; i < count ; ++i)
+ mResultAdapter.add(mediaList.get(i));
+ mResultAdapter.sort();
+
+ String headerText = getResources().getQuantityString(R.plurals.search_found_results_quantity, mediaList.size(), mediaList.size());
+ showListHeader(headerText);
+
+ setListAdapter(mResultAdapter);
+ }
+ });
}
+ }).start();
- }
- mResultAdapter.sort();
-
- String headerText = getResources().getQuantityString(R.plurals.search_found_results_quantity, results, results);
- showListHeader(headerText);
-
- setListAdapter(mResultAdapter);
}
private void showListHeader(String text) {
@@ -169,7 +158,7 @@ public class SearchFragment extends ListFragment {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (s.length() > 0) {
- search(s, Media.TYPE_ALL);
+ search(s.toString(), Media.TYPE_ALL);
} else {
showSearchHistory();
}
diff --git a/vlc-android/tv/src/org/videolan/vlc/gui/tv/SearchFragment.java b/vlc-android/tv/src/org/videolan/vlc/gui/tv/SearchFragment.java
index 5ce0799..e0be766 100644
--- a/vlc-android/tv/src/org/videolan/vlc/gui/tv/SearchFragment.java
+++ b/vlc-android/tv/src/org/videolan/vlc/gui/tv/SearchFragment.java
@@ -20,20 +20,14 @@
package org.videolan.vlc.gui.tv;
import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
import org.videolan.libvlc.Media;
import org.videolan.vlc.MediaLibrary;
import org.videolan.vlc.R;
import android.app.Activity;
-import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
-import android.os.Parcelable;
import android.support.v17.leanback.widget.ArrayObjectAdapter;
import android.support.v17.leanback.widget.HeaderItem;
import android.support.v17.leanback.widget.ListRow;
@@ -47,7 +41,6 @@ public class SearchFragment extends android.support.v17.leanback.app.SearchFragm
implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
private static final String TAG = "SearchFragment";
- private static final int SEARCH_DELAY_MS = 300;
private ArrayObjectAdapter mRowsAdapter;
private Handler mHandler = new Handler();
@@ -72,10 +65,10 @@ implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider
private void queryByWords(String words) {
mRowsAdapter.clear();
- if (!TextUtils.isEmpty(words)) {
+ if (!TextUtils.isEmpty(words) && words.length() > 2) {
mDelayedLoad.setSearchQuery(words);
- mHandler.removeCallbacks(mDelayedLoad);
- mHandler.postDelayed(mDelayedLoad, SEARCH_DELAY_MS);
+ mDelayedLoad.setSearchType(Media.TYPE_ALL);
+ new Thread(mDelayedLoad).start();
}
}
@@ -91,18 +84,18 @@ implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider
return true;
}
- private void loadRows(String query) {
- ArrayList<Media> mediaList = MediaLibrary.getInstance().getMediaItems();
- ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
- for (Media media : mediaList) {
- if (media.getTitle().toLowerCase().indexOf(query.toLowerCase()) >= 0
- || media.getLocation().toLowerCase().indexOf(query.toLowerCase()) >= 0) {
- listRowAdapter.add(media);
+ private void loadRows(String query, int type) {
+ ArrayList<Media> mediaList = MediaLibrary.getInstance().searchMedia(query, type);
+ final ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
+ listRowAdapter.addAll(0, mediaList);
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ HeaderItem header = new HeaderItem(0, getResources().getString(R.string.search_results),
+ null);
+ mRowsAdapter.add(new ListRow(header, listRowAdapter));
}
- }
- HeaderItem header = new HeaderItem(0, getResources().getString(R.string.search_results),
- null);
- mRowsAdapter.add(new ListRow(header, listRowAdapter));
+ });
}
protected OnItemClickedListener getDefaultItemClickedListener() {
@@ -119,15 +112,19 @@ implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider
private class SearchRunnable implements Runnable {
private volatile String searchQuery;
+ private volatile int searchType;
public SearchRunnable() {}
public void run() {
- loadRows(searchQuery);
+ loadRows(searchQuery, searchType);
}
public void setSearchQuery(String value) {
this.searchQuery = value;
}
+ public void setSearchType(int value) {
+ this.searchType = value;
+ }
}
}
--
1.9.1
More information about the Android
mailing list