How prevent apktool sort global variables? - decompiling

Hi first Forgive me for my weak english . i have a class named Class A in my android application with the content below :
public class A {
public static final SomeClass1 variable_C = new SomeClass1();
public static final SomeClass1 variable_A = new SomeClass1();
public static final SomeClass1 variable_D = new SomeClass1();
public static final SomeClass1 variable_B = new SomeClass1();
}
when i compile my project and then give my project apk to apktool to decompile it , apktool decompiles Class A Like below :
public class A {
public static final SomeClass1 variable_A = new SomeClass1();
public static final SomeClass1 variable_B = new SomeClass1();
public static final SomeClass1 variable_C = new SomeClass1();
public static final SomeClass1 variable_D = new SomeClass1();
}
apktool when decompile my project apk changes global variables ordering to alphabetical order .
How can i force apktool does not sort global variables in alphabetical order and keep main global variables ordering when decompile my apk ?
thanks for your answers .

This is not apktool's fault. Unlike the Java classfile format, the Android dex format requires that fields appear in sorted order, which means that the source level ordering is lost as soon as you compile your code.
From https://source.android.com/devices/tech/dalvik/dex-format#class-data-item
the defined static fields, represented as a sequence of encoded elements. The fields must be sorted by field_idx in increasing order.
field identifiers list. These are identifiers for all fields referred to by this file, whether defined in the file or not. This list must be sorted, where the defining type (by type_id index) is the major order, field name (by string_id index) is the intermediate order, and type (by type_id index) is the minor order. The list must not contain any duplicate entries.

Related

IntelliJ Live Template for dart named constructor: lists class' fields

I want to generate a custom named constructor in Dart.
I have many dto class to implement and each should provide a named constructor like: ClassName.fromMap().
For example for this class:
class Student {
final String name;
final int age;
}
The generated constructor should be:
Student.fromMap(Map<String, dynamic> map) :
name = map['name'],
age = map['age'];
How can I retrieve the list of the field of my current class as strings? Is that even possibile?
Of course I can have a variable number of fields.
My template looks like:
$CLASS$.fromMap(Map<String, dynamic> map) :
$INITIALIZATION_LIST$
binding $CLASS$ to dartClassName().
Now I'd like to bind $INITIALIZATION_LIST$ to something like:
getClassFieldList().forEach((fieldName) => "$fieldName = map['$fieldName']")
Can I achieve something like that?
There is no way to retrieve a list of Dart class fields using predefined live template functions. You can try developing your own template macro for this. See https://intellij-support.jetbrains.com/hc/en-us/community/posts/206201699-create-a-new-expression-for-a-live-template-for-actionscript for some hints.
Existing live template functions implementations can be found at https://github.com/JetBrains/intellij-community/tree/master/platform/lang-impl/src/com/intellij/codeInsight/template/macro.
You can also try using Structural Search and Replace instead of live template

Android Studio code error

