#java #android #rest
#java #Android #отдых
Вопрос:
Я разрабатываю приложение для Android, которое выполняет вызов RESTful-сервера через HTTP. Проблема в том, что я получаю следующую ошибку: NegativeArraySizeException -1
. Я не могу понять, почему возникает проблема.
У меня есть два класса: ReadHttpTask
и HttpHelper
. Ошибка, по-видимому, вызвана StringBuilder внутри класса HttpHelper или, по крайней мере, там, где отладчик показывает причину исключения.
ReadHttpTask:
public class ReadHttpTask extends AsyncTask<String, Void, CharSequence> {
@Override
protected CharSequence doInBackground(String...urls) {
String urlString = urls[0];
try{
CharSequence result = HttpHelper.GetHttpResponse(urlString);
return resu<
} catch (IOException ex){
cancel(true);
String errorMessage = ex.getMessage() "n" urlString;
Log.e("Something went wrong", errorMessage);
return errorMessage;
}
}
}
HttpHelper:
public class HttpHelper {
public static CharSequence GetHttpResponse(String urlString) throws IOException {
URL url = new URL(urlString);
URLConnection connection = url.openConnection();
if(!(connection instanceof HttpURLConnection)){
throw new IOException("Not an HTTP connection");
}
HttpURLConnection httpConnection = (HttpURLConnection) connection;
int responseCode = httpConnection.getResponseCode();
if(responseCode != HttpURLConnection.HTTP_OK){
String responseMessage = httpConnection.getResponseMessage();
throw new IOException("HTTP response code: " responseCode " " responseMessage);
}
InputStream inputStream = httpConnection.getInputStream();
BufferedReader reader = null;
try{
reader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder result = new StringBuilder(httpConnection.getContentLength());
while(true){
String line = reader.readLine();
if(line==null) break;
result.append(line);
}
return resu<
} finally {
if(reader != null) reader.close();
}
}
}
Комментарии:
1. Вы получите только
NegativeArraySizeException
в том случае, если пытаетесь создать массив — и я не вижу, где вы это делаете в этом коде. Пожалуйста, укажите полную трассировку стека и укажите соответствующие номера строк в приведенном выше коде.2. Прочитайте это : developer.android.com/reference/java/net/… Как вы сказали, это происходит от получения Stringbuilder -1. Почему, хорошо проверьте метод, который вы используете для создания этого экземпляра. В документе указано, что он может возвращать -1 в двух случаях.
3. @AndyTurner, StringBuilder тоже использует это исключение, поскольку это динамический массив символов 😉
4. где находится трассировка стека?
5. Также:
result.append(line).append("n");
строка as не содержит разделителя строк.
Ответ №1:
Вы используете getContentLength
методы из URLConnection
create an instance StringBuilder .
Сначала давайте посмотрим на StringBuilder :
StringBuilder общедоступный StringBuilder(int capacity)
Создает конструктор строк, в котором нет символов, а начальная емкость указана аргументом capacity . Параметры: емкость — начальная емкость. Выдает: исключение NegativeArraySizeException — если аргумент емкости меньше 0.
Если вы откроете документ, вы увидите :
ВОЗВРАТ
введите длину содержимого ресурса, на который ссылается URL-адрес этого соединения, -1, если длина содержимого неизвестна или если длина содержимого больше целого числа.MAX_VALUE.
Итак, у вас есть свое решение. Вы не должны создавать StringBuilder с определенным размером, если это значение равно -1, если вы получаете значение, которое вы можете. Если нет, пусть SB управляет собственным размером.
Создайте StringBuilder следующим образом :
StringBuilder result = new StringBuilder(); //create with a size of 16 character.
Комментарии:
1. Спасибо за ваш ответ. Я немного смущен тем, как позволить SB управлять своим собственным размером. Если я вас правильно понимаю, то
httpConnection.getContentLength();
это тот, который определяет размер SB, но как еще вы могли бы получить длину содержимого, если не так?2. @kennyYice23 Ну, вы должны знать, что StringBuilder — это массив символов, размер которого сам менеджер, поэтому, если вы добавите экземпляр, а массив будет маленьким, он изменит его размер. Итак, в основном, просто создайте StringBuilder без параметра. Я думаю, что это создаст массив из 15, когда появится больше символов, массив будет расти, исключение из ограничений не будет добавлено (не могу сказать, каков предел памяти массива …). Я добавил строку для создания SB
Ответ №2:
Я также столкнулся с подобным исключением. Это было вызвано, когда таблица / представление / процедура отсутствовали в БД.Я вводил имя пакета и имя процедуры из инъекции конструктора и пытался скомпилировать simplejdbccall, поскольку процедура отсутствовала, она выдала ту же ошибку.