2013-11-19 4 views
0

Я пишу свое первое приложение для Android и пытаясь получить вызов REST из приложения. После пару страниц и других SO сообщения, я получил это:Запрос RESTful с использованием HTTPUrlConnection

URL serverUrl = new URL("http://localhost:13980/api/maps/"); //the value is hardcoded for testing purposes 

public String getMapsJson() 
{ 
    Log.d("Minimap", ">> getting maps json from " + serverUrl.toString()); 
    String output = ""; 

    HttpURLConnection connection = null; 

    try 
    { 
     connection = (HttpURLConnection) serverUrl.openConnection(); 
     connection.setRequestMethod("GET"); 
     Log.d("Minimap", "connection opened!"); 
     InputStream in = new BufferedInputStream(connection.getInputStream()); 
     Log.d("Minimap", "input stream captured"); 
     output = readStream(in); 
     Log.d("Minimap", "stream read"); 
    } 

    catch (Exception e) 
    { 
     Log.d("Minimap", e.getMessage()); //************* This is line 53 <<<<<< 
    } 

    finally 
    { 
     connection.disconnect(); 
    } 


    Log.d("Minimap", "JSON: " + output); 
    return output; 
} 

private String readStream(InputStream in) 
{ 
    try 
    { 
     BufferedReader reader = new BufferedReader(new InputStreamReader(in)); 
     String line = reader.readLine(); 
     String output = line; 

     while((line = reader.readLine()) != null) 
      output += line; 

     return output; 
    } 
    catch (IOException e) 
    { 
     e.printStackTrace(); 
     return ""; 
    } 
} 

Выход я получаю от LogCat просто

11-19 07:38:31.599 3813-3813/com.northstar.minimap D/Minimap﹕ >> getting maps json from http://localhost:13980/api/maps/ 
11-19 07:38:31.599 3813-3813/com.northstar.minimap D/Minimap﹕ connection opened! 

, а затем приложение падает со следующей трассировки стека:

11-19 08:02:50.903  744-744/com.northstar.minimap E/AndroidRuntime﹕ FATAL EXCEPTION: main 
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.northstar.minimap/com.northstar.minimap.MapActivity}: java.lang.NullPointerException: println needs a message 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180) 
      at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
      at android.app.ActivityThread.access$600(ActivityThread.java:141) 
      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
      at android.os.Handler.dispatchMessage(Handler.java:99) 
      at android.os.Looper.loop(Looper.java:137) 
      at android.app.ActivityThread.main(ActivityThread.java:5041) 
      at java.lang.reflect.Method.invokeNative(Native Method) 
      at java.lang.reflect.Method.invoke(Method.java:511) 
      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
      at dalvik.system.NativeStart.main(Native Method) 
    Caused by: java.lang.NullPointerException: println needs a message 
      at android.util.Log.println_native(Native Method) 
      at android.util.Log.d(Log.java:138) 
      at com.northstar.minimap.Communicator.getMapsJson(Communicator.java:53) 
      at com.northstar.minimap.MapActivity.onCreate(MapActivity.java:36) 
      at android.app.Activity.performCreate(Activity.java:5104) 
      at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080) 
      at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144) 
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230) 
            at android.app.ActivityThread.access$600(ActivityThread.java:141) 
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234) 
            at android.os.Handler.dispatchMessage(Handler.java:99) 
            at android.os.Looper.loop(Looper.java:137) 
            at android.app.ActivityThread.main(ActivityThread.java:5041) 
            at java.lang.reflect.Method.invokeNative(Native Method) 
            at java.lang.reflect.Method.invoke(Method.java:511) 
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793) 
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560) 
            at dalvik.system.NativeStart.main(Native Method) 
11-19 08:02:50.933  308-445/system_process W/ActivityManager﹕ Force finishing activity com.northstar.minimap/.MapActivity 
11-19 08:02:50.943  308-445/system_process W/ActivityManager﹕ Force finishing activity com.northstar.minimap/.MainActivity 

страница это запрашивая (http://localhost:13980/api/maps/) является простой GET конечной точкой, которая плюет назад некоторые JSON. На данный момент я был бы счастлив, если бы JSON, который он вытащил, был напечатан в LogCat.

Спасибо!

+1

Что вы подразумеваете под «сбоями»? Как вы знаете, что это сбой, и какова трассировка стека из всех исключений, которые возникают? –

+0

Это не решает вашу проблему, но улучшает обработку исключений: readStream НЕ должен улавливать исключение, но вместо этого указывать его в предложении throws. – isnot2bad

+0

@JasonC Приложение выходит из эмулятора, на котором отображается уведомление, в котором говорится: «К сожалению, Minimap остановлен». Я обновил описание с помощью трассировки стека. Похоже, что это происходит при вызове Log.d() в блоке catchMapsJson. – Benjin

ответ

2

Возможно, вы ошибаетесь с localhost, сервер не работает на устройстве Android или эмуляторе.

вы должны использовать 10.0.2.2 для доступа к компьютеру под управлением эмулятора см http://developer.android.com/tools/devices/emulator.html

или IP веб-сервера. (убедитесь, что он доступен для внешнего мира)

как указано @Jason C, ваша обработка ошибок довольно плохая. вы никогда не должны ловить все исключения.

довольно стандартный способ сделать ваш метод броском IOException, поэтому код, вызывающий getMapsJson, может обрабатывать это конкретное и общее исключение (например, без подключения).

Если вы хотите обработать код ошибок HTTP и ошибок, вы должны проверить код результата перед открытием InputStream. В случае ошибки вы также можете получить ErrorStream вместо InputStream, если вам нужен фактический ответ в дополнение к известному результату.

+0

@Benjin : Даже если это ваша проблема, вы можете улучшить код обработки ошибок, чтобы ошибки отображались/регистрировались правильно. –

+0

@JasonC вы могли бы разработать? Я только что (как, час назад) узнал, что мне нужно использовать Log.d() вместо System.out.println, чтобы печатать материал на консоли, поэтому, пожалуйста, несите меня. – Benjin

+0

@Gal Ben-Haim Делает смысл. Я не думаю, что вам не удастся узнать, как работать с этим портом для localhost до 127.0.0.1:port (и, следовательно, 10.0.2.2:port в эмуляторе)? – Benjin

0

Причина, по которой ваше приложение (вероятно) бросает исключение, дается в ответе Гал Бен-хаим. Однако причиной вашего приложения является crashing, потому что вы неправильно обрабатываете это исключение.

Одна хитрая вещь об исключениях, что getMessage() метод может возвращение null. Log.d() не нравится параметр null и поэтому выбрасывает другое исключение из вашего обработчика исключений, которое не отображается, а ваше приложение сбрасывается и записывается. Кроме того, ваше исходное исключение больше не является частью трассировки стека (поскольку это не было прямой причиной сбоя), и информация о нем проглатывается.

Вы должны проверить, e.getMessage() is null, и если да, то передайте что-то ненулевое значение в Log.d (например, пустую строку).

NullPointerException : println needs a message in android

Смежные вопросы