Pobieranie pliku xml z kursami walut NBP

0

Witam mam problem z pobieraniem kursów walut do tablicy. Chciałbym aby pobrane kursy średnie dla danych walut były zapisywane w tablicy aby można było je dalej łatwo wykorzystać do przeliczania. Stworzyłem przycisk który ma wykonywac aktualizację tych kursów, lecz na androidzie wyskakuje bład android.os.NetworkOnMainThreadException. Dodałem do kodu <uses-permission android:name="android.permission.INTERNET" /> lecz nadal nie działa.

Oto kod dla aktualizacji:

public void onClick(View vv) {
        TextView kod_waluty[];
        TextView kurs_sredni[];

        try {

            URL url = new URL("http://www.nbp.pl/kursy/xml/LastA.xml");
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(url.openStream()));
            doc.getDocumentElement().normalize();

            NodeList nodeList = doc.getElementsByTagName("pozycja");

            kod_waluty = new TextView[nodeList.getLength()];
            kurs_sredni = new TextView[nodeList.getLength()];


            for (int i = 0; i < nodeList.getLength(); i++) {

                Node node = nodeList.item(i);

                Element kodElmnt = (Element) node;
                NodeList kodList = kodElmnt.getElementsByTagName("kod_waluty");
                Element kodElement = (Element) kodList.item(0);
                kodList = kodElement.getChildNodes();
                kod_waluty[i].setText(((Node) kodList.item(0)).getNodeValue());

                Element kursElmnt = (Element) node;
                NodeList kursList = kursElmnt.getElementsByTagName("kurs_sredni");
                Element kursElement = (Element) kursList.item(0);
                kodList = kursElement.getChildNodes();
                kurs_sredni[i].setText(((Node) kursList.item(0)).getNodeValue());
            }

        } catch (Exception e) {
            onClick.setText("Blad: " + e);
        }
    }
0

Skup się na błędzie, który dostałeś. android.os.NetworkOnMainThreadException oznacza, że próbujesz działać na wątku głownym (UI thread), przez co mógłbyś zablokować cały program. Android od razu temu przeciwdziała, poprzez ten wyjątek. Jednym z rozwiązań byłoby użycie AsyncTask. Jest dość prosty w użyciu. Poczytaj sobie o wątkach http://developer.android.com/guide/components/processes-and-threads.html.

0

Po modyfikacji kodu błąd nie wyskakuje, ale za to pojawia się inny java.lang.NullPointerException

Dołączam kod:

