Android ICS 4.0 NDK NewStringUTF stürzt die App ab

8
___ qstnhdr ___ Android ICS 4.0 NDK NewStringUTF stürzt die App ab ___ answer17462492 ___

Ich hatte dieses Problem, wenn ich die Datei Application.mk

ändere

Aus dieser Zeile:

%Vor%

An:

%Vor%

Sobald ich es wieder zurücksetzte, behob es das Problem.

    
___ answer34218851 ___

So habe ich das gemacht.

1- Char Array zu JByteArray.

2- JByteArray zu JString.

3- Geben Sie jstring an die Java-Seite zurück.

JNI-Code; (.c) format

%Vor%

Java-Code;

%Vor%

Andere Vorgehensweise funktioniert nicht für mich;

Ich habe auch versucht, %code% , aber einige Zeichen, die nicht im Char-Array, am Ende der Zeichenfolge, wo mit der Warnung JNI WARNUNG: Eingabe ist nicht gültig Modified UTF-8: illegale Fortsetzung Byte 0x40 .

Beispiel; PKdhtXMm18n2L9K DL- DL

Bearbeiten:

C ++ Version

%Vor%     
___ answer46230253 ___

Für mich bestand die Lösung darin, den Inhalt auf ein const char * zu setzen:

%Vor%

und die Funktion:

%Vor%     
___ answer12134423 ___

Zeichenfolgen, die Sie an NewStringUTF () übergeben, müssen gültig sein UTF-8 . Es sieht so aus, als ob die von Ihrer Funktion start_Inauthroot () zurückgegebene Zeichenfolge in einer anderen Codierung enthalten ist oder nur eine ungültige Zeichenfolge zurückgibt. Sie müssen die Zeichenfolge in UTF-8 konvertieren, bevor Sie sie an JNI-Funktionen übergeben. Oder Sie können einen der Zeichensatz-bewusste String-Konstruktoren , um stattdessen das String-Objekt zu erstellen.

    
___ answer19779053 ___

Das funktioniert für mich in C ++

%Vor%     
___ tag123android ___ Android ist das mobile Betriebssystem von Google, das zum Programmieren oder Entwickeln von digitalen Geräten (Smartphones, Tablets, Automobile, Fernseher, Wear, Glass, IoT) verwendet wird. Verwenden Sie für Themen rund um Android Android-spezifische Tags wie android-intent, nicht intent, android-activity, nicht activity, android-adapter, nicht adapter usw. Bei anderen Fragen als der Entwicklung oder Programmierung, aber im Zusammenhang mit Android Framework, verwenden Sie Der Link: https://android.stackexchange.com. ___ tag123androidndk ___ Das Android Native Development Kit (NDK) ist ein begleitendes Tool zum Android-SDK, mit dem Sie performance-kritische Teile Ihrer Apps in nativem Code erstellen oder vorhandene Bibliotheken in C / C ++ an Android portieren können. Es bietet Header und Bibliotheken, mit denen Sie Aktivitäten erstellen, Benutzereingaben verarbeiten, Hardwaresensoren verwenden, auf Anwendungsressourcen zugreifen und vieles mehr, wenn Sie in C / C ++ programmieren. ___ answer45819651 ___

Meiner Meinung nach ist es kein Fehler.

NewStringUTF Konstruiert ein neues java.lang.String-Objekt aus einem Array von Zeichen in der modifizierten UTF-8 -Codierung.

Modifiziertes UTF-8 ist kein Standard-UTF-8. Siehe Modified UTF-8

In den meisten Fällen ist die UTF-8-codierte Zeichenfolge gültig Modified UTF-8. Weil Modified UTF-8 und UTF-8 sehr ähnlich sind. Wenn es jedoch zu einer Unicode-Zeichenfolge außerhalb der Basic Multilingual Plane kommt, sind sie nicht kompatibel.

Lösung: Übergeben Sie UTF-8-Bytes an die Java-Ebene und die neue Zeichenfolge (Bytes, "UTF-8") und übergeben Sie dann jstring an JNI.

    
___ tag123jni ___ Das Java Native Interface (JNI) bietet JVM-Implementierungen die Möglichkeit, systemeigenen Code auszuführen, und nativen Code kann Java-Code ausführen (indem neue JVM-Instanzen erstellt werden). Die gebräuchlichsten Zielsprachen für JNI sind C und C ++, für die zumindest die Sun / Oracle JDK-Implementierungen Hilfsbefehle (javap, javah) bereitstellen. ___ tag123androidndkr7 ___ Mit dem Native Development Kit von Android können Benutzer C / C ++ - Code von ihren Anwendungen aufrufen, die in der Dalvik Virtual Machine ausgeführt werden. Verwenden Sie dieses Tag nur für Fragen, die sich speziell auf Version 7 des Android Native Development Kit beziehen. Andernfalls verwenden Sie [tag: android-ndk] und stellen Sie sicher, dass Sie das trotzdem hinzufügen. ___ answer26522748 ___

