我知道我可以通过调用NameNotFoundException
来捕获PackageManager.getPackageInfo
或循环访问PackageInfo
返回的PackageManager.getInstalledPackages
列表,以了解是否安装了特定的包,但这两者似乎都是漫长的啰嗦或丑陋。在我的个人电话上,我安装了300多个软件包,所以每次我需要检查时,我都不想做这个操作。捕获异常作为执行应用程序逻辑的一种方法只会让我感到错误。我在某处错过了isPackageInstalled方法,还是只需要使用上述技术之一自己实现它?如果是后者,那将被认为是更快,资源更少的选择?
答案 0 :(得分:2)
由于PackageManager.getInstalledPackages()
返回List
,因此您无需手动循环。您可以使用List.contains()
或List.containsAll()
在一行代码中完成任务。当然,这并不会改变效率,因为两种方法本身都可能包含一个循环。
答案 1 :(得分:1)
如果使用API确实会让您感到烦恼,那么您可能会看到涉及以下内容的黑客攻击
获取PM列表的Bash shell表达式 Java运行时表达式 Java管道,缓冲区和流 Java NIO Java grep
所以bash表达式将是:
pm list packages -f | sed's / ^ package .//'| awk -F“=”'{print $ 2“”$ 1}'|排序
以及从'pm list'处理stdout的参考列表,其方式可能会更快......
答案 2 :(得分:0)
处理一个NameNotFoundExcepetion不应该让你觉得“整个错误”恕我直言。根据{{3}},如果自api级别1后包不存在,则抛出此异常。使用try / catch语句与使用if / then语句测试空值非常相似。
在这种情况下,不应将其视为变通方法或黑客攻击,因为您正在使用已记录和预期的异常返回值来确定是否存在包。
我认为这种方法比通过getInstalledPackages()返回的List迭代更快。但是,我不知道在返回NameNotFoundExcepetion之前android采取了什么步骤。这将是一个有趣的基准测试。
我不知道有任何其他实用方法来测试已安装的软件包。
答案 3 :(得分:0)
我写了一些基准测试并测试了捕获异常与几种不同的方法来获取已安装的软件包并循环遍历它们。这是我的结果
调用PackageManager.getPackageInfo并捕获NameNotFoundException在所有情况下都需要1到4毫秒,无论是否安装了请求的包,我确保还包括这是第一次调用PackageManager的情况应用程序的特定运行以及后续调用,以防框架在每次应用程序启动时对此信息进行任何缓存。
在所有情况下,调用PackageManger.getPackageInfo也需要1到1.5秒。
调用getPackageInfo并捕获异常以确定是否未安装软件包是目前检查的更快方法。