the app was bulding fine, until I added some new layouts and when I run it this error shows within the line of codes
enter code
here public static final class id {
public static final int Nexus 5 (5_0")=0x7f070001;
public static final int dummy_button=0x7f070003;
public static final int fullscreen_content=0x7f070000;
public static final int fullscreen_content_controls=0x7f070002;
public static final int switch2=0x7f070004;
in second line: public static final int Nexus 5 (5_0")=0x7f070001;
it underlines it red from Nexus 5 (5_0")=0x7f070001; till the end of that line. what did I do wrong?
Your problem is that Nexus 5 (5_0") is not a valid identifier for a Java variables. You cannot have spaces, for example, in the names. When you declared the new layouts with the new ids, Android Studio automatically took the ID names and created the Java equivalents. The rest of your variables have a valid name and follow the naming convention for resource ids.
Try renaming the ID (in the layout file) to something similar to nexus_5.

Java - Adding List<String> from parameter to existing list

I want to be able to add new entries of parameter inputs to the list.
For example:
public static void theList (List<String> wholeList) {
wholeList = new ArrayList<String>();
wholeList.add("Lettuce");
wholeList.add("Bacon");
wholeList.add("Milk");
wholeList.add(wholeList); <--------- error - addAll doesn't fix it.
Above I tried ' wholeList.add(wholeList) '. What I intended to do is: Whatever additional (item (from parameter), when adding the input to run this method) item I need to add, will be added to the ' wholeList '.
As you can see, I have 3 items added to the list: Lettuce, Bacon and Milk. However, if I suddenly changed my mind, and want to add another item (via parameter), I can simply add it to the current list (wholeList).
Also, another question.
Is there a neater way to add a list of items instead of adding it one-by-one (whilst using the same list import)? Say, {"Lettuce", "Milk", "Bacon", etc}?
TY.
As I understand, addAll() is everything you need:
List<String> someList = new ArrayList<String>();
List<String> itemsToAdd = new ArrayList<String>();
itemsToAdd.add("one");
itemsToAdd.add("two");
someList.addAll(itemsToAdd);
// or use handy method which creates temporary list internally:
someList.addAll(Arrays.asList("three", "four"));
Well, your code does something very wrong.
You initialize the wholeList inside the method, and after the method is finished, it is gone (pointers in Java).
Also, you added the list on itself, so the code is probably not what you wanted to do.
you probably meant to create a new list inside the method and add all the items to the list in the parameter.
If so, you shouldn't use "new" on the list that you got from a parameter.
Actually, after reading the title of your question -
You need an existing list - it can't be with the name of the list in the parameter. Let's call it existingList.
After you get the list in the method, you shouldn't use the "new ArralyList" on it, as it will void the list from the parameter.
Your code should look like that:
public static void theList (List<String> wholeList) {
wholeList.add("Lettuce");
wholeList.add("Bacon");
wholeList.add("Milk");
existingList.add(wholeList);
The only "cleaner" way of adding the values to the list would be:
wholelist.addAll(Arrays.asList("Lettuce", "Bacon", "Milk"));
But I see the Top answer already states that. So, you could clean it up more by creating a array as a global private variable outside of the method. Also, as another answer said, you should have another seperate list that does not share the same name as the parameter list. Here is an example with libaries needed:
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
public class Example{
private List<String> globalList = new ArrayList<>();
private String[] list = {"Bacon", "Lettuce", "Milk"};
public static void theList (List<String> wholelist) {
wholelist.addAll(Arrays.asList(list));
globalList.addAll(wholeList);
}
If you wanted to use wholeList as the name for both lists, then you could change globalList above to wholelist, then:
public static void theList (List<String> wholelist) {
this.wholelist.AddAll(wholelist);
this.wholelist.addAll(Arrays.asList(list));
}
But I would avoid doing that.

How can I make #XmlAttribute in a special order by using JAXB?

I have XML file which needs 3 attributes in an element. How can make the order of street, zip and city attribute as I wanted?
<address street="Big Street" zip="2012" city="Austin">
</address>
#XmlType(name="Street)
#XmlRootElement(name = "Street")
public class Street {
#XmlAttribute
private String name;
#XmlAttribute
private String type;
... set and get method
}
Anecdotally, the attributes seem to be in reverse order than they are mentioned in code. In my case, I'm using two variables (name & value) and I had to declare them as:
// The inverse order of name & value seems to make them render in XML in name/value order
#XmlAttribute
protected String value;
#XmlAttribute
protected String name;
When the XML is generated, it results in the following:
<attribute name="nameValue" value="valueValue"/>
You can use #XmlAccessorOrder(has predefined values) or #XmlType(Only works for properties) to govern the ordering.
Samples
Edit :
For custom ordering JAXB specification doesnt provide anything, but you can do if your JAXB provider provides you some features.
Found this link where it speaks about ordering using EclipseLink JAXB.

Can Automapper map from a Dictionary of properties to a flat destination?

Source contains a property bag in a Dictionary. Can Automapper map the entries in the Dictionary to individual properties of the Destination based upon matching the dictionary keys with the names of the properties on the destination type?
Example:
public class Destination
{
public int ProdNumber;
public string Title;
}
public class Source
{
public Dictionary<string, object> values = new Dictionary<string, object>();
}
where the values Dictionary will have two entries, one with a key of "ProdNumber" and one with a key value of "Title". There will likely be entries in the dictionary that have keys that don't match any property in the Destination and they should be ignored. There will be multiple properties of each primitive data type (int, string, etc) - so I presume I can't use a simple set of TypeConverters.
Any suggestions?
Thanks,
Chris
Unfortunately it is not possible at the moment, but it is planned for the next version. Read this thread as it discusses the plans and a work around.

Resources