I mean, imports generally don't effect code unless you use something that is unknown in the current file without giving the full qualified identifier, but this one seems weird to me. It's in a few files and is generally unused.
Can "import org.parceler.Generated" be removed savely? Is there any reason to keep it?
The part that stumps me is the word "Generated" here. It seems like this has to be or atleast should be kept, but I don't know why.
I suppose it's autoincluded when using some autogeneration tool, potentially even build into android-studio. But why is the "import org.parceler.Generated" line generated if the import is unused ?
If you're using Parceler, then it should be generating classes that look like the following:
#Generated(value = "org.parceler.ParcelAnnotationProcessor", date = "2016-09-03T09:53-0600")
#SuppressWarnings({
"unchecked",
"deprecation"
})
public class ParcelerTestModel$$Parcelable
implements Parcelable, ParcelWrapper<org.parceler.test.ParcelerTestModel>
{
...
Notice the #Generated annotation. This requires the import you mentioned if the generated class it outside of the org.parceler package.
The #Generated annotation doesn't do much here. The intention behind this annotation is to demarcate generated code from user written code, following the JSR269 standard.
If you're taking the generated code out of the purview of the annotation processor and managing it yourself then you're free to remove this annotation. I wouldn't recommend this approach, however, as it's simply more boilerplate to manage which defeats the purpose of using a boilerplate-reducing solution like Parceler.
Related
In this Q&A, it says there's no difference. And some people says annotation is better or using constructor(mockk<*>()) is better.
For me, if they are equivalent, less line of code(not using annotation) is better.
Many sample code shows #MockK is used for the values that pass to Class such as ViewModel/Activity or Fragment. On the other hand, mockk<*>() is used for the classes that have its behaviour or data class, etc
There must be some differences since one is annotation and the other is using constructor. And there must be some reasons why each of them are created, not only one of them.
If you know this, could you please answer it?
I am using Android LintFix (see slide 119 or code examples) and I have managed to do fixes for the function, however it does not seem to be possible to add imports like Kotlin #Deprecated annotation. Is it possible to do somehow or should I rely on the IDE for auto-import?
Thanks to Mark Prengemann who indicated me the solution:
Using fully qualified names with reformat(true) and shortenNames():
LintFix.create().replace()
.text("<original>").with("<correction with fully qualified entities>")
.shortenNames()
.reformat(true)
.build()
I'm creating a new module in android studio, and I want some of the classes to be hidden to outside of the module, I mean, that the classes could just be used internally in the module, but not externally. Is it possible? How could I achieve that?
Thanks in advance!
EDIT: I doubt it's possible to have module-visibility, but the closest you can use is package-visibility, for which you do the following:
Don't make the classes you intend to hide 'public'. Keep the default visibility, which is only seen within classes of the same package. Other public classes within this same package can act as your external interface to your module.
class PrivateToPackageInModule {
}
public class InterfaceOfModule {
private PrivateToPackageInModule ptpim;
}
For anyone that happens to stumble upon this post, there is now a keyword called internal which offers exactly the functionality that OP was looking for.
Documentation link
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 want to make a small change to the Android standard TimePicker class. Specifically, I'm trying to change it so it works in 15 minute increments, rather than 1 minute increments.
This post helped me constrain the range of minute values to {0, 15, 30, 45}, as required in my app. But as I pointed out in a follow up comment, the minute spinner still shows previous minute as current value - 1, and the next minute as current value + 1, which creates a sloppy-feeling user interface.
I looked into the relevant Android source code, and it appears that the changes I would need to make are pretty simple. But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration, where to find Widget, how to resolve R.id variables, etc.
So my question is:
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
In my case, I just need to make a few small changes to TimePicker and NumberPicker, but I'm not sure how to properly set this up in my project.
Thanks for any suggestions.
But when I tried copying the source code into my project I got about a zillion errors relating to the package declaration
Your source file's directory needs to match the package name. And since you cannot overwrite android.widget.TimePicker, you will either need to move that class to a new package or give it a new name.
where to find Widget
That implies that you copied TimePicker into one of your packages. That is fine, but then you need to add in the appropriate import statements for classes that TimePicker referred to from its original package. Or, you need to keep your (renamed) TimePicker in android.widget, adding this package to your project. This is rudimentary Java.
how to resolve R.id variables
If TimePicker relies upon resources that are not part of the Android SDK, you will need to copy those resources from the AOSP into your project as well.
What's the best way to make a small change to a given class from Android source code, and incorporate it into your own project?
IMHO, that cannot be answered readily in the abstract. Generally speaking, you do the sorts of things that I listed above.
You are best off subclassing the relevant classes and overriding the methods you would like to change.
In Java, you can do the following in a subclass:
The inherited fields can be used directly, just like any other
fields.
You can declare a field in the subclass with the same name as
the one in the superclass, thus hiding it (not recommended).
You can
declare new fields in the subclass that are not in the superclass.
The inherited methods can be used directly as they are.
You can write a new instance method in the subclass that has the same signature as the one in the superclass, thus overriding it.
You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
You can declare new methods in the subclass that are not in the superclass.
You can write a subclass constructor that invokes the constructor of the superclass, either implicitly or by using the keyword super.
More info on subclassing in Java