1

I have a textWatcher for my editText. The idea is:

I have two list views and they are both updated after every inserted in editText field character. Somehow I could't implement this using standart ArrayAdapter with filter method. So I had to make my own realization of search. At the beggining it seemed good, but as soon as I added to my data base more less enough data the interface started to freeze.

This is the call

inputSearch.addTextChangedListener(createAndReturnTextWatcher());

And this is the method that creates and returns textWatcher

private TextWatcher createAndReturnTextWatcher() {
    final List<String> list = dbExtractor.getDataForSearchAdapters();
    TextWatcher watcher1;

    watcher1 = new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {

            if (cs.length() == 0) {

                lv.setAdapter(null);
                lv2.setAdapter(null);

                dc.clickedOnce = true;
                dc.decrement();
                dc.checkDimCounter();
            } else {


                setSecondListData(list, String.valueOf(cs));
                setFirstListData(list, String.valueOf(cs));

                if (dc.clickedOnce) {
                    dc.increment();
                    dc.checkDimCounter();
                    dc.clickedOnce = false;
                }

            }

        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                                      int arg3) {
        }

        @Override
        public void afterTextChanged(Editable arg0) {

        }
    };

    return watcher1;
}

And this are methods that perform filtering

private void setSecondListData(List<String> inputData, String cs) {
    List<String> result = turkishSearcher.performFiltering(inputData, cs);
    ArrayAdapter turkAdapt = new ArrayAdapter(this, R.layout.dictionary_list_item, R.id.product_name,
            result);
    lv2.setAdapter(turkAdapt);
}

private void setFirstListData(List<String> inputData, String cs) {
    List<String> result = normSearcher.performFiltering(inputData, cs);
    ArrayAdapter turkAdapt = new ArrayAdapter(this, R.layout.dictionary_list_item, R.id.product_name,
            result);
    lv.setAdapter(turkAdapt);
}

And this is the class that filters data

public class TurkishSearcher extends Searcher{

@Override
int returnPosition() {
    return 1;
}

@Override
String reverse(String couples) {
    java.lang.String[] arr = couples.split(" — ");
    return arr[1]+ " — " + arr[0];
}

@Override
String replaceTurkish(String words) {

    if (checkWithRegExp(words)) {
        return words.toLowerCase().replaceAll("ç", "c").replaceAll("ğ", "g").replaceAll("ı", "i").
                replaceAll("ö", "o").replaceAll("ş", "s").replaceAll("ü", "u");
    } else return words;
}

public static boolean checkWithRegExp(String word){
    Pattern p = Pattern.compile("[öçğışü]", Pattern.CASE_INSENSITIVE);
    Matcher m = p.matcher(word);
    return m.find();
}

}

I clearly understand that the way I keep data is wrong and the search algorhytm isn't good as well. But my question is:

Is it possible to avoid freezes using Threads for search implementations. Can i puth both searchers to their own threads to somehow avoid interface freezes? If it's possible, pls tell me the best place in code where I can use threads.

Thank you in advance!

Dmitry Smolyaninov
  • 2,159
  • 1
  • 18
  • 32

2 Answers2

2

Best way to do long tasks in background thread. You can use asynctask to do this.

Learn Pain Less
  • 2,274
  • 1
  • 17
  • 24
2

You should never block the main thread by database operations. Instead use:

     new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(Void... unusedParams) {
            // TODO: do your database stuff
            return null;
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            // TODO: refresh UI elements, because thread finished
            super.onPostExecute(aVoid);
        }
    }.execute();
lidox
  • 1,901
  • 3
  • 21
  • 40
  • Oh, thanks. This kind of confirmation s exact thing I wanted to read :) Database uploads just once in the Activity beggining (still not with Async Task). And then I work just with List of Strings. Is AsyncTask ok for this case too? – Dmitry Smolyaninov Sep 13 '16 at 15:11
  • 1
    I wouldn't let upload the database at the beginning in the mainthread too. This is just a strict mode policy, described here: https://developer.android.com/reference/android/os/StrictMode.html – lidox Sep 13 '16 at 15:13
  • Ye, I knew it before. So will remove all database stuff to async task as well. Thank you so much for help :3 Ye, and one more question. So Asynctask is good for calculations I described? Like for search implementation? – Dmitry Smolyaninov Sep 13 '16 at 15:17