We’ve been using WWW.LoadFromCacheOrDownload to copy asset bundles from StreamingAssets to the cache (for faster loading), but after attempting to switch to using UnityWebRequest.GetAssetBundle, we’re now getting the following error:
A URL Connection to a Java ARchive (JAR) file or an entry in a JAR file is not supported
(the URL is jar:file:///data/app/). Is this use case something that will be supported in future releases, or perhaps is there a more appropriate way to go about getting bundles from StreamingAssets cached with UnityWebRequest? We’re currently on 5.4.0p3. We would use AssetBundle.LoadFromFileAsync to load the file directly, but it takes significantly longer than loading a cached asset bundle, so being able to maintain this usage after WWW is deprecated would be very good for us.
I understand that this support it’s not only for Asset Bundles isn’t it? We need it for any file loaded with UnityWebRequest. There are other cases like xml, json, textures, videos…
Yes, even though it is not recommended.
For loading asset bundles from streaming assets you should use AssetBundle.LoadFromFileAsync().
While on Android it’s recommended to not use streaming assets for performance reasons. You are in fact reading from apk, which is a zip file.
Hi! I’m currently working on AssetBundles and I also encounter this kind of problem.
When you say :
What do we should use instead ?
For example, I have some textures variants that I want to load depending on screen resolution of the running device and I have no online server to host my AssetBundles what are my options ?
Yes but building an asset bundle implies more steps on workflow than simply putting files in streaming assets folder. Everytime you change something you need to build it for each platform you target. You also need to exclude in resources folder the asset bundles of the platforms that are not the currently one. Also the code to load the assets inside of it is not the same. It’s not a trivial change.
If you want people to start using asset bundles instead of streaming assets you should optimize and automatize this process.
Thank you Aurimas-Cernius for the answer. If I understand correctly, in my case, I cannot avoid to use streaming assets, and I will have to deal with performance when I use AssetBundle.LoadFromFileAsync() on Android devices.
To be sure to understand how AssetBundles works, am I right when I say :
Another way to do handle this, is to have a web server where AssetBundles are stored and have the game calling UnityWeRequest functions to connect and download the bundles. I wonder if it means that the player should always be online when he/she play the game ?
When I read these pages :
I suppose that AssetBundles will be downloaded the very first time the player launch the game and they will be cached. So the next time the player don’t need to be online to play because asset bundles are presents in cache, right ?
That’s how AssetBundles are designed to be used: you download a bundle, cache it and use to from that on until you update your game and a newer version of asset bundle has to be used (or your game somehow finds out that the newer version of asset bundle is available online).
You can ship asset bundle with your game too, but they were designed with download from internet in mind.
Note: make sure you use our APIs properly for asset bundle to be cached, otherwise you will have to pay the download/decompression price all the time.
I think I’m running into a similar issue here. I tried using AssetBundle.LoadFromFileAsync but that doesn’t actually cache the file (I check Caching.IsVersionCached immediately after loading the bundle and it always comes back false), so when I next run UnityWebRequest.GetAssetBundle on any bundle that I’d previously loaded from StreamingAssets, it says it’s not cached and re-downloads. Kind of the worst of both worlds (incurring the cost of bundling my assets with my binary and re-downloading them needlessly).
I’ve fixed this on iOS by loading the AssetBundles from StreamingAssets using UnityWebRequest.GetAssetBundle, pointing at Application.streamingAssetsPath (with the file:// protocol). This caches the AssetBundles. However, UnityWebRequest doesn’t like that path on Android.
Is there a way to use AssetBundle.LoadFromFileAsync to cache the AssetBundles it loads, or is there another method I can use to properly load and cache AssetBundles stored in StreamingAssets on both Android and iOS?
On Android Application.streamingAssetsPath already includes that ja:file:// protocol, all you need to append the file name to it and it can be loaded using UnityWebRequest.
We have never managed to get UnityWebRequest and a DownloadHandlerTexture to load files from StreamingAssets on Android, and don’t understand why. This is with Unity 5.6.3f1, but we have tried many other 5.x versions. The same code has always worked fine with WWW, and runs on all platforms other than Android. Note for sanity, we have constructed the path string in two different ways, and checked that filePathPerDocs and filePathFromStreamingAssets are identical.
// Construct path as recommended in https://docs.unity3d.com/Manual/StreamingAssets.html
string filePathPerDocs = "jar:file://" + Application.dataPath + "!/assets/" + fileName;
Debug.Log("File Path per docs: " + filePathPerDocs);
// Construct path as we always have for streaming assets.
string filePathFromStreamingAssets = Application.streamingAssetsPath + "/" + fileName;
if (Application.platform != RuntimePlatform.Android)
{
filePathFromStreamingAssets = "file://" + filePathFromStreamingAssets;
}
Debug.Log("File path using streamingassets: " + filePathFromStreamingAssets);
// Load it. This will fail, but will work if using a WWW.
using (UnityWebRequest www = UnityWebRequest.GetTexture(filePathFromStreamingAssets))
On Android, both of these functions build a string of the form:
And fail with: “A URL Connection to a Java ARchive (JAR) file or an entry in a JAR file is not supported.”
Can somebody tell me what is wrong with this string (e.g. by typing the correct form of the above string)? We have tried all manner of permutations of file://, ///, etc.
Interestingly, this thread implies that UnityWebRequest streamingassets support on Android was only added in 2017.1 (post #16)
Yet there are replies higher in this thread (e.g. #5) saying it works in 5.6.
I see nothing in the 2017.1 release notes saying that android streamingassets support for UnityWebRequest was added in this version. Unity release notes tend to be, umm, opaque but it would be great to clarify.
We tried to do the same.
Ship the apk with embedded initial asset bundles so that the users won’t need to download lots of asset bundles during the startup of the app and also to be able to patch those assets if needed.
However we didn’t succeed to work with the StreamingAssets.
We encountered the following issues:
Error joining threads: 22
We tried to LoadFromCacheOrDownload from the Application.streamingAssetsPath by going over a list of assets to be load for the first time the app launch (so that later on those assets will be in the cache).
For simplicity of the POC, we just did this in a for loop with yield return in it on the WWW object.