Менеджер пакетов Android умер с TransactionTooLargeException

мое приложение считывает список всех установленных файлов APK, а затем перебирает список, чтобы прочитать информацию APK, однако он выдает исключение TransactionTooLargeException.

из того, что я прочитал здесь http://developer.android.com/reference/android/os/TransactionTooLargeException.html, google рекомендует разбивать большие транзакции на более мелкие транзакции. Однако, похоже, это происходит посередине при циклическом просмотре списка APK. Если я поймаю исключение и продолжайте, остальное все работает нормально. Есть ли способ уменьшить использование памяти при вызове getPackageInfo? Этот вызов держит что-то даже после того, как он уже вернулся.

вот след, когда это произошло:

at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:89)
at com.myapp.appreader.getAppDetails(Appreader.java:207)
at com.myapp.appreader.collectData(Appreader.java:99)
at com.myapp.appreader.AppDataCollectionTask.run(AppDataCollectionTask.java:26)
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.executeTask(AppDataTaskExecutor.java:439) 
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.doInBackground(AppDataTaskExecutor.java:327)
at com.myapp.appreader.service.AppDataTaskExecutor$AppDataAsyncTask.doInBackground(AppDataTaskExecutor.java:1)
at android.os.AsyncTask.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask.run(FutureTask.java:234)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1080)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:573)
at java.lang.Thread.run(Thread.java:856)nCaused by: android.os.TransactionTooLargeExceptionat android.os.BinderProxy.transact(Native Method)
at android.content.pm.IPackageManager$Stub$Proxy.getPackageInfo(IPackageManager.java:1538)
at android.app.ApplicationPackageManager.getPackageInfo(ApplicationPackageManager.java:84)

2 ответов


существует ограничение 1 Мб на транзакцию связующего, что означает, что большинство вызовов IPC должны быть скромными по размеру.

если вы нажмете TransactionTooLargeException или аналогичные сбои связующего при извлечении данных из PackageManager (например, getPackageInfo()), попробуйте разделить запрос на несколько звонков, с меньшим количеством флагов (например, GET_META_DATA) за звонок. Надеюсь, это уменьшит размер любой отдельной транзакции, которая будет находиться под лимитом 1MB.

кроме того, если вы используете вызовы на PackageManager Это возвращает несколько результаты (например, getInstalledPackages(), попробуйте задать для нет флаги на этом вызове, а затем получение значений для каждого пакета по отдельности, чтобы избежать получения много данных на много записей сразу.

и, конечно, используйте только флаги, которые вам нужны, особенно если ваш вызов может содержать некоторые. GET_META_DATA является классическим примером этого: многие приложения используют его (например, для Play Services), но если вам не нужно знать информацию о метаданных, не запрашивайте ее.


Я нашел способ решить эту проблему, и написал об этом здесь.

короче говоря, он находит имена pacakges установленных приложений (с помощью ADB), а затем получает информацию о каждом из них, один за другим.