2015-10-09 10 views
10

ich mit diesem Code etwas ernstes Problem hat, von svg-android:Android 6.0 (Eibisch) statische Initialisierung Ausnahme auf getDeclaredField()

public class ParserHelper { 

private static final Field STRING_CHARS; 
static { 
    try { 
     STRING_CHARS = String.class.getDeclaredField("value"); //<-- exception here 
     STRING_CHARS.setAccessible(true); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
} 

private final char[] s; 
private final int n; 
private char current; 
public int pos; 

public ParserHelper(String str, int pos) { 
    try { 
     this.s = (char[]) STRING_CHARS.get(str); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 
    this.pos = pos; 
    n = s.length; 
    current = s[pos]; 
} 

die STRING_CHARS = String.class.getDeclaredField("value"); führt den excpetion

10-09 10: 25: 58.240: E/AndroidRuntime (3430): Verursacht von: java.lang.RuntimeException: java.lang.NoSuchFieldException: Kein Feld Wert in Klasse Ljava/lang/String; (Erklärung von 'java.lang.String' erscheint in /system/framework/core-libart.jar)

ich den Job nicht weitergehen kann. Nur in Android 6.0 Marshmallow. Irgendeine Idee?

GELÖST: Nun, ich die statische Initialisierung Problem nicht gelöst hat, aber ich änderte die char[] s Initialisierung:

public class ParserHelper { 

// private static final Field STRING_CHARS; 
// static { 
//  try { 
//   STRING_CHARS = String.class.getDeclaredField("value"); 
//   STRING_CHARS.setAccessible(true); 
//  } catch (Exception e) { 
//   throw new RuntimeException(e); 
//  } 
// } 

    private final char[] s; 
    private final int n; 
    private char current; 
    public int pos; 

    public ParserHelper(String str, int pos) { 
     try { 
      s = new char[str.length()]; 
      str.getChars(0, str.length(), this.s, 0); //<-- here 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
     this.pos = pos; 
     n = s.length; 
     current = s[pos]; 
    } 
+0

Sie müssen nicht eine String-Instanz verwenden, um eine Reflektion durchzuführen? kein Experte dafür. – Nanoc

+0

@Nanoc ich keine ... –

+0

Dann versuchen Sie es stattdessen und sagen Sie mir "neue Zeichenfolge (" Hallo "). Class.getDeclaredField (" Wert ");" – Nanoc

Antwort

12

wie die String Sieht ‚s privaten Bereich value genannt, die das Array von Zeichen hält war im Marshmallow in ASCII umbenannt. So haben Sie eine RuntimeException in diesen Zeilen (von der com.larvalabs.svgandroid.ParserHelper Klasse übernommen):

try { 
     STRING_CHARS = String.class.getDeclaredField("value"); 
     STRING_CHARS.setAccessible(true); 
    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

Die svgandroid ist discontinued, so gibt es kaum eine Chance, dass der Autor des Projekts wird dieses Problem beheben und die neue Glas zu maven.You drücken können Sie Ihre eigene Gabel von Svgandroid-Bibliothek machen, this pull-request verschmelzen, das Glas bauen und es von nun an anstelle der mavenized Version verwenden.

Oder Sie können ein wenig weiter gehen, und drücken Sie die feste Version zu mvnrepository selbst. :)

+1

Oh Liebes ... Wenn jemand eine Reparatur für diese Bibliothek machen würde, wäre es großartig. Ich denke, viele Leute benutzen es, und jetzt stürzen all ihre Apps auf Marshmallow. – Deinlandel

+0

Obwohl Ihre Antwort es beheben, frage ich mich, ob es irgendwelche Auswirkungen auf die Leistung haben wird. Ich denke, dass es so gemacht wurde, um effizienter zu sein, da die neuen Methoden eine Kopie erzeugen und durch Reflexion direkt darauf zugreift. –

Verwandte Themen