I have a question about the google play asset delivery system.
Is it possible to reuse asset packs in previous versions of an app without redownloading them on the user end?
Right now, I have one asset pack which is currently in use, and I would like to add a second asset pack with some new images. I made no changes to the first asset pack (and never plan to), but when I go to download the app on internal testing, I get an update download with the size of ~300mb (which is the size of the 1st asset pack + the new one).
I read on the documentation that updating an app would invalidate all previously installed asset packs (which I am guessing causes the play store to download the 1st asset pack again), so I was wondering if there was a way around this, because I would really like to not re-download 300mb of cards when I only made a 13mb addition.
The app had already been installed, and the asset pack had also been fully downloaded and installed, so I was wondering why the update redownloaded it instead of leaving it alone.
I thought that putting the new images in a new asset pack would prevent the 1st pack from being invalidated, but it doesn't seem like that is working.
Basically, the end result I'm looking for is to have a ~15mb update which adds the new images and updates the base code (which is around 2mb total). Is this possible?
Here is the build.gradle of the 1st asset pack in case it helps:
apply plugin: 'com.android.asset-pack'
assetPack{
packName = "cards1_0"
dynamicDelivery {
deliveryType = "on-demand"
}
}
Any help would be greatly appreciated, or if I'm completely wrong on this issue then I'd love to know.
I have spent several hours trying to figure out the same thing.
What the documentation for Google Play Asset Delivery does not specify is that once you upload your bundle, it takes time to generate all the different APKs that users can download.
One of the first APKs that is generated is the one that downloads everything and is available right after you publish your internal update.
My download size was over 300 MB at first and included everything. However once I waited about 15-20 minutes, the download size went down to under 15 MB (as expected) on all my test devices.
So the answer is - wait until Google servers are done processing your bundle and generating delta packages in the background. The time will almost guaranteed vary depending on server load and your original bundle size.
Related
Some relevant background:
My application is a Java app compiled into a .exe via JSmooth. The anticipated user base would likely be a few hundred users, but could grow well beyond that, as it's a community specific application.
How it works:
2 .jar files, one that preforms initial checks, another with the meat of the application.
Ideally, the init jar displays the splash, checks the version in desktop.txt against server.txt, if they differ, it prompts the user to update.
What I need to figure out:
1) What is a cheap, scalable hosting service that I could use as the file host for updates?
2) How can I create an "updater" to actually preform the jar replacement? My current solution is simply writing an updater in Java, but I was hoping for something like the installers people are more familiar with.
All of the research I've done has resulted in lackluster results, as 99% of hosting searches result in site hosting results. I just need an update repository with reasonable security. i.e., decent DDoS resistance and not left wide open to the Internet.
Edit: formatting
Easy to do and very foolish cheap with Amazon S3 or Joyent Manta as both support time-limited signed URLs and headers (which can contain a SHA-1 of the file) to check to see if the update is needed before downloading
On startup your app would check the update URL to see if it has changed. If it has changed, download the JARs. Do this before the app loads classes from those JARs. Updating the updater itself will be trickier so consider that an update might need a new update URL to prevent expiry.
I have done this with iOS perfectly and now I need it for Android. I have one codebase that can create unlimited different apps with a simple config file change.
Each app is created based on a complex XML config file that I included in the resources. All I make is one simple change in my strings.xml file and it points to the config file needed, which in turn makes this my project a new standalone app. Easy.
<string name="xmlconfig">nike-shoes</string>
But now that I have done that, how do I make the change so each app is it's own APK?
How can I switch between apps (and uploadable apk's) easily with one codebase and one project. I have heard people say "use a library and then just create a project for each that includes it" but that gets overly complicated when you have 15+ apps and growing.
And I've also seen people say "why not just make one app where you can switch between them all within the app" but that also is irrelevant to my project and doesn't make sense to my users. I can't explain more than that unfortunately, but the short answer is that this won't work as well.
What I did on the iOS project I have is that I just change the Bundle ID, change the code signing identify to match, change the app name, and point to the new plist from within my main Info.plist file. BAM! Whole new app. A few simple steps that takes me less than a minute.
How can I do this with Eclipse/Java/Android? What is the easiest way?
A few steps is fine, as long as I am not mucking with every file to get it done.
I figured I would answer my own question here using Android Studio (2.2.3 at the time I'm typing this), do the following:
In your AndroidManifest file, click on your package name (click the whatever part of com.myapp.whatever) and then hit Shift+F6. Choose "Rename package" and then rename it (without the com.myapp part). Don't do it for comments, strings, and text unless needed. You'll need to approve the refactor with the button at the bottom of the Android Studio window.
Check your build.gradle file and make sure your applicationId under defaultConfig matches what you changed it to.
In your strings.xml file, change your app_name and other strings as needed to make your app its own.
Takes me about 1-2 minutes to have a whole new app. Hopefully someone else finds this useful.
All you need to do is change the package name in the manifest(and a little re-factoring in your code file due to base package name changed), and the next build will create a new App.
If you want to maintain all your apps I would also recommend to create a branch for each app that will contain this change set. this way you can fix something and push it to all versions.
Lets say you change com.foo to com.foo.bar, then rebuild, all your R imports should be now added .bar, just find replace import com.foo.R to com.foo.bar.R, thats about it.
Convert your initial project in a library project, then reference to it from all other projects. This way you have a big advantage: all modification made to the library project are yet available in the other projects. Refernce: http://developer.android.com/tools/projects/projects-eclipse.html#SettingUpLibraryProject
Here is said that files saved on getExternalCacheDir() will be deleted on uninstall.
I have placed my downloaded files there.
Everything works fine with 3 devices.
But with one Samsung Galaxy S2 with Android 4.0 these files do not delete.
What can be the reason of this?
Looking at the getExternalCacheDir() documentation:
The platform does not always monitor the space available in external storage, and thus may not automatically delete these files. Currently the only time files here will be deleted by the platform is when running on JELLY_BEAN_MR1 or later and Environment.isExternalStorageEmulated() returns true. Note that you should be managing the maximum space you will use for these anyway, just like with getCacheDir().
Looks like the device has to be Android 4.2 and later for the external storage caching. You could have your app do its own clean up. See here for detecting when your app is about to be uninstalled.
The app works perfectly fine on the simulator and on the device. After adding a new set of images, it started to show on every run, on the simulator and on the device, a class not found exception.
When trying to delete some images to find the cause, I get different classes not found when running. Compiling and packaging the application generates no warning or error. They even get signed. Some of the "classes not found exception" I get:
java.lang.stringbuilder
net.rim.device.api.ui.uiapplication
I am guessing it has something to do with the total image size. The size of each image ranges from 100KB to 300KB, and we are talking of only 25 to 30 images in total. Adding the image outside of the 'res' folder doesn't generate the error, but the image isn't added to the final files. Deleting the images, the ones just added resolved the issue, but I need those images...
Also, this application is not big, but when compiling, and packaging the app, it generates and signes 125 cod files. Is that normal?
I am using Eclipse 3.6(Helios), and BlackBerry Eclipse Plugin SDK 5.0.0.25 on Win 7
Any help will be appreciated. Thanks.
Each .cod file is limited to about 64K. If your 25-30 images average about 200K, the 125 cod files doesn't surprise me.
The error messages sound like rapc is getting very confused. After you add your images, try refreshing the project or even exiting and restarting Eclipse, then clean and build the project from scratch.
Including large amounts of media is generally not a good app design for the BB. There's a good discussion here about alternative ways to handle this.
It turns out this issue was caused because of the total size of my images, which in turn created more then 127 .cod files. Total number of siblings .cod files is 127, my app had that limit, and this is why some essential classes were not included. I still think the blackberry plugin should warn about this, because it showed no error when compiling, packaging and signing the application. Here is the link from the BlackBerry developer support forums where I got this information:
http://supportforums.blackberry.com/t5/Testing-and-Deployment/The-maximum-size-of-a-BlackBerry-smartphone-application/ta-p/502534
Since I am used to the iOS world, where I can add whatever I want to the app, and it has virtually no limit on the resources I can add, except to consider that the user would have to wait a good amount of time downloading the app, and the 2GB application size, which, really is a lot for 99% of the apps.
So for this app what I did was I added only the essential images as compiled resources in the app, and the rest of the images are downloaded automatically when the application launches the first time.
I'm using Eclipse Galileo working with a large java project.
When I type out a method like:
InterfaceDefinedInOtherPackageAndNotYetImported getSomething() {
return something;
}
Eclipse will underline the InterfaceDefinedInOtherPackageAndNotYetImported type, because I have not yet imported it. So I position my cursor on it and press Cntrl + 1 to bring up the list of error fix suggestions.
Every single time I do this, I hear my hard disk grinding away, and can see (in Process Explorer) Eclipse doing megabytes of disk I/O. It takes 5-10 seconds for the suggestion menu to appear. Even when this is the very first change I've made since building.
I'm on a newer, dual-core machine, and can see hundreds of free MB in Eclipse's heap status bar. So why does Eclipse have to hit the file system each time to get me a list of suggestions? Can't I get it to cache my type names somehow so that it doesn't have to do this? How can I get it to go faster?
Is the project small enough to put on a flash drive? You might get a speed boost by moving your workspace to a flash drive or SSD.