public void onClick(View vv) {


        new Thread(new Runnable(){
            @Override
            public void run() {
                try {

                    TextView kod_waluty[];
                    TextView kurs_sredni[];
                    try {

                        URL url = new URL("http://www.nbp.pl/kursy/xml/LastA.xml");
                        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
                        DocumentBuilder db = dbf.newDocumentBuilder();
                        Document doc = db.parse(new InputSource(url.openStream()));
                        doc.getDocumentElement().normalize();

                        NodeList nodeList = doc.getElementsByTagName("pozycja");

                        kod_waluty = new TextView[nodeList.getLength()];
                        kurs_sredni = new TextView[nodeList.getLength()];


                        for (int i = 0; i < nodeList.getLength(); i++) {



                            Node node = nodeList.item(i);

                            Element kodElmnt = (Element) node;
                            NodeList kodList = kodElmnt.getElementsByTagName("kod_waluty");
                            Element kodElement = (Element) kodList.item(0);
                            kodList = kodElement.getChildNodes();
                            kod_waluty[i].setText(((Node) kodList.item(0)).getNodeValue());

                            Element kursElmnt = (Element) node;
                            NodeList kursList = kursElmnt.getElementsByTagName("kurs_sredni");
                            Element kursElement = (Element) kursList.item(0);
                            kodList = kursElement.getChildNodes();
                            kurs_sredni[i].setText(((Node) kursList.item(0)).getNodeValue());
                        }

                    } catch (Exception e) {
                        onClick.setText("Blad: " + e);
                    }



                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }).start();


    }
0

Po pierwsze używaj tagów <code class="java"> i umieszczaj w nich kod.

Po drugie gdzie dokładnie leci ten NPE, bo bawiąc się we wróżkę (i korzystając z doświadczenia w pisaniu podobnego pobieracza kursów) któryś element w XMLu nie ma zawartości i próba jej pobrania zwraca null.

0

zamiast się bawić w dziwne ściąganie i parsowanie xml-a skorzystaj sobie z gotowych bibliotek przystosowanych do androida tzn Retrofita
http://square.github.io/retrofit/

a tutaj masz przykład jak skorzystać z retrofita z xml-em
http://stackoverflow.com/questions/25380280/how-to-use-retrofit-and-simplexml-together-in-downloading-and-parsing-an-xml-fil

nie ma sensu pisać czegoś co ktoś już zrobił wcześniej i z dużą dozą prawdopodobieństwa dużo lepiej ;-)

pzdr

0

logcat:

01-09 0930.975 17803-17803/pwr.kantor I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:269>: EGL 1.4 QUALCOMM build: AU_LINUX_ANDROID_JB_REL_RB4.04.01.02.16.028_msm8960_JB_REL_RB4.2_Merge_release_AU (Merge)
Build Date: 12/06/12 Thu
Local Branch:
Remote Branch: m/jb_rel_rb4.2
Local Patches: NONE
Reconstruct Branch: NOTHING
01-09 0930.985 17803-17803/pwr.kantor D/libc﹕ pt_debug : pthread_create->start_routine=0x4ffbfe31, tls=0x5396cf00, arg=0x512fc1c8
01-09 0930.985 17803-18984/pwr.kantor D/libc﹕ pt_debug : __thread_entry->func=0x4ffbfe31
, tls=0x5396cf00, arg=0x512fc1c8
01-09 0930.995 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x5396d000 size:2088960 offset:0 fd:60
01-09 0930.995 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x4003f000 size:4096 offset:0 fd:62
01-09 0931.055 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x544e9000 size:2088960 offset:0 fd:65
01-09 0931.055 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x40092000 size:4096 offset:0 fd:67
01-09 0931.516 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x546e7000 size:2088960 offset:0 fd:69
01-09 0931.516 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x400a1000 size:4096 offset:0 fd:71
01-09 0936.471 17803-17803/pwr.kantor D/libc﹕ pt_debug : pthread_create->start_routine=0x40a2b645, tls=0x549e4f00, arg=0x51df6f30
01-09 0936.471 17803-18995/pwr.kantor D/libc﹕ pt_debug : __thread_entry->func=0x40a2b645
, tls=0x549e4f00, arg=0x51df6f30
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:5127)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:979)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.View.requestLayout(View.java:15240)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.View.requestLayout(View.java:15240)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.View.requestLayout(View.java:15240)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.view.View.requestLayout(View.java:15240)
01-09 0936.671 17803-18995/pwr.kantor W/System.err﹕ at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:292)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at android.view.View.requestLayout(View.java:15240)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at android.widget.TextView.checkForRelayout(TextView.java:6753)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at android.widget.TextView.setText(TextView.java:3765)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at android.widget.TextView.setText(TextView.java:3615)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at android.widget.TextView.setText(TextView.java:3590)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at pwr.kantor.MainActivity$3.run(MainActivity.java:197)
01-09 0936.681 17803-18995/pwr.kantor W/System.err﹕ at java.lang.Thread.run(Thread.java:864)
01-09 0946.201 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x5396d000 size:2088960
01-09 0946.211 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x4003f000 size:4096
01-09 0946.211 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x544e9000 size:2088960
01-09 0946.211 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x40092000 size:4096
01-09 0946.211 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x546e7000 size:2088960
01-09 0946.211 17803-17803/pwr.kantor D/memalloc﹕ ion: Unmapping buffer base:0x400a1000 size:4096
01-09 0946.351 17803-17803/pwr.kantor D/libc﹕ pt_debug : pthread_create->start_routine=0x4ffbfe31, tls=0x5396cf00, arg=0x51d93820
01-09 0946.351 17803-19003/pwr.kantor D/libc﹕ pt_debug : __thread_entry->func=0x4ffbfe31
, tls=0x5396cf00, arg=0x51d93820
01-09 0946.371 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x5396d000 size:2088960 offset:0 fd:61
01-09 0946.371 17803-17803/pwr.kantor D/memalloc﹕ ion: Mapped buffer base:0x4003f000 size:4096 offset:0 fd:64

0

teraz pokazałeś stack-trace błędu że nie możesz zmieniać widoku (Views-a ) spoza wątku który go utworzył

Edit:

W ogóle zabierasz się do tego po chińsku

Stwórz sobie klasę dziedziczącą po ASyncTask która Ci ściągnie tego XML-a jak nie chcesz z retrofita korzystać. W postExecute przepisz sobie do swoich okienek, jeżeli masz listę to użyj ListView albo GridView a nie tablicę TextViews

0

wojciechmaciejewski a mógłbyś dokładniej opisać jak działa ten Retrofit? Nie będę ukrywał, że jestem całkowicie początkujący w sprawach programowania na aplikację i tak naprawdę jest to moja 1 aplikacja jaką robię w javie. Musze zrobić projekt przelicznika walut na aplikacje mobilną na studiach, jako że nie jestem na kierunku informatycznym, to miałem styczność tylko z C i C++ i to też w niezbyt zaawansowanym stopniu. Jako że chciałbym się czegoś nauczy a nie kupić gotowy projekt to gdyby ktoś mógł mi to wytłumaczyć byłbym bardzo szczęśliwy. Poszukuję korepetycji online lub w okolicach Wrocławia w sprawie tego projektu jeśli ktoś byłby chętny proszę o kontakt.

0

Retrofit to biblioteka do obsługi serwera REST-owego po stronie klienta. Pobierasz z usługi REST-owej xml-a lub JSON-a i obrabiasz go na wybrany przez siebie sposób.

1 użytkowników online, w tym zalogowanych: 0, gości: 1