TransactionTooLargeEception when trying to get a list of applications installed

后端 未结 2 1172
Happy的楠姐
Happy的楠姐 2021-01-31 06:13

As part of my app I get a list of apps installed on the device by using ApplicationPackageManager.getInstalledApplications but for some users I get crash reports saying that

2条回答
  •  粉色の甜心
    2021-01-31 06:31

    I've found that this was solved on Android 5.1 (proof here, search for "Fix package manager TransactionTooLargeExceptions") as it was reported on multiple places:

    • https://code.google.com/p/android/issues/detail?id=95749
    • https://code.google.com/p/android/issues/detail?id=93717
    • https://code.google.com/p/android/issues/detail?id=69276

    However, I wanted to solve this for pre-5.1, so I've come up with a solution (and suggested Google to put it on the support library, here) . Here's a short code version of what I've suggested:

      public static List 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 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;
        }
    

    What it does it to try using the official way first, and then, if failed, it fetches the package names using ADB command, and get the information of each of the apps, one after another.

    It is much slower than the official one, but it didn't crash for me. I've tested it on Android emulators (2.3.x till 5.0.x, including), and on real devices too.

    The time it took on my device (Galaxy S3 with custom rom of Android 5.1) is 1375-2012 ms (on 197 apps total) compared to 37-65 ms using the official way .


    EDIT: people claim here that it's not fixed on Android 5.1 . I hope that it got fixed on Android 6 .

提交回复
热议问题