2013-09-09 3 views
-1

Я новичок в Android и Java. Я исхожу из PHP. Следующий код взят из книги (Pro Android 4 App Dev - Рето Майер): Вот Android код, где я столкнулся проблемой:Решение ошибки NullPointerException в Android

Файл: EarthquakeListFragment.java

public class EarthquakeListFragment extends ListFragment { 

    ArrayAdapter<Quake> aa; 
    ArrayList<Quake> earthquakes = new ArrayList<Quake>(); 

    private static final String TAG = "EARTHQUAKE"; 
    private Handler handler = new Handler(); 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 

     int layoutID = android.R.layout.simple_list_item_1; 
     aa = new ArrayAdapter<Quake>(getActivity(), layoutID, earthquakes); 
     setListAdapter(aa); 

     Thread t = new Thread(new Runnable() { 
      public void run() { 
       refreshEarthquakes(); 
      } 
     }); 
     t.start(); 

    } 

    public void refreshEarthquakes() { 

     // Get the XML 
     URL url; 
     try { 
      String quakeFeed = getString(R.string.quake_feed); 
      url = new URL(quakeFeed); 

      URLConnection connection; 
      connection = url.openConnection(); 

      HttpURLConnection httpConnection = (HttpURLConnection) connection; 
      int responseCode = httpConnection.getResponseCode(); 

      if (responseCode == HttpURLConnection.HTTP_OK) { 

       InputStream in = httpConnection.getInputStream(); 

       DocumentBuilderFactory dbf = DocumentBuilderFactory 
         .newInstance(); 
       DocumentBuilder db = dbf.newDocumentBuilder(); 

       // Parse the earthquake feed 
       Document dom = db.parse(in); 
       Element docEle = dom.getDocumentElement(); 

       // clear the old earthquake 
       earthquakes.clear(); 

       // Get a list of each earthquake entry. 
       NodeList nl = docEle.getElementsByTagName("entry"); 
       if (nl != null && nl.getLength() > 0) { 

        for (int i = 0; i < nl.getLength(); i++) { 
         Element entry = (Element) nl.item(i); 
         Element title = (Element) entry.getElementsByTagName(
           "title").item(0); 
         Element g = (Element) entry.getElementsByTagName(
           "georss:point").item(0); 
         Element when = (Element) entry.getElementsByTagName(
           "updated").item(0); 
         Element link = (Element) entry.getElementsByTagName(
           "link").item(0); 

         String details = title.getFirstChild().getNodeValue(); 
         String hostname = "http://earthquake.usgs.gov"; 
         String linkString = hostname 
           + link.getAttribute("href"); 

         String point = g.getFirstChild().getNodeValue(); 
         String dt = when.getFirstChild().getNodeValue(); 
         SimpleDateFormat sdf = new SimpleDateFormat(
           "yyyy-MM-dd'T'hh:mm:ss'Z'"); 
         Date qdate = new GregorianCalendar(0, 0, 0).getTime(); 

         try { 
          qdate = sdf.parse(dt); 
         } catch (ParseException e) { 
          Log.d(TAG, "Date parsing exception.", e); 
         } 

         String[] location = point.split(" "); 
         Location l = new Location("dummyGPS"); 
         l.setLatitude(Double.parseDouble(location[0])); 
         l.setLongitude(Double.parseDouble(location[1])); 

         String magnitudeString = details.split(" ")[1]; 
         int end = magnitudeString.length() - 1; 
         double magnitude = Double.parseDouble(magnitudeString 
           .substring(0, end)); 

         details = details.split(",")[1].trim(); 

         final Quake quake = new Quake(qdate, details, l, 
           magnitude, linkString); 

         // Process a newly found earthquake 
         handler.post(new Runnable() { 
          public void run() { 
           addNewQuake(quake); 
          } 
         }); 

        } 

       } 
      } 
     } 
     catch (HttpHostConnectException e) { 
      Log.d(TAG, "HttpConnection Error."); 
     } 

     catch (MalformedURLException e) { 
      Log.d(TAG, "MalformedURLException"); 
     } catch (IOException e) { 
      Log.d(TAG, "IOException"); 
     } catch (ParserConfigurationException e) { 
      Log.d(TAG, "Parser Config Exception"); 
     } catch (SAXException e) { 
      Log.d(TAG, "SAX Exception"); 
     } finally { 

     } 
    } 

    private void addNewQuake(Quake _quake) { 
     // add the new quake to our list of earthquake 
     earthquakes.add(_quake); 

     // Notify the array adapter of a change 
     aa.notifyDataSetChanged(); 

    } 

} 

