繁体   English   中英

在android中退出应用程序时如何删除由createTempFile创建的所有临时文件?

[英]How to delete all temp files which created by createTempFile when exit an App in android?

我使用以下代码创建一些临时文件,并将 tem 包装为 inputteam 以发送到客户端。

我知道当磁盘空间不足时,android 系统可以自动删除临时文件。

但是我希望我可以在退出应用程序时自己删除临时文件,我该怎么办? 谢谢!

代码

File outputDir = context.getCacheDir(); // context being the Activity pointer
File outputFile = File.createTempFile("prefix", "extension", outputDir);

如果isChangingConfigurations()falseisFinishingtrue则删除onDestroy的文件。 例子:

@Override protected void onDestroy() {
  super.onDestroy();
  if(!isChangingConfigurations()) {
    deleteTempFiles(getCacheDir());
  }
}

private boolean deleteTempFiles(File file) {
  if (file.isDirectory()) {
    File[] files = file.listFiles();
    if (files != null) {
      for (File f : files) {
        if (f.isDirectory()) {
          deleteTempFiles(f);
        } else {
          f.delete();
        }
      }
    }
  }
  return file.delete();
}

调用deleteOnExit()方法!

或者

在活动的onStop()中调用delete()方法。

编辑:

如果您在onDestroy()调用delete()以确保即使应用程序被系统销毁,您的代码也能正常工作,可能会更好。

尝试使用 WorkManager 确保即使在应用程序关闭后它也会清理临时文件。

    override fun doWork(): Result {

            return try {
                applicationContext.cacheDir?.let {
                    if(it.exists()){
                        val entries = it.listFiles()
                        if (entries != null){
                            for (entry in entries) {
                                Timber.i("My file: ${entry.name}")
                                entry.delete()
                            }
                        }
                    }
                }
                Result.success()
            } catch (e: Exception) {
                Timber.e(e)
                Result.failure()
            }

        }

首先,请记住,Android 应用程序的“退出”与桌面应用程序的含义非常不同。 有关详细信息,请参阅这篇文章,但简短的回答是,一般而言,您不知道操作系统何时真正关闭您的应用程序(即使它不可见)。 事实上,没有明确保证操作系统会关闭它。

可以在这里找到一些想法(它是 C#/Xamarin.Android,但与 Java 完全相同): How to detection application exit on android?

除了此处列出的内容之外,您还可以尝试在手机关机时注册广播接收器。

另一种(更糟糕的是,在我看来)方法是在应用程序不再可见时(在onStop )简单地执行此操作。 然而,如上所述,这与程序实际关闭不同(因为您不知道操作系统何时 - 甚至是否 - 实际关闭应用程序)。

如果您可以为您创建的所有文件维护一个集合(避免重复)会更好。

并迭代文件列表,将每个文件一一删除。

 public static final Set<String> TMP_FILES = new HashSet<>();

并通过迭代删除所有内容。

public void deleteTempFiles() {
  for(String myTempFile: TMP_FILES) {
    try {
      new File(myTempFile).delete();
    } catch (Exception e) {
      // Handle if needed.
    }
  }
}

不幸的是,您似乎必须通过先前将它们保存在数组中来一个一个地删除这些文件。

话虽如此,如果您在此问题上查看 Android 开发人员页面,就会发现您可以“定期删除缓存文件,并定期删除您不再需要的其他文件”。 但是,我认为没有关于如何做到这一点的解释。

我最终在这里寻找一种方法来删除我为相机意图创建的临时文件,我实际上结合使用了Sridhar 的答案和这个答案中cleanOldFiles函数

我正在使用createTempFile创建一个新的图像文件,然后将其添加到

public static final HashSet<File> TEMP_FILES = new HashSet<>();

使用普通的 foreach 循环迭代并从集合中删除会抛出java.util.ConcurrentModificationException所以我使用Iterator更新了循环

更多关于迭代器

我想我会发布以防它帮助其他人,感谢来自其他帖子的 Sridhar 和 ggrandes 的帮助。

public synchronized void cleanTempFiles(final int secondsOld) {
    long now = (System.currentTimeMillis() / 1000);
    for (Iterator<File> iterator = TEMP_FILES.iterator(); iterator.hasNext(); ) {
        File f = iterator.next();
        long expired = (f.lastModified() / 1000) + secondsOld;
        if (now >= expired) {
            Log.d(TAG, "Deleted file - \"" + f.getAbsolutePath() +"\"");
            f.delete();
            iterator.remove();
        }
    }
}

该函数以秒为单位删除早于给定时间值的文件,并被调用

cleanTempFiles(3); // or however long

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM