What is the one line max length limit in XML files? - android

Recently I've faced an issue related to max line (string) length limit in a path attribute of vector xml. In my case 51k chars appears to be an overlimit while 29k is OK. Anyway, I guess it is not related to some specific kind of xml like manifest, string, style, attr, drawable, layout or any other, I'm sure it is a general limitation for any xml in Android project.
So I'm curious what is the limit (I mean an exact max number of chars allowed for one line in Android xml) and why its not being applied by AndroidStudio at vector importing time? It looks like Google does not know about this limit itself or maybe its a limitation of a gradle.
Please do not point me that long strings are bad - I do realize it and it does not cancel my question.
Guys, please read my question and other SO questions you might think are the dupes carefully! There is no answer to my question there.
Android strings.xml length SO question has absolutely other meaning. Asker asks if there is a way to get the count of strings in strings.xml. Besides that, my question is not related to strings.xml exactly but to any xml file at all.
Android IndexOutOfBound Exception for resource getString is about absolutely another exception/issue and gives absolutely NO answer on my question. Again, my question is not related to strings.xml at all.
What is the maximum amount of data that a String can hold in java? is not what I am asking about, its about Java String class limitation. Even if its related then the limit is about Integer.MAX/2(cuz for Unicode it takes 2 bytes to encode 1 char) so its not 51k chars in any way.

My guess reading your question was that the limit would be somewhere between 29k and 51k but clipped to a logical number
I might have found the answer by testing it.
As you said, a char is stored on two bytes. So 29k char would be 58k bytes and 51k would be 102k bytes.
The "logical" limit would be 65536 as it is 2^16. so the limit in char is 2^16 / 2 or 2^15 which is 32768
I tested to put strings in my string.xml (basically a long line of 'a')
<string name="length_test32000">(32 000 a)</string>
<string name="length_test32767">(32 767 a)</string>
<string name="length_test32768">(32 768 a)</string>
<string name="length_test32769">(32 769 a)</string>
<string name="length_test33000">(33 000 a)</string>
Then i tried to log their size :
String test32k = getString(R.string.length_test32000);
String test32k767 = getString(R.string.length_test32767);
String test32k768 = getString(R.string.length_test32768);
String test32k769 = getString(R.string.length_test32769);
String test33k = getString(R.string.length_test33000);
Log.i("tag", "32000 : "+test32k.length());
Log.i("tag", "32767 : "+test32k767.length());
Log.i("tag", "32768 : "+test32k768.length());
Log.i("tag", "32769 : "+test32k769.length());
Log.i("tag", "33000 : "+test33k.length());
Here are the results :
I/tag: 32000 : 32000
I/tag: 32767 : 32767
I/tag: 32768 : 16
I/tag: 32769 : 16
I/tag: 33000 : 16
From 32768 it seems to be truncated so i log what was inside
Log.i("tag", "32768 : "+test32k768.length() + " content : " + test32k768);
And the result is :
I/tag: 32768 : 16 content : STRING_TOO_LARGE
The maximum char seems to be 32767 (2^15 - 1) characters. I didn't find any official doc that say that, but it is what i found while testing

Related

android Regex issue