Вот часть LogCat, где показаны ошибки:

09-09 20: 03: 15,689: Вт/dalvikvm (1095): ThreadId = 11: поток, выходящий с неперехваченного исключения (группа = 0x40a71930) 09-09 20: 03: 15.735: E/AndroidRunti me (1095): FATAL EXCEPTION: Thread-111 09-09 20: 03: 15.735: E/AndroidRuntime (1095): java.lang.NullPointerException 09-09 20: 03: 15.735: E/AndroidRuntime (1095): в com.satyaweblog.earthquake.EarthquakeListFragment.refreshEarthquakes (EarthquakeListFragment.java:106) 09-09 20: 03: 15.735: E/AndroidRuntime (1095): в com.satyaweblog.earthquake.EarthquakeListFragment $ 1.Run (EarthquakeListFragment. java: 50) 09-09 20: 03: 15.735: E/AndroidRuntime (1095): at java.lang.Thread.run (Thread.java:856) 09-09 20: 03: 20.015: I/Process (1095): сигнал отправки. PID: 1095 SIG: 9

Так, в одном месте, то строка кода:

String point = g.getFirstChild().getNodeValue(); 

В PHP, я бы проверил этот путь: var_dump (г); Как проверить здесь, в Android + Java?

Думаю, 2-я ошибка будет вызвана первым!

+1

, если вы используете Eclipse, если вы дважды нажали эту строку: com.satyaweblog.earthquake.EarthquakeListFragment.refreshEarthquakes (EarthquakeListFragment.java:106) 09- 09 20: 03: 15.735: в вашем LogCat, он отправит вас в строку, в которой он выбрал Exception, Runtime Exceptions всегда отображаются в строке после строки «cased by: NullPointerException», если вы нашли свое имя класса в этой следующей строке, дважды щелкните по нему, чтобы перейти на ошибку также убедитесь, что инициализируйте свои методы локальными переменными поскольку компилятор несколько раз не знает, когда он вызывается, и поэтому он может вызвать ошибку компилятора для –

ответ

1

В проблематичной линии

String point = g.getFirstChild().getNodeValue(); 

вполне возможно, что это gnull.

Element g = (Element) entry.getElementsByTagName(
          "georss:point").item(0); 

в NodeList#item(int)

Возвращает элемент indexth в коллекции. Если индекс больше или равен числу узлов в списке, это возвращает значение null.

Возможно также, что Node#getFirstChild()null. Его состояния javadoc

Первый ребенок этого узла. Если такого узла нет, это возвращает null.

Посмотрите на XML, который вы извлекаете. Скорее всего, нет дочернего узла.

+0

. Вот ссылка на файл xml: http://earthquake.usgs.gov/earthquakes/catalogs/1day-M2.5.xml Я вижу, что 1-й вход не имеет . Говорят, что фид устарел. Возможно, причина в том, что код не работает? –

+0

@SatyaPrakash Не используйте 'getElementsByTagName' при использовании пространств имен. Используйте 'getElementsByTagNameNS'. Первый не найдет ничего с значением '' georss: point "'. Также рассмотрите использование XPath. –

+0

Спасибо за предложение, но getElementsByTagName работает сейчас через два раза. Запуск Eclipse и угрюмое изменение имени файла XML (http://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/2.5_day.atom?format=xml). –

0

for (int i = 0; i < nl.getLength(); i++) Изменить код for (int i = 1; i < nl.getLength(); i++)

он будет работать, как код XML по ссылке уже истекли.Таким образом, для 0-го индекса он получает устаревшее сообщение.

для запуска для цикла из i = 1 вместо i = 0

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