As part of an automated build for android projects, I want to validate the layout xml files contains a string reference (i.e. pointing to strings.xml) such as
android:text="#string/what_ever_identifier"
and not something like
android:text="a string not referenced in strings.xml"
If the text contains absolute strings, then I want the build process to fail.
I searched for the appropriate ant tasks but could not find any. The closest I saw was ReplaceRegExp. But I do not want the replace functionality of regex. I need something similar to grep.
Any pointers on how I can achieve this?
I think what you are probably looking for is the "-z" flag passed to aapt, which has it require that any strings it knows are displayed to the user come from string resources that can be localized rather than string literals.
Related
I need to replace a string in a dex file. That is, I need a tool (free and open-sourced) that receives dex file, string index and new string value as input parameters and produces new (patched) dex file.
It shouldn't be too hard to write by myself, but maybe there's a tool that does exactly what I need and can save me time.
Any help will be appreciated!
I'm not aware of an existing end-to-end solution. Your best bet would be to use dexlib2. In particular, the DexRewriter class is a good example of how to go about doing this sort of replacement, although it doesn't directly support string replacement.
I don't think modifying a string in the string table is actually what you want. Keep in mind that strings can be used for a number of things in a dex file: string constants, method names, field names, class names, etc. If you just want to change a string constant, you would need to find and replace all instances of where that string is used as a string constant. If you try to replace all instances of that string, you might end up inadvertently modifying a field name, etc.
Probably a little late answering but hopefully others who come across this can benefit. The sable soot library (https://github.com/sable/soot) offers tools to modify Android APK files code. Once the library is set up then swapping out a single string is not too bad.
I have been working on a simple android tutorial and while browsing through the project folders I found this R.java file in gen folder...
When I opened it seemed to me as a mess...
first R itself is a class.
it had multiple Inner classes defined within eg drawable,id,layout,etc.
and that inner classes had lots of variables declared as below which were assigned with hex values
public static final int addr=0x7f080003;
...
...
and much more
R is auto generated and acts as some pointer for other files
Questions for R.java
what it is basically for
how it works
why
values are in hex
what role did it performs while the actual application is running
"Acts as some pointer to other files" is actually absolutely correct, now the question is which files it points to how it is done.
What does it contain?
R file contains IDs for all the resources in the res folder of your project and also some additional IDs that you define on your own (in the layouts, for example). The IDs are needed for the Android resource management system to retrieve the files from the APK. Each ID is basically a number which corresponds to some resource in the resource management system.
The file itself is needed so you can access or reference the resource from code by giving the ID of the resource to the resource manager. Say, if you want to set the view in the activity, you call
setContentView(R.layout.main);
main in the R file contains the number which is understood by the Android resource management system as the layout file which is called main.
Why is it better than just plain file names?
It's harder to make a mistake with the generated fields. If you write the field name incorrectly, your program won't compile and you will know that there's an error immediately. If you write an incorrect string, however, the application won't fail until it is launched.
If you want to read more on this topic, you should check the Android documentation, especially the Accessing Resources part.
This holds your resource ids. So when you do something like
TextView tv = (TextView) findViewById(R.id.mytextview);
it looks up your id here for that View, layout, etc... This way the app has an easy way to look up your ids while you can use easy to remember names. Anytime you create a resource it automatically creates an id for it and stores it here. That's why you never want to try and edit this file yourself.
One way to think about how valuable R.java is, imagine a world without it. Its amazing how android brings the xml and java world together to help avoid coding the UI manually completely. With legacy java building UI using the java language was a pain. Invaluable.
With Android you can not only build your UI using only xml, but also see it while you build it. Invaluable.
Every element in the xml can be referenced in the java code WITHOUT writing a single line of code to parse the xml :). Just R.id.nameOfElement. Invaluable.
Rapid development is beautifully done in android. Imagine if iPhone would have 5000 screens to fit that one piece of code, they would crumble on their XCode. Google has done a wonderful job with just R.java. Invaluable.
In android we have files by name String. Developers define the string values that they used for naming objects in this file. This is a very useful way. Because avoid of hard coding string values(you can change them from a single file, less time to change), also useful to creating multi language application and etc. (for more info just google this).
But the question is this: whether iPhone(Monotouch) have a mechanism like this to define strings on them or developers have to define themselves mechanism for this?
In XCode, you'll find File/New File, then on the left, pick "Resource", and you'll find "Strings File".
From code, you'll be referencing the keys in your strings file with NSLocalizedString:
NSLog("%#", NSLocalizedString(#"YOUR-STRING-KEY-OR-DEFAULT-VALUE", #"Comment about what this is"));
For details on what that second param is for, What is the second parameter of NSLocalizedString()?
Put your strings in a single file. Make them global constants. Access them throughout the app. When you change these, the change will be reflected everywhere.
It's not a big deal to have persistent string references throughout your app. It can be done in any decent programming language and platform I suppose.
I have read in many places that you should declare your String objects in your resource file but I haven't read about any benefits anywhere.
I have already declared all my Strings that I have in my layouts as resources but I haven't done so in my classes.
My question is:
What are the benefits of declaring Strings as a resource? Are there any memory benefits?
Internationalisation,
Keeping all of your strings in a single place (where they can be editted globally),
Changing strings based on device (mdpi/large/portrait)... I mean, it'd be really rare for this
last one, but it's possible.
Sharing the same string among many layouts (this will happen in any app which isn't tiny)
The top one I reckon is: Translations! Put a new strings.xml in the right folder and the app translates itself for each device.
But there's a matter of organisation too. Just like the layout, you normally don't build in the code, because that's not the place for it.
The code is to process stuff. The string is just one more of the resources that your code will use to show stuff on the screen.
One of the main benefits is for localization: you keep your code language-independent and just need to provide a different XML file for each language you want to support.
As you probably know, Mozilla aims to do the mobile UI on fennec as native Java/Android UI.
That includes using the layout XML files, which by default use stuff like
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="#string/text_a"
/>
with #string/text_a being resolved to text_a in a strings.xml file, doing l10n.
We'd like to use something else, and I wonder if/how we can hook that up in the XML files.
So, I'd love to get pointers to android source code that actually does the string lookup, for one.
And I have three ideas on how to hook up something custom, which are not fact-checked, basically because I haven't managed to find the code that does stuff yet:
#moz-l10n/text_a, with a java-implemented service giving back values for that resource type
moz:l10n="text_a" custom attribute that would get hooked up to post process the generated widgets
subclass the widgets we want to localize with our scheme, adding (2)
I hope that there are folks out here that have a good idea to point me to good paths or shoot some down.
PS: I'd appreciate a lack of bike-shed about whether android l10n scheme is good or not.
So, I'd love to get pointers to android source code that actually does the string lookup, for one.
android.content.res.Resources delegates to android.content.res.AssetManager and the getResourceText() method. That in turn dives into a native loadResourceValue() method. And you're on your own from there... :-)
1) #moz-l10n/text_a, with a java-implemented service giving back values for that resource type
Unless you are going to pre-process your faux resource files with your own build tools, generating valid Android resource files into the res/ directory, you cannot invent new resource types (e.g., #moz-10n). That would require modifications to the build tools and the firmware.
2) moz:l10n="text_a" custom attribute that would get hooked up to post process the generated widgets
3) subclass the widgets we want to localize with our scheme, adding 2)
Your option #3 is definitely possible and is fairly typical when creating custom widgets. It's conceivable that the techniques for it (usually involving a res/values/attrs.xml file with a declare-styleable resource) could somehow be applied to a standard widget class, but I've never seen that done. Of course, you could always do the pre-processing as in how you'd accomplish option #1.