I had an issue with this regex:
(\{(([^\p{Space}][^\p{Punct}])+)\})
The problem is in number of chars. If I typing even number of chars it's works, when odd - not. I was trying to replace '+' with '?' or '*', but result still the same. How can I fix this?
I expect from this regex to block such strings: {%,$ #fd}. And allow this:
{F} or {F242fFSf23}.
Currently, it matches a {, then 1 or more repetitions of 2 chars, a non-space and then a non-punctuation, and then a }, hence you cannot use 1 char in between {...}.
To fix that, you need to use both the character classes inside bracket expression:
\{[^\p{Punct}\p{Space}]+\}
or
\{[^\p{P}\p{S}\s]+\}
Details
\{ - a { char
[^\p{Punct}\p{Space}]+ - 1 or more repetitons (+) of any char that does not belong to the \p{Punct} (punctuation) or \p{Space} (whitespace) class.
\} - a }.
Note that if the contents between the braces can only include ASCII letters or digits (in regex, [A-Za-z0-9]+), you may even use a mere
\{[A-Za-z0-9]+\}
Disassembling your regex... the reason why it only accepts an even number in between is the following part:
([^\p{Space}][^\p{Punct}])+
This basically means: something which isn't a space, exactly 1 character and something which isn't a ~punct, exactly 1 character and this several times... so exactly 1 + exactly another 1 are exactly 2 characters... and this several times will always be even.
So what you probably rather want is the following:
[^\p{Space}\p{Punct}]+
for the part shown above... which will result in the following for your complete regex:
\{[^\p{Space}\p{Punct}]+}
that of course can be simplified even more. I leave that up to you.

Substring contains extra integers

I have a problem with substring
When i extract a character from a string it contains some extra integer with the result...
Can anyone help me why this happening?
here is my code
mySrtring ="12456+" Char temp1 = myString.charAt(myString.length()-1);
it produce temp1='+' 443
I assume you're saying this "43" in the debugger. It is correct. All magics inside the computer are nothing more than numbers. Those great minds once assigned certain numbers to represent certain characters, such as 65 for 'A' and 97 for 'a'. And 43 stands for '+', that's all. This kind of number-to-character mapping is called ASCII (American Standard Code for Information Interchange). And the modern IDE displays those numbers behind the character only for debugging convenience.
So, '+' is 43 (in decimal), and 43 (in decimal) can be '+' when you treat it as a character.
Furthermore, you can do something like temp1 + 2 in C language and then it will give you 45, which is '-' in ASCII.

How to remove hyphen from TextUtils.split(line, "-")?

I found a dictionary sample in GitHub that I am currently experimenting with. The sample database used hyphen between the searched word and the word's meaning. So something like this.
abbey - n. a monastery ruled by an abbot
I looked into the dictionary database java file and found the following code:
String[] strings = TextUtils.split(line, "-");
I have my own database that translates Korean words to English. However I didn't use hyphen while creating it. So is there a way to not use hyphen or any other symbols but simply spaces? Also this is part of an android app.
Edit- An example of my own dictionary would be something like
abbey a monastery ruled by an abbot
Edit-
The problem here is that the old code only differentiates and recognizes the words and the meaning only if they are separated by hyphen. How do I make this so it works with spaces alone.
To remove a character in a String use String.replace
String newString = line.replace("-","");
To replace with a space simply use
String newString = line.replace("-"," ");
String mystring = mystring 1.replace("_"," "); if you want space give space.
As I understand it, you want to split your String to get the output like
abbey - n. a monastery ruled by an abbot
[abbey][n. a monastery ruled by an abbot]
You can use String.split(String, int) to force the number of split.
The limit parameter controls the number of times the pattern is applied and therefore affects the length of the resulting array. If the limit n is greater than zero then the pattern will be applied at most n - 1 times
Let's use it like :
String[] array = s.split(" ", 2);
This will split your String on the regex " " but will limit the size of the output to 2 cells. So it will only split once, put the left part on the first cell and the right part on the second cell.
Without this limit argument, the method would keep split the right part again using a bigger array.
Note: this will be a problem if your word is a sentence in the left part.

single line alignment in textview [duplicate]

I have a very weird problem. After writing this:
for (File f : currentFile.listFiles()) {
if (f.isDirectory()){
System.out.println(f.getName()+"\t"+"Dir\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
else{
System.out.println(f.getName()+"\t"+"File\t"+Command.getpremission(f)+"\t"+f.getTotalSpace());
}
I see this printed:
see.txt File rw 267642728448
see1.txt File rw 267642728456
see2.txt File rw 267642728448
Why is there a problem with the tabs?
Building on this question, I use the following code to indent my messages:
String prefix1 = "short text:";
String prefix2 = "looooooooooooooong text:";
String msg = "indented";
/*
* The second string begins after 40 characters. The dash means that the
* first string is left-justified.
*/
String format = "%-40s%s%n";
System.out.printf(format, prefix1, msg);
System.out.printf(format, prefix2, msg);
This is the output:
short text: indented
looooooooooooooong text: indented
This is documented in section "Flag characters" in man 3 printf.
The "problem" with the tabs is that they indent the text to fixed tab positions, typically multiples of 4 or 8 characters (depending on the console or editor displaying them). Your first filename is 7 chars, so the next tab stop after its end is at position 8. Your subsequent filenames however are 8 chars long, so the next tab stop is at position 12.
If you want to ensure that columns get nicely indented at the same position, you need to take into account the actual length of previous columns, and either modify the number of following tabs, or pad with the required number of spaces instead. The latter can be achieved using e.g. System.out.printf with an appropriate format specification (e.g. "%1$13s" specifies a minimum width of 13 characters for displaying the first argument as a string).
The length of the text that you are providing in each line is different, this is the problem, so if the second word is too long (see2.txt is long 8 char which corresponds to a single tab lenght) it prints out a tab which goes to the next tabulation point.
One way to solve it is to programmatically add a pad to the f.getName() text so each text generated: see.txt or see2.txt has the same lenght (for example see.txt_ and see2.txt) so each tab automatically goes to the same tabulation point.
If you are developing with JDK 1.5 you can solve this using java.util.Formatter:
String format = "%-20s %5d\n";
System.out.format(format, "test", 1);
System.out.format(format, "test2", 20);
System.out.format(format, "test3", 5000);
this example will give you this print:
test 1
test2 20
test3 5000
In continuation of the comments by Péter and duncan, I normally use a quick padding method, something like -
public String rpad(String inStr, int finalLength)
{
return (inStr + " " // typically a sufficient length spaces string.
).substring(0, finalLength);
}
similarly you can have a lpad() as well
As mentioned by other folks, the variable length of the string is the issue.
Rather than reinventing the wheel, Apache Commons has a nice, clean solution for this in StringUtils.
StringUtils.rightPad("String to extend",100); //100 is the length you want to pad out to.
The problem is the length of the filenames. The first filename is only 7 chars long, so the tab occurs at char 8 (doing a tab after every 4 characters). However the next filenames are 8 chars long, so the next tab won't be until char 12. And if you had filenames longer than 11 chars, you'd run into the same problem again.
You can use this example to handle your problem:
System.out.printf( "%-15s %15s %n", "name", "lastname");
System.out.printf( "%-15s %15s %n", "Bill", "Smith");
You can play with the "%" until you find the right alignment to satisfy your needs
You can also pad a string to the required length using Guava's Strings.padEnd(String input, int minLength, char padding)

android resource string %

now I encounter a doubt about % in android string resource. The question as follow:
If I want to use % symbol in other language, such as in chinese. I must add resource string formatted="false" in /values-zh-rCN/strings.xml.
Yes, the string tag must have ther formatted attribute.
However, it could not add this formatted attribute in /values/strings.xml in english language. it compile successfully, and work well.
Why?
I can't find any answer in android developer website.
ps: how i write Angle brackets in stackoverflow editor. I'm a freshman.
Java code:
autoDownloadLayout.findViewById(R.id.setItemContent)).setText(R.string.setting_auto_update_title_1_subtitle);
/values/strings.xml :
<string name="setting_auto_update_title_1_subtitle">Automatically download updates when connected to Wi-Fi, when the battery level is greater than 30% and CPU usage is less than 50%</string>
/values-zh-rCN/strings.xml :
<string formatted="false" name="setting_auto_update_title_1_subtitle">"仅在 WLAN 网络,手机电量高于 30% 且 CPU 占用率低于 50% 时,预先下载游戏更新包"</string>
It seems that Android Lint has different ideas when checking translated strings as compared to default strings. There's an open issue (Issue 74959) about this (although it's not exactly your problem). It would seem that technically you should be adding formatted="false" to the strings in /values as well as to those in /values-zh-rCN.
Alternatively, you could encode all literal percent signs as % (or %). That might be the simplest (and least risky) approach.

Categories

Resources