Die Ursache dieses Problems steht in direktem Zusammenhang mit einem bekannten UTF- 8 Fehler in der NDK / JNI GetStringUTFChars () Funktion (und wahrscheinlich verwandte Funktionen wie NewStringUTF). Diese NDK-Funktionen konvertieren keine zusätzlichen Unicode-Zeichen (dh Unicode-Zeichen mit einem Wert von U + 10000 und oben) richtig. Dies führt zu falschem UTF-8 und nachfolgenden Abstürzen.

Ich habe den Absturz bei der Verarbeitung von Text mit Emoticon-Zeichen festgestellt ( siehe das entsprechende Unicode-Diagramm ) ). Emoticon-Zeichen liegen im Unicode-Zeichenbereich.

Analyse des Problems

  1. Der Java-Client übergibt einen String mit einem zusätzlichen Unicode Zeichen nach JNI / NDK.
  2. JNI verwendet die NDK-Funktion GetStringUTFChars (), um den Inhalt der Java-Zeichenfolge zu extrahieren.
  3. GetStringUTFChars () gibt die Zeichenfolgendaten als falsches und ungültiges UTF-8 zurück.

Es gibt einen bekannten NDK-Fehler , wobei GetStringUTFChars ( ) konvertiert zusätzliche Unicode-Zeichen falsch und erzeugt eine falsche und ungültige UTF-8-Sequenz.

In meinem Fall war die resultierende Zeichenfolge ein JSON-Puffer. Wenn der Puffer an den JSON-Parser übergeben wurde, ist der Parser sofort fehlgeschlagen, weil eines der UTF-8-Zeichen des extrahierten UTF-8 ein ungültiges UTF-8-Präfix-Byte hatte.

Mögliche Abhilfe

Die Lösung, die ich verwendet habe, kann wie folgt zusammengefasst werden:

  1. Das Ziel besteht darin, zu verhindern, dass GetStringUTFChars () das ausführt falsche UTF-8-Codierung des zusätzlichen Unicode-Zeichens.
  2. Dies erfolgt durch den Java-Client, der die Anforderungszeichenfolge als codiert Base64.
  3. Die Base64-codierte Anfrage wird an JNI übergeben.
  4. JNI ruft GetStringUTFChars () auf, das das Base64-encoded extrahiert string ohne UTF-8-Codierung durchzuführen.
  5. Der JNI-Code decodiert dann die Base-64-Daten und erzeugt das Original UTF-16 (wide char) Anforderungszeichenfolge, einschließlich der Zusatzzeichenfolge Unicode-Zeichen.

Auf diese Weise umgehen wir das Problem, zusätzliche Unicode-Zeichen aus der Java-Zeichenkette zu extrahieren. Stattdessen konvertieren wir die Daten vor dem Aufruf von GetStringUTFChars () in Base-64 ASCII, extrahieren die Base-64-ASCII-Zeichen mithilfe von GetStringUTFChars () und konvertieren die Base-64-Daten zurück in Wide-Zeichen.

    
___ tag123android40 ___ Android 4.0 (Codename Ice Cream Sandwich) ist API-Stufe 14 des von Google entwickelten mobilen Betriebssystems. Diese Version bietet eine verfeinerte, einheitliche Benutzeroberfläche für Smartphones und Tablets und führt innovative Funktionen für Benutzer und Entwickler ein. ___ answer12270249 ___

Ich habe dieses Problem gelöst, indem ich ein Byte-Array anstelle von String zurückgegeben habe. Auf der Java-Seite konvertiere ich jetzt das Byte-Array in Strings. Funktioniert gut! Vermeiden Sie die Verwendung von NewStringUTF () für Android 4.0 und höher, da bereits ein Fehler auf Google Android NDK gemeldet wurde.

    
___
rana 26.08.2012, 05:24
quelle

8 Antworten

9

Ich habe dieses Problem gelöst, indem ich ein Byte-Array anstelle von String zurückgegeben habe. Auf der Java-Seite konvertiere ich jetzt das Byte-Array in Strings. Funktioniert gut! Vermeiden Sie die Verwendung von NewStringUTF () für Android 4.0 und höher, da bereits ein Fehler auf Google Android NDK gemeldet wurde.

    
rana 04.09.2012, 19:40
quelle
15

Die Ursache dieses Problems steht in direktem Zusammenhang mit einem bekannten UTF- 8 Fehler in der NDK / JNI GetStringUTFChars () Funktion (und wahrscheinlich verwandte Funktionen wie NewStringUTF). Diese NDK-Funktionen konvertieren keine zusätzlichen Unicode-Zeichen (dh Unicode-Zeichen mit einem Wert von U + 10000 und oben) richtig. Dies führt zu falschem UTF-8 und nachfolgenden Abstürzen.

Ich habe den Absturz bei der Verarbeitung von Text mit Emoticon-Zeichen festgestellt ( siehe das entsprechende Unicode-Diagramm ) ). Emoticon-Zeichen liegen im Unicode-Zeichenbereich.

Analyse des Problems

  1. Der Java-Client übergibt einen String mit einem zusätzlichen Unicode Zeichen nach JNI / NDK.
  2. JNI verwendet die NDK-Funktion GetStringUTFChars (), um den Inhalt der Java-Zeichenfolge zu extrahieren.
  3. GetStringUTFChars () gibt die Zeichenfolgendaten als falsches und ungültiges UTF-8 zurück.

Es gibt einen bekannten NDK-Fehler , wobei GetStringUTFChars ( ) konvertiert zusätzliche Unicode-Zeichen falsch und erzeugt eine falsche und ungültige UTF-8-Sequenz.

In meinem Fall war die resultierende Zeichenfolge ein JSON-Puffer. Wenn der Puffer an den JSON-Parser übergeben wurde, ist der Parser sofort fehlgeschlagen, weil eines der UTF-8-Zeichen des extrahierten UTF-8 ein ungültiges UTF-8-Präfix-Byte hatte.

Mögliche Abhilfe

Die Lösung, die ich verwendet habe, kann wie folgt zusammengefasst werden:

  1. Das Ziel besteht darin, zu verhindern, dass GetStringUTFChars () das ausführt falsche UTF-8-Codierung des zusätzlichen Unicode-Zeichens.
  2. Dies erfolgt durch den Java-Client, der die Anforderungszeichenfolge als codiert Base64.
  3. Die Base64-codierte Anfrage wird an JNI übergeben.
  4. JNI ruft GetStringUTFChars () auf, das das Base64-encoded extrahiert string ohne UTF-8-Codierung durchzuführen.
  5. Der JNI-Code decodiert dann die Base-64-Daten und erzeugt das Original UTF-16 (wide char) Anforderungszeichenfolge, einschließlich der Zusatzzeichenfolge Unicode-Zeichen.

Auf diese Weise umgehen wir das Problem, zusätzliche Unicode-Zeichen aus der Java-Zeichenkette zu extrahieren. Stattdessen konvertieren wir die Daten vor dem Aufruf von GetStringUTFChars () in Base-64 ASCII, extrahieren die Base-64-ASCII-Zeichen mithilfe von GetStringUTFChars () und konvertieren die Base-64-Daten zurück in Wide-Zeichen.

    
Moshe Rubin 23.10.2014 06:55
quelle
9

So habe ich das gemacht.

1- Char Array zu JByteArray.

2- JByteArray zu JString.

3- Geben Sie jstring an die Java-Seite zurück.

JNI-Code; (.c) format

%Vor%

Java-Code;

%Vor%

Andere Vorgehensweise funktioniert nicht für mich;

Ich habe auch versucht, return (*env)->NewStringUTF(env, r) , aber einige Zeichen, die nicht im Char-Array, am Ende der Zeichenfolge, wo mit der Warnung JNI WARNUNG: Eingabe ist nicht gültig Modified UTF-8: illegale Fortsetzung Byte 0x40 .

Beispiel; PKdhtXMm18n2L9K DL- DL

Bearbeiten:

C ++ Version

%Vor%     
Berkay Turancı 11.12.2015 08:14
quelle
2

Ich hatte dieses Problem, wenn ich die Datei Application.mk

ändere

Aus dieser Zeile:

%Vor%

An:

%Vor%

Sobald ich es wieder zurücksetzte, behob es das Problem.

    
Zammbi 04.07.2013 05:30
quelle
1

Für mich bestand die Lösung darin, den Inhalt auf ein const char * zu setzen:

%Vor%

und die Funktion:

%Vor%     
JCJ 15.09.2017 01:09
quelle
0

Zeichenfolgen, die Sie an NewStringUTF () übergeben, müssen gültig sein UTF-8 . Es sieht so aus, als ob die von Ihrer Funktion start_Inauthroot () zurückgegebene Zeichenfolge in einer anderen Codierung enthalten ist oder nur eine ungültige Zeichenfolge zurückgibt. Sie müssen die Zeichenfolge in UTF-8 konvertieren, bevor Sie sie an JNI-Funktionen übergeben. Oder Sie können einen der Zeichensatz-bewusste String-Konstruktoren , um stattdessen das String-Objekt zu erstellen.

    
kelnos 26.08.2012 22:28
quelle
0

Das funktioniert für mich in C ++

%Vor%     
hB0 04.11.2013 23:10
quelle
0

Meiner Meinung nach ist es kein Fehler.

NewStringUTF Konstruiert ein neues java.lang.String-Objekt aus einem Array von Zeichen in der modifizierten UTF-8 -Codierung.

Modifiziertes UTF-8 ist kein Standard-UTF-8. Siehe Modified UTF-8

In den meisten Fällen ist die UTF-8-codierte Zeichenfolge gültig Modified UTF-8. Weil Modified UTF-8 und UTF-8 sehr ähnlich sind. Wenn es jedoch zu einer Unicode-Zeichenfolge außerhalb der Basic Multilingual Plane kommt, sind sie nicht kompatibel.

Lösung: Übergeben Sie UTF-8-Bytes an die Java-Ebene und die neue Zeichenfolge (Bytes, "UTF-8") und übergeben Sie dann jstring an JNI.

    
Shaw 22.08.2017 13:55
quelle