@Alex,
Happy to follow up, and please remember these are just thoughts for
improvement as I have no problems with the current system. I wasn't
intending to present an argument or present even an advocacy for any
particular solution; my apologies as my meaning was muddled with the
intention of presenting the use case of a new user using Google only
provided technologies and winding up in a situation that warranted a
requirement of accessing the /res directory from the NDK. The goal was
merely to show it is a non-zero chance (and I'd wager an increasing chance)
that only going down the path of Google best practices results in
developers having an unaddressed need.
That said, the points you make a valid. No Google provided API would be
considered cross platform, and naturally there's an xkcd to cover this
situation:
Loading Image...
However, I would mention that perhaps we're a bit quick to say there isn't
a solution that we can craft to address the needs of a cross platform
developer having access to apk resources. There's tradeoffs to other
solutions, however, if we first accept that all languages the NDK might
support now and in the future can natively read files off the disk with
basic file I/O and all other platforms share similar basic file I/O
capabilities. A solution presents itself if we eliminate the zipped nature
of the apk.
Obvious trade off with that solution is it would take up more disk space on
app install. This could be mitigated by expanding only portions a
developer would care about; which providing an api would allow a developer
to say what files should be available or label them in the manifest for
easy NDK access then explode to temp directory on either app install, run,
or when requested via API. There's also a chance if one were to be a bit
clever of crafting a ramdisk solution in Java that C sees as a file system.
Moving on to the Resources access for shared GUI concerns. I'd wager that
when sharing resources one wouldn't need to have concern about which screen
size / orientation etc are used. Allow me to elaborate this strange
assertion with pointing out that if one were to go down the path of having
their own GUI and requiring shared resources, then likely it's shared
because they're still using the very excellent Android GUI for some
interactions. This would indicate with my wild assumption that the reason
they might have a second GUI requirement is because the Android GUI doesn't
completely fit their needs. Now the reason why there's different resources
for different orientations, screen densities etc is because the GUI is
operating on a different viewport dictated by being different size,
oriented or on different screen densities etc.
Assuming my understanding is correct, the time an end user would get into a
use case requirement of needing their own GUI is when the frustum are not
the same as the full screen one provided by Android's GUI. This would be
the case of VR or AR and some games. Thus, if you have a custom projection
matrix, you likely have need of one version of a resource and wouldn't care
what the Java mapping is for a resource that wouldn't match your viewport
in the first place; after all, if you did care, you likely would be in a
scenario where Android's GUI is a better path forward.
So to clarify the use case here is Android GUI can't fit the needs due to
not using the custom viewport (which by the way you guys provide a means to
render the Android GUI to a GLTexture and I'll sing the highest of praises
for Android's GUI). However, there are some resources that can be used
sans changes between GUIs (logos and other sharable disk guzzling assets
that are high res etc). So my point in all this is it wouldn't likely
matter that R.drawable.my_background_image maps to
/res/hdpi/xxxx/background.png instead of /res/xxx/yyy/background.jpg.
What would ultimately matter is generic access to the file in the first
place as the reasoning behind the correlation is lost. It would have to be
incumbent upon the developer to determine the correct mapping within the
resources directory of reusable resources as that developer is the only one
capable of knowing the frustum they will be using.
If the dev wants to use a completely custom GUI, then they have all
resources in Assets and they have an existing solution. If the dev wants
to use completely Android GUI, then this isn't an issue as they can use
Java. If the dev has need for keeping the apk small (instant apps) and
they're looking for cutting file size costs, then providing a means to
access resources that might be shared between the two is attractive.
In this case what I'd propose is packaging zlib along with an easy to use
interface (API) to return a file for a given path within the APK. I'm not
sure there's a need to be more clever than that for the shared GUI problem.
Post by Alex CohnThank you for this reply.
This is not very convincing, I must confess.
When we speak about cross platform, no new API to access resources will
really help (unless Android finds a way to bring iOS and Unity to the same
ground). An independent 3rd party library could be better positioned in
this case.
As for sharing some resources with the "classic Android GUI", we must keep
in mind that the API will need all the logic of screen size / orientation /
locale / whatnot that is transparent when using Context.getResources()
<https://developer.android.com/reference/android/content/Context.html#getResources()>.
Not only that, resources use generated id's (e.g.
*R.drawable.my_background_image*), not names. As a result, the best
strategy in the rare cases that this is justified, is to call the native
Resources
<https://developer.android.com/reference/android/content/res/Resources.html> API
via JNI. All you need a valid Context
<https://developer.android.com/reference/android/content/Context.html#getResources()>
.
I agree that the existing Assets API which requires a Java object for
Asset Manager is not very convenient for native developers.
BR,
Alex
Post by Steven Winston@Alex,
While I can't offer up my companies' code (not a particular hurdle I'd
want to jump through for this), it's also not exactly earth shattering.
Zlib as provided by cdep and caching of files as they are extracted. If
you need such a tool open sourced, I can certainly write a new tool and
provide that. There's a ton of samples that aren't always the highest
quality of ideas. https://www.google.com/search?ei=9piyWoyAA4fUjwP57Kj
oCA&q=ndk+read+files+in+resources+of+apk results in many SO questions
unzip the apk
AAssetManager
Read in Java pass through JNI
etc.
For almost every use case I've seen in those questions, I believe the
understanding is incorrect and the developer should place the files within
Assets successfully ignoring the res directory when in the ndk. For these
use cases selecting AAssetManager is a quite competent solution; however,
it fails on one key area, cross platform and requires maintaining the java
object in code that doesn't really need it (I've seen some less than
optimal solutions caused by accessing the java object from other threads
etc).
So most of the time legacy game devs that aren't already on Unity, Unreal
or other common game engine here would select the first option, unzip the
apk. These are quite competent devs that understand caching so there's no
real problem there that a new API would help. That said, they are the
people I'd most expect to have a valid reason to select the first path and
already have toolsets in house that handle it.
For new devs, the challenge should be to instruct that Assets are where
you want to place NDK resources and use AAssetManager. However, I'd
propose a relatively new use case where if my understanding is correct, the
only available answer facing a new dev would be treat the apk as a zip.
Imagine, having a project that is targeting a VR/AR app that you wish to
have an in Vr/Ar GUI. Now that VR/AR app has a requirement of handling 2d
user interaction (system messages, help screens, or options menu) that must
display classic Android GUI elements for. Now imagine those GUI elements
include something that would be useful to both GUI resource sets (logos
come to mind). The natural solution for this use case would be to inform
the dev to duplicate the resource in both Assets and Res and stay with
AAssetManager. That works until someone cares about apk size, someone
might say "hey how about we do an instant app." Now we have to care about
the size of the apk a whole lot more. If my understanding is correct, this
set of circumstances will transition a dev from being fully able to
successfully only use AAssetManager. They'd now be in the corner case of
using the apk as a zip.
Again, this isn't a major requirement as using zlib or other zip library
is quite easy, most devs are used to it from other platforms, also even if
I weren't in a similar use-case requirement for the above scenario I'd
still opt for using zlib to better support handling resources in a common
method between Android/iOS/PS4 etc. Hopefully this provides an idea for
when it could prove useful to have such an API for others.
Post by Alex Cohn@Steven,
Could you point to some sample code that works decently? Or maybe Google
can help you opensource your toolset?
OTOH, I would be glad to learn in what use cases your native code needs
access specifically to /res and not to /assets.
Sincerely,
Alex
Post by Steven WinstonI have to admit to agreeing with Dan that this might be worthy of
consideration. I think you're right about the underlining intention for
Assets to hold assets and resources to hold android sdk stuff that changes
per several different factors. However, a standardized method of accessing
it from native would actually prove quite beneficial.
1.) It lowers the barrier for entry into using the NDK.
Everyone that works with the NDK for any longer length of time has in
their arsenal of libraries a tool that handles APK file access. It's
common to everyone and a concern of everyone. Thus it stands to reason
that new comers are likely to not have these tools/libraries and will wind
up reinventing the wheel.
2.) There's tons of implementations for reading the APK of vastly
varying levels of quality.
That point speaks for itself, but suffice it to say, if it's hard to
get the API right, then it's likely hard for new comers to get the
implementation right. Lots of bad code out there, can point to some sample
code that does incredibly bad things in this area too.
A bonus reason is this is a good common place where caching is quite
helpful; but underused by several companies / developers. If anything I'd
love to get a folder to place resources that gets auto expanded to a common
location on app install; for convenience if nothing else.
Please note, this is not a concern for me directly as I fall into the
category of having an already existing competent toolset.
Post by Alex CohnI beg to differ. I believe that the whole separation between assets
and resources exists because the former can be accessed as read-only files,
while the latter are used via Android SDK with built-in support for
providing alternatives for different languages, OS versions, screen
orientations, etc <https://stackoverflow.com/a/5583782/192373>.
There is very little added value in having native access to resources,
and many tricky questions to resolve while implementing it.
BR,
Alex
Post by 'Dan Albert' via android-ndkSounds like a reasonable API request. Looks like we're missing a bug
component for NDK API requests. I've asked for that to be fixed, but I
suppose for now you can file it in the Java category and we'll try to route
it appropriately: https://issuetracker.google.co
m/issues/new?component=328403
Post by Alex CohnThere is no API, but you can find your APK file
<https://stackoverflow.com/q/7701801/192373>, and trust that it is
a ZIP file under the hood.
BR,
Alex
Post by ideaWe know there is Android NDK API to read file from assets folder.
Is there any way to read file from res/raw folder?
--
You received this message because you are subscribed to the Google
Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it,
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit
https://groups.google.com/d/msgid/android-ndk/a76b0327-7ccf-
438d-8f0f-d38f9ca55d96%40googlegroups.com
<https://groups.google.com/d/msgid/android-ndk/a76b0327-7ccf-438d-8f0f-d38f9ca55d96%40googlegroups.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to a topic in the
Google Groups "android-ndk" group.
To unsubscribe from this topic, visit https://groups.google.com/d/
topic/android-ndk/A9jdEgAqkNw/unsubscribe.
To unsubscribe from this group and all its topics, send an email to
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/
msgid/android-ndk/852c4dfe-a28a-4b1e-a6db-1e2dc0dd4dfa%40googlegroups.com
<https://groups.google.com/d/msgid/android-ndk/852c4dfe-a28a-4b1e-a6db-1e2dc0dd4dfa%40googlegroups.com?utm_medium=email&utm_source=footer>
.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "android-ndk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to android-ndk+***@googlegroups.com.
To post to this group, send email to android-***@googlegroups.com.
Visit this group at https://groups.google.com/group/android-ndk.
To view this discussion on the web visit https://groups.google.com/d/msgid/android-ndk/CAFcKJqjhCrLv-HJQX7AFO4SeahYn4iPfy28AMGzMQdtiGfVutw%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.