作为我的应用程序的一部分,我通过使用ApplicationPackageManager.getInstalledApplications获得设备上安装的应用程序列表,但对于某些用户,我收到崩溃报告说
android.osBinderProxy.tranasact(Native Method)中的TransactionTooLargeException
有谁能想到我为什么会这样做?
答案 0 :(得分:14)
我发现这是在Android 5.1(证明here,搜索“修复包管理器TransactionTooLargeExceptions”)上解决的,因为它在多个地方报告:
但是,我想在5.1之前解决这个问题,所以我想出了一个解决方案(建议谷歌把它放在支持库上,这里)。这是我建议的简短代码版本:
public static List<PackageInfo> getInstalledPackages(Context context,int flags)
{
final PackageManager pm=context.getPackageManager();
try
{
return pm.getInstalledPackages(flags);
}
catch(Exception ignored)
{
//we don't care why it didn't succeed. We'll do it using an alternative way instead
}
// use fallback:
Process process;
List<PackageInfo> result=new ArrayList<>();
BufferedReader bufferedReader=null;
try
{
process=Runtime.getRuntime().exec("pm list packages");
bufferedReader=new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line=bufferedReader.readLine())!=null)
{
final String packageName=line.substring(line.indexOf(':')+1);
final PackageInfo packageInfo=pm.getPackageInfo(packageName,flags);
result.add(packageInfo);
}
process.waitFor();
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if(bufferedReader!=null)
try
{
bufferedReader.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
return result;
}
首先尝试使用官方方式,然后,如果失败,它会使用ADB命令获取包名称,并一个接一个地获取每个应用程序的信息。
它比官方的慢得多,但它并没有让我崩溃。我已经在Android模拟器(2.3.x到5.0.x,包括)和真实设备上进行了测试。
我的设备(带有Android 5.1自定义rom的Galaxy S3)花费的时间为1375-2012毫秒(总共197个应用程序),而使用官方方式为37-65毫秒。
编辑:人们声称在Android 5.1上没有修复它。我希望它在Android 6上得到修复。答案 1 :(得分:5)
在正常情况下,此异常很难重现。传输数据时,如果IPC内存耗尽,您将收到此异常。在两种情况下都会发生这种情况,其中服务试图将数据放置到客户端或客户端正在将数据发送到服务。很可能你的一些用户可能安装了大量的应用程序,导致数据大小超过1MB(这是IPC缓冲区的大小)。
我担心在这种情况下,你不会做更好的事情。但是,如果您正在执行类似applyBatch的操作,则可以将一个大型事务分成多个较小的事务。