-
Notifications
You must be signed in to change notification settings - Fork 372
Slow parsing of APK files #97
Comments
So to parse the manifest alone, I've found I can do this:
But later I think it's a bit harder to get just the name of the app and on another function to get its icons... EDIT: tested it on all APK files that are installed on the device, and sadly it still takes a huge amount of time, this time even more than before (39384ms) , for some reason... Attached here a sample project. |
packageManager.getInstalledPackages read from a cached data, see |
Makes sense. ? I've tested now. Still takes less time. Took me 7 seconds now, using 0 as flags. Attached new sample project. I could instead get some APK files and parse them using both methods (the framework and this library). |
Is it possible perhaps to tell the library which types of data we wish to get?
I don't need all the extra things. Of course other developers might need, so I think it's best to tell the library what we need, and it will try to perform the minimal amount of parsing to get what was requested. |
AndroidDeveloperLB Try the following in your project here. It will save scanning the zip files and should be faster.
|
Using ZipFile is actually faster than the Android Framework: But there are still some issues here:
Do you know how to overcome those issues ? |
1. The reason I used ZipInputStream instead of ZipFile... The code below extracts data from the APK using the URI returned from SAF and is not dependent upon real paths. I believe that this code will give you access to 100% of the apk. (Tested on API 29 emulator with targetSdkVersion = 29.) 2. Sadly still unable to get some APK data using this method... I assume all the information you need is encoded into the apk file in some way. Unless the information is readily available, like some information from the manifest, you may need to look at the framework code to understand how to get to it. Fortunately, it looks like you need just a small amount of data.
|
Can you please share the full project, and show how well it works when going over all installed apps (to see it in action, compared to the normal Do you think it's a lot of work to get the app-icon and app-name? Remember that in some cases, the app-icon is not a simple image, but it can be an adaptive-icon (2 layers of images), or a VectorDrawable or both (adaptive-icon of one or two VectorDrawable )... If you have a good sample, which includes all of these, I have a bounty for you: |
@AndroidDeveloperLB I don't have the code that will use SAF to get a URI for the APK of each installed app. I don't see it in any of your samples. If you can post that, I will take a crack something that will parse the manifest from each APK for comparison. Even with access to raw APK files, your work is going to be cut out for you. What I presented will only get you the raw APK data through a URI supplied by SAF. I took a quick look at extracting even the app name from the APK and it won't be easy IMHO. This whole SAF thing looks to me like a disaster in the making. Maybe Google can pull a rabbit out of the hat for this one. |
I didn't mean that it will handle a Uri. You can use anything you wish, as long as it's compatible with SAF, and won't cause issues (such as OOM). As for how bad SAF and scoped storage are, you are correct. There are already articles about it and the issue tracker also has various issues about it. Here's one article, made by a file manager app : And you know of Commonsware? He decided to write so many articles about it, trying to help developers about it when possible: |
Is it possible perhaps to grab the part in Android's code to do this, and that's it? Or even a hack to use it? |
I saw the coverage of SAF and read CommonsWare's blog about it. It is a general headache, but you may be able to get around it (still a headache, though.) Here is a short app that dumps to logcat some the information that you are looking for. It uses the package name to get the package info. I am unclear about your exact needs but, if you have URIs from SAF, you may be able to match those URIs up with what this little app can do - maybe by matching APK signatures, APK location, etc.
My sense is a huge amount of work and I would always wonder if I did everything right. Personally, I would spend time trying to leverage the system but that is me. |
Sadly using what the system has (currently) would work very badly in terms of performance, because it will require me to copy the APK file before I can read it. So if I go over multiple files (especially large ones), it's just a waste of time and space. My app (here: https://play.google.com/store/apps/details?id=com.lb.app_manager ) searches for all APK files on the storage of the device, and shows information about each, while also allowing to install, delete, and share them. Your sample doesn't work as I wrote. It just takes the already known information about the installed APK files. My question was about APK files in general, so it should work even for non-installed APK files, and it should work with SAF too. So assume you have a Uri and/or inputStream to parse the APK file. You could have the inputStream again and again, of course, and you shouldn't copy the file either (because that's not really parsing of the original file, just a copy of it, and it wastes time and space), and not load it entirely into memory (because of possible OOM) |
I think latest versions of this library are actually good in terms of performance. Closing this. |
I tried to check how much time it takes to parse APK files using this library, compared to the one of Android's framework.
I know it's a bit hard to compare performance, but I tried to get it anyway.
So I went over all installed apps, taking all flags possible for
packageManager.getInstalledPackages
, and getting the name of each app.And I did it for the library itself. I know the library does a lot more, but I think it can be better if we tell it exactly what to do.
The results are quite bad (tested on Pixel 2).
It took 3555 ms to use the Android framework.
But, it took 27088 ms to use this library.
Attached here the sample project.
My Application.zip
Is it possible to split the various parsing tasks in the library?
Something that could match the one of Android framework?
When I don't give any flags and not getting the names of the apps, it's even much faster (less than 100ms)...
It doesn't get the app name and icons, but I can do it later on a different task.
Is there a way to make it faster? To match the same performance, and delay loading of things that might not even be needed?
Maybe to parse only the manifest file, and later the rest, if needed?
The text was updated successfully, but these errors were encountered: