美文网首页
如何在安卓上优雅的搜索文件,解决The content of t

如何在安卓上优雅的搜索文件,解决The content of t

作者: Eternity岚 | 来源:发表于2019-04-09 17:17 被阅读0次

    码字辛苦!转载请注明出处!

    我们知道,在安卓上运行JAVA有严格的内存限制,不能像PC上那样肆无忌惮的使用递归和多线程,否则~

    OOM,经典不~

    那么,如何在安卓上优雅搜索文件呢?

    关键点就在于:

    1、取代递归

    2、适时终止上一个搜索线程

    3、在主线程中更新List和View

    4、避免线程中Activity对象造成的内存泄漏

    ——那我们把需要搜索的文件目录记录下来循环遍历,在回调时检测Activity生命周期,并进行线程切换,问题不就解决了嘛~

    话不多说,上代码:

       //搜索文件线程
       private Thread t_searchFile;
    
       public interface SearchFileListener {
           void gotOne(File file);
    
           void onFinished(List<File> searchedFiles);
       }
    
       //搜索文件
       public List<File> searchFile(final Activity activity, final String filePath,
                                    final String fileName, final SearchFileListener searchFileListener) {
    
           //终止上一个搜索线程(如果有)
           stopSearching();
    
           final List<File> searchedFiles = new ArrayList<>();
           if (TextUtils.isEmpty(fileName) || TextUtils.isEmpty(filePath)) {
               return searchedFiles;
           }
           t_searchFile = new Thread() {
               @Override
               public void run() {
                   super.run();
    
                   //不使用递归,而是将需要扫描的文件目录记录下来
                   List<File> waitForSearchFilePath = new ArrayList<>();
                   waitForSearchFilePath.add(new File(filePath));
    
                   while (waitForSearchFilePath.size() > 0 && !isInterrupted() &&
                           //所有循环均检测Activity生命周期,以防内存泄漏
                           !activityIsDestroyed(activity)) {
                       File[] files = waitForSearchFilePath.get(0).listFiles();
                       if (files != null) {
                           for (int i = 0; i < files.length; i++) {
                               if (isInterrupted() && activityIsDestroyed(activity)) {
                                   break;
                               }
                               final File temp = files[i];
    
                               //过滤掉没有读写权限的文件,以防权限异常崩溃
                               if (temp.canRead() && temp.canWrite()) {
    
                                   //全部转换为小写再匹配,以使搜索结果不区分大小写
                                   if (temp.getName().toLowerCase().contains(fileName.toLowerCase())) {
    
                                       //当Activity生命周期已经结束时,终止搜索
                                       if (activityIsDestroyed(activity)) {
                                           break;
                                       }
    
                                       //将符合条件的项目添加到链表,并在主线程回调以便刷新页面
                                       activity.runOnUiThread(new Runnable() {
                                           @Override
                                           public void run() {
                                               searchedFiles.add(temp);
                                               if (searchFileListener != null) {
                                                   searchFileListener.gotOne(temp);
                                               }
                                           }
                                       });
                                   }
                                   if (temp.isDirectory()) {
    
                                       //将子目录添加到待扫描链表,替代递归
                                       waitForSearchFilePath.add(temp);
                                   }
                               }
                           }
                       }
    
                       //完成当前目录扫描,移除链表
                       waitForSearchFilePath.remove(0);
                   }
                   if (!activityIsDestroyed(activity) && !isInterrupted()) {
                       activity.runOnUiThread(new Runnable() {
                           @Override
                           public void run() {
                               if (searchFileListener != null) {
                                   searchFileListener.onFinished(searchedFiles);
                               }
                           }
                       });
                   }
               }
           };
           t_searchFile.start();
           return searchedFiles;
       }
    
       //终止搜索线程
       public void stopSearching() {
           if (t_searchFile != null) {
               t_searchFile.interrupt();
           }
       }
    
       //检测Activity生命周期
       private boolean activityIsDestroyed(Activity activity) {
           return activity == null || activity.isFinishing() || activity.isDestroyed();
       }
    

    使用上述方法,实测该线程的内存(不含已检出的文件List)只有不到3K,OOM问题完美解决~

    相关文章

      网友评论

          本文标题:如何在安卓上优雅的搜索文件,解决The content of t

          本文链接:https://www.haomeiwen.com/subject/oseiiqtx.html