Please explain me what is the purpose and meaning of classes like StringsKt__StringsKt (i.e. doubled class name with one or more underscores in between) and, similarly, StringsKt__StringsJVMKt?
Strings are not the only example, there are many others too. I see them when looking into the structure of the classes.dex file in my .apk.
screenshot here
I'm asking because I faced a situation where I had to explicitly state some of them in my proguard-rules. The app crashed without it.
It is a generated file. A file like that will be generated if there are several Kotlin files named with same JvmName.
Let's take Strings.kt and StringNumberConversions.kt as an example:
// StringNumberConversions.kt
#file:kotlin.jvm.JvmMultifileClass
#file:kotlin.jvm.JvmName("StringsKt")
...
// Strings.kt
#file:kotlin.jvm.JvmMultifileClass
#file:kotlin.jvm.JvmName("StringsKt")
...
Both of them have #file:kotlin.jvm.JvmName("StringsKt"), so StringsKt and StringsKt__StringNumberConversionsKt are generated to distinguish them.
Related
I know in Proguard you are recommended to keep the fields names of the R inner classes like ID. Because ProGuard doesn't handle the layout xml files. You will end up with broken links
But is there away to obfuscate classes like R$id by some other means, even if it involves doing it before passing it to ProGuard, via Ant.
I am asking this because if you have a button with an id btnSaveArticle, for a hacker it becomes too easy to grasp what the code around is doing by looking at the name.
Could it be possible to copy all the source code, including the resource files to another folder and use ant to run regex to change the names of the R.ids as well as changing where they appear in the layout xml files, and then somehow running generate to re-create the R classes?
Or you could create translation class eg TR then map it to the fields in the R.class
eg.
TR.btnSaveArticle = R.id.DHTXM;
Where DHTXM is some meaning less word that can be used in the layout XML. But in the code you always refer to TR.btnSaveArticle, which will be obfuscated by proguard.
Are there ways to achieve this or am I wasting my time?
Just use below ,add it to you Proguard config file
-keepclassmembers class **.R$* {
public static <fields>;}
I am asking this because if you have a button with an id btnSaveArticle, for a hacker it becomes too easy to grasp what the code around is doing by looking at the name.
Using Hierarchy View, it would take them less than 30 seconds to determine the actual ID of the "Save Article" button, no matter what you name it. And I can envision even faster solutions with a bit of custom tooling.
am I wasting my time?
IMHO, yes.
With the default configuration for Android, ProGuard removes R classes entirely, unless your code performs introspection on them. In the latter case, ProGuard also preserves the fields with their original names, in order not to break the introspection.
That being said, the resource names can also be retrieved from the resource XML files, which ProGuard leaves untouched.
It is possible through Ant, as it allows you to set a different gen and res folder.
So what you do is copy from the originals to those folders and then you edit the files using regex to update to the new names.
You will need a translation class (eg D) like this to map it to the fields in the R.class, so in your code you can work with non obfuscated names.
public final class D{
public static final class id{
D.btnSaveArticle = R.id.btnSaveArticle //DHTXM;
Then you also need to create a different src folder and copy from the original folder. There you run a task to edit the D class so it becomes
D.btnSaveArticle = R.id.DHTXM;
I had to create a java program which is run through ant to swap the names to obfuscated names.
If you do something similar for strings, and styles your XML in the apk would end up looking like this:
<TextView
android:id="#+id/GnvCMa"
android:text="#string/OVuCbd"
style="#style/ZOVkuu.MGTRgZ" />
It is a little time consuming to setup, but once implemented it can be used for other projects.
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.
I am trying to enable push notifications on my application.
I have the client sample code and now i am trying to get some of the code to implement it on my application. For those of you who have already implemented push notifications on your apps i am sure you are familiar with the class GCMIntentService.
So i am copying this class on my project , i configure the Manifest correctly(or i think i do) but i get errors in the file.
The errors are in expressions like R.string."something"
For example I get errors in :
R.string.gcm_registered
R.string.gcm_message
R.string.gcm_deleted
R.string.gcm_error
R.string.gcm_recoverable_error
R.drawable.ic_stat_gcm
The error is always that gcm cannot be resolved or is not a field.
But what exactly is this expression?! Is it a class or something?
Is it something on the Manifest that I haven't configured correctly?
It are strings, probably in the example app you're using, in /res/values/strings.xml
You put strings in there to have a localized place to put your user visible Strings in, so you have
1. One place to find all your strings, if you ever want to change and/or re-use
2. Easy access to translation by putting translations in per example /res/values-de/strings.xml
Look for that file in whatever example you're using, you'll find some XML defined strings. Copy them into your own project, in the same place.
this may helps you ,define all Reuired String in your strings.xml and save
R.string.gcm_registered
R.string.gcm_message
R.string.gcm_deleted
R.string.gcm_error
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.
What are some layout file naming conventions people have come up with.
I haven't found anything online, but thought about using the following convention.
What does everyone think?
- activity_*
- dialog_*
- list_item_*
That's all I have worked with so far.
Also, what about the naming of the activity against its layout? For example:
-> res
-> layout
-> activity_about_us.xml
-> src
-> activity
-> AboutUs.java
Strangely enough, trying to google this question brings only this page as meaningful result...
For the past half year I am using naming convention similar to yours but with shorter prefixes. For example:
For activity that shows "About us" screen:
Class name: ActAboutUs. Prefixing class is kind of overkill but it clearly distinguishes activity classes from the others. Initially I used separate directory for all the activities (similar to your approach) but after some time I realized that for bigger apps may be it is better to group in directories by feature than by superclass (i.e. Activity). It is easier for me to work in single directory for example /src/settings/ when I work on Settings. That way all java files that I need are in a single dir so i don't have to wander around:
/src/settings/ActSettingsGlobal.java
/src/settings/ActSettingsNet.java
/src/settings/Settings.java
/src/settings/SettingsDBAdapter.java
/src/settings/etc...
This approach also helps to split the work among different developers, i.e. each one is working in his own dir on separate feature so no stepping on each other's feet :-).
Some people preffer suffixes but I found them less useful. Prefixes help to group things alphabetically like in the example above: Act* prefix is sorted first so all activities are conveniently at the top.
I am even considering of using Act_ as a prefix which is more readable although it is in conflict with java naming conventions...
Layout filename: act_about_us.xml. In res/layout/ we don't have the "luxury" of subdirs which is quite unfortunate so the only way to group things is using appropriate prefix like act_, dlg_, etc...
String IDs: <string name="act_about_us_dlg_help1_title" ...
string.xml is the place where we have most problems with duplicate names. It is very easy to create duplicates if naming convention like activity_element_item is not used. It adds a lot of additional typing but it saves you from a lot of confusion later on.
For global (application wide) strings we use prefix "global_", for example global_btn_ok, global_msg_no_inet_conn. Usually we make one person responsible for all global_ strings so if someone needs new string or change he needs to sync with him in order to avoid creating a mess.
(now I am realizing that activity__element__item (two underscores) is more clear and readable than activity_element_item)
All in all I still can't get rid of the feeling that there is something wrong with my approach because I can't believe that google devs created such an inconvenient framework when it comes to working with files, IDs, names, etc...
i think following naming convention should be follow
for activity
if our activity name is
DisplayListActivity
then our layoutname should be
display_list_activity.xml
for list items we can include category in list item layout name
country_list_item.xml
and for dialogboxes their action can be included
delete_country_dialog.xml
When looking for a group of layouts, which is how I tend to work on them, I find it effective to always prepend the class name and follow up with any sub-layouts. For Instance:
Class Name: AboutActivity.java
Layout Name: about_activity.xml
Sub-layout Name: about_activity_menu.xml
Sub Sub-layout Name: about_activity_menu_item.xml
Your activity will always be at the top of each grouping and hunting for non-activities becomes less of a chore. Anyone know why sub-folders aren't a thing yet? I expect for efficiency and simplicity on the back-end, but I imagine it wouldn't hurt too much.
This is a good read https://jeroenmols.com/blog/2016/03/07/resourcenaming/
Basically, you follow WHAT WHERE DESCRIPTION SIZE
For example, layout file
activity_main: content view of the MainActivity
fragment_articledetail: view for the ArticleDetailFragment
strings
articledetail_title: title of ArticleDetailFragment
feedback_explanation: feedback explanation in FeedbackFragment
drawable
- all_infoicon_large: large version of generic info icon
- all_infoicon_24dp: 24dp version of generic info icon
The first part of a layout file name should always be the type of the corresponding class.
For example if we have a class MainActivity (type is Activity in this case), the corresponding layout file should be called activity_main.xml
That means that lets say we have a dialog called WarningDialog, the corresponding layout file should be called dialog_warning.xml, same goes for fragments etc.
This might seem familiar because thats also how the activity/layout files are named when creating a new project in Android Studio (MainActivity -> activity_main.xml).
For me, naming should fix two important requirements:
it should give you a hint about files' content and type (for example activity_login/login_activity or movie_list_item/list_item_movie)
it should visually group related items together to minimize jumping back and forth
For the second requirement, most people define "related" as type related which gives you something like this:
activity_login
activity_movie_list
activity_user_list
activity_settings
fragment_movie_list
fragment_user_list
item_movie
item_user
etc.
I prefer to do grouping by feature since you'll almost never work on all activities or all fragments, but instead, you'll work on movies feature or setting feature.
so, my prefered way is this:
login_activity
movie_list_activity
movie_list_fragment
movie_list_item
user_list_activity
user_list_fragment
user_list_item
settings_activity
Source files are following xml naming but in CamelCase, so there will be
LoginActivity
MovieListActivity
MovieFragment
etc.