Issue #80: Unable to open large json files on android 2.2 + phonegap 0.9.5

I could not get rid of the url encoding and decoding without hampering some users ability to pass non-ascii characters back to JavaScript.  However, I was able to reduce the amount of data being passed from Java to JavaScript by 40% by decoding common characters that occur in JSON and XML.  These characters will survive the round trip just fine and don't need to be encoded.

This is the best solution I could come up with.  You won't be able to read files as large as you could in 0.9.4 but it will get close and it will support non-ascii characters.
This commit is contained in:
macdonst 2011-06-01 02:54:18 +08:00
parent 39ec9c095d
commit 992ee0bca4
2 changed files with 46 additions and 4 deletions

View File

@ -767,8 +767,8 @@ PhoneGap.JSCallback = function() {
// If callback has JavaScript statement to execute
if (xmlhttp.status === 200) {
// Need to url decode the response and replace %20 with a space
var msg = decodeURIComponent(xmlhttp.responseText.replace(/\+/g, '%20'));
// Need to url decode the response
var msg = decodeURIComponent(xmlhttp.responseText);
setTimeout(function() {
try {
var t = eval(msg);

View File

@ -11,11 +11,14 @@ import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URLEncoder;
import java.util.LinkedList;
import android.util.Log;
/**
* This class provides a way for Java to run JavaScript in the web page that has loaded PhoneGap.
* The CallbackServer class implements an XHR server and a polling server with a list of JavaScript
@ -42,6 +45,8 @@ import java.util.LinkedList;
*/
public class CallbackServer implements Runnable {
private static final String LOG_TAG = "CallbackServer";
/**
* The list of JavaScript statements to be sent to JavaScript.
*/
@ -224,8 +229,9 @@ public class CallbackServer implements Runnable {
//System.out.println("CallbackServer -- sending item");
response = "HTTP/1.1 200 OK\r\n\r\n";
String js = this.getJavascript();
if (js != null)
response += URLEncoder.encode(js, "UTF-8");
if (js != null) {
response += encode(js);
}
}
}
else {
@ -321,4 +327,40 @@ public class CallbackServer implements Runnable {
}
}
/**
* This will encode the return value to JavaScript. We revert the encoding for
* common characters that don't require encoding to reduce the size of the string
* being passed to JavaScript.
*
* @param value to be encoded
* @return encoded string
*/
public static String encode(String value) {
String encoded = null;
try {
encoded = URLEncoder.encode(value, "UTF-8")
.replaceAll("\\+", " ")
.replaceAll("\\%21", "!")
.replaceAll("\\%22", "\"")
.replaceAll("\\%27", "'")
.replaceAll("\\%28", "(")
.replaceAll("\\%29", ")")
.replaceAll("\\%2C", ",")
.replaceAll("\\%3C", "<")
.replaceAll("\\%3D", "=")
.replaceAll("\\%3E", ">")
.replaceAll("\\%3F", "?")
.replaceAll("\\%40", "@")
.replaceAll("\\%5B", "[")
.replaceAll("\\%5D", "]")
.replaceAll("\\%7B", "{")
.replaceAll("\\%7D", "}")
.replaceAll("\\%3A", ":")
.replaceAll("\\%7E", "~");
} catch (UnsupportedEncodingException e) {
Log.e(LOG_TAG, e.getMessage(), e);
}
return encoded;
}
}