title: Create a fast file search function in android
body: <p>I'm new to android and I'm trying to develop file explorer which includes search function. I'm using a recursive search function that works fine in folders with a few subfolders and files, but for some reason it's EXTREMELY SLOW and could "Force Close" in folders with lots of subfolders and files, because there's not enough memory. I do the search by creating ArrayList where the results will be placed, and then calling the recursive function that will fill the list. The "path" argument is the file where the search will start from, and "query" is the search query.</p>
  
  <pre><code>ArrayList&lt;File&gt; result = new ArrayList&lt;File&gt;();
  fileSearch(path, query, result);
  </code></pre>
  
  <p>this is what the recursive function looks like:</p>
  
  <pre><code>private void fileSearch(File dir, String query, ArrayList&lt;File&gt; res) {
      if (dir.getName().toLowerCase().contains(query.toLowerCase()))
          res.add(dir);
      if (dir.isDirectory() &amp;&amp; !dir.isHidden()) {
          if (dir.list() != null) {
              for (File item : dir.listFiles()) {
                  fileSearch(item, query, res);
              }
          }
      }
  }
  </code></pre>
  
  <p>If someone could point me to a way of performing a faster and/or more efficient file search, I would really appreciate that.</p>
  
  <p>EDIT:</p>
  
  <p>This is how I tried to do the job with AsyncTask:</p>
  
  <pre><code>private class Search extends AsyncTask&lt;File, Integer, Void&gt; {
  
      String query;
      ArrayList&lt;File&gt; result = new ArrayList&lt;File&gt;();
  
      public Search(String query){
          this.query = query;
          setTitle("Searching");
      }
  
      @Override
      protected Void doInBackground(File... item) {
          int count = item.length;
          for (int i = 0; i &lt; count; i++) {
              fileSearch(item[i], query, result);
              publishProgress((int) ((i / (float) count) * 100));
              // Escape early if cancel() is called
              if (isCancelled()) break;
          }
          return null;
      }
  
      protected void onProgressUpdate(Integer... progress) {
          setProgress(progress[0]);
      }
  
      protected void onPostExecute() {
          searchResults = new ListItemDetails[result.size()];
          for (int i = 0; i &lt; result.size(); i++) {
              File temp = result.get(i);
              if (temp.isDirectory())
                  searchResults[i] = new ListItemDetails(temp.getAbsolutePath(),
                          R.drawable.folder, temp.lastModified(), temp.length());
              else {
                  String ext;
                  if (temp.getName().lastIndexOf('.') == -1)
                      ext = "";
                  else
                      ext = temp.getName().substring(
                              temp.getName().lastIndexOf('.'));
                  searchResults[i] = new ListItemDetails(temp.getAbsolutePath(),
                          getIcon(ext), temp.lastModified(), temp.length());
              }
          }
          finishSearch();
      }
  
  }
  
  public void finishSearch() {
      Intent intent = new Intent(this, SearchResults.class);
      startActivity(intent);
  }
  </code></pre>
  
  <p>The call to finishSearch() is just so I can create the Intent to show the results in other Activity. Any ideas, suggestions, tips? Thanks in advance</p>