Java - Android - crash aplikacji w trakcie działania

0

Witam, napisałem prostą apkę, które łączy się z serwerem i pobiera z niego dane o pogodzie. Można wpisywać miasto lub pozwolić aplikacji na wykrycie nas po lokalizacji gps. Niestety, co kilka zapytań aplikacja crashuje, czasami zdarza jej się to od razu po uruchomieniu. Do pobrania danych używam Async Taska. Wrzucam kod MainActivity i będę wdzięczny za jakieś sugestie co tutaj może być nie tak.

 package com.example.sebastian.pogodainfo;



public class MainActivity extends Activity {

    private TextView miasto;
    private TextView opisWarunkow;
    private TextView temperatura;
    private TextView predkoscWiatru;
    private TextView windDeg;
    private TextView cisnienie;
    private TextView wilgotnosc;
    private Button ustalPolozenie;
    private Button zmianaMiastaPrzycisk;
    private ImageView ikonka;
    private String miastko;

    private TextView dl;
    private TextView szer;
    private TextView info;
    private String dlStr;
    private String szerStr;
    private JSONPogodaTask task;

private     String zmienZnaki(String aa)
    {

        String input = aa.toLowerCase();
        String tmp = input.replace("ą", "a");
        tmp = tmp.replace("ć","c");
        tmp = tmp.replace("ę", "e");
        tmp = tmp.replace("ł", "l");
        tmp = tmp.replace("ń", "n");
        tmp = tmp.replace("ó", "o");
        tmp = tmp.replace("ś", "s");
        tmp = tmp.replace("ź", "z");
        tmp = tmp.replace("ż", "z");
        String output = tmp.replace(" ", "-");
        return output;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        miastko = "Lodz";
       miasto         = (TextView) findViewById(R.id.miasto);
       opisWarunkow   = (TextView) findViewById(R.id.opisWarunkow);
       temperatura    = (TextView) findViewById(R.id.temperatura);
       predkoscWiatru = (TextView) findViewById(R.id.predkoscWiatru);
       windDeg     =    (TextView) findViewById(R.id.windDeg);
       cisnienie   =    (TextView) findViewById(R.id.cisnienie);
       wilgotnosc  =    (TextView) findViewById(R.id.wilgotnosc);
       ikonka      =   (ImageView) findViewById(R.id.ikonka);
       dl          =   (TextView)  findViewById(R.id.dl);
       szer        =   (TextView)  findViewById(R.id.szer);
       info        =   (TextView)  findViewById(R.id.info);




        task = new JSONPogodaTask();
        task.execute(new String[]{ustalAdresMiasto(zmienZnaki(miastko))});

        Button zmianaMiastaPrzycisk = (Button) findViewById(R.id.zmianaMiastaPrzycisk);
        Button ustalPolozenie = (Button) findViewById(R.id.ustalPolozenie);

        zmianaMiastaPrzycisk.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick (View v){
                EditText zmianaMiasta = (EditText) findViewById(R.id.zmianaMiasta);
                miastko = zmianaMiasta.getText().toString();
                task.cancel(true);
                task = new JSONPogodaTask();
                task.execute(new String[]{ustalAdresMiasto(zmienZnaki(miastko))});


            }

        });

        ustalPolozenie.setOnClickListener(new View.OnClickListener()
        {
        @Override
        public void onClick(View v)
        {
           Criteria kryteria = new Criteria();
            LocationManager locman =(LocationManager)getSystemService(LOCATION_SERVICE);

            String najlepszyDostawca=locman.getBestProvider(kryteria,true);
            Location lokalizacja=locman.getLastKnownLocation(najlepszyDostawca);
            MyLocationListener locListener = new MyLocationListener();
            locman.requestLocationUpdates(najlepszyDostawca,1000,1,locListener);

          info.setText("Znajdujesz się na współrzędnych, pogoda została dla nich ustalona: ");
          szer.setText("Szerokosc geograficzna: " +Double.toString(lokalizacja.getLongitude()));
          dl.setText("Dlugosc geograficzna: " +lokalizacja.getLatitude());

          szerStr=(Double.toString(lokalizacja.getLatitude()));
          dlStr=(Double.toString(lokalizacja.getLongitude()));

            task.cancel(true);
            task = new JSONPogodaTask();
            task.execute(new String[]{ustalAdresKoordynaty(szerStr,dlStr)});

        }



        });
    }

    public String ustalAdresMiasto(String miasto)
    {
        return "http://api.openweathermap.org/data/2.5/weather?q="+miasto;
    }

    public String ustalAdresKoordynaty(String szer, String dl)
    {
       return "http://api.openweathermap.org/data/2.5/weather?lat="+szer+"&"+"lon=" + dl;
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }




    private class JSONPogodaTask extends AsyncTask<String, Void, Pogoda>
    {
        private boolean zmieniac;

        @Override
        protected Pogoda doInBackground(String... params) {

            Pogoda pogoda = new Pogoda();
            String data = ((new KlientHTTP()).getWeatherData(params[0]));
            if(data.length()>200) {
                try {
                    pogoda = JSONParser.getPogoda(data);

                    // Let's retrieve the icon
                    pogoda.daneIkony = ((new KlientHTTP()).getImage(pogoda.warunkiPogodowe.getIkona()));
                    zmieniac=true;

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            else zmieniac=false;

            return pogoda;
        }

        @Override
        protected void onPostExecute(Pogoda pogoda) {
            super.onPostExecute(pogoda);

            if(zmieniac==true) {
                miasto.setText(pogoda.lokalizacja.getMiasto() + "," + pogoda.lokalizacja.getKraj());
               /* if (pogoda.daneIkony != null && pogoda.daneIkony.length > 0) {
                    Bitmap img = BitmapFactory.decodeByteArray(pogoda.daneIkony, 0, pogoda.daneIkony.length);
                    //  ikonka.setImageBitmap(img); // Teraz jest zeskalowana
                    ikonka.setImageBitmap(Bitmap.createScaledBitmap(img, 200, 200, false));

                }*/

                miasto.setText(pogoda.lokalizacja.getMiasto() + "," + pogoda.lokalizacja.getKraj());
                opisWarunkow.setText(pogoda.warunkiPogodowe.getOpis());
                temperatura.setText("" + Math.round((pogoda.temperatura.getTemperatura() - 273.15)) + "°C");
                wilgotnosc.setText("" + pogoda.warunkiPogodowe.getWilgotnosc() + "%");
                cisnienie.setText("" + pogoda.warunkiPogodowe.getCisnienie() + " hPa");
                predkoscWiatru.setText("" + pogoda.wiatr.getPredkosc() + " m/s");
                windDeg.setText("" + pogoda.wiatr.getDeg() + "°");

            }
            else
            {
                miasto.setText("Zle miasto");
                opisWarunkow.setText("Zle miasto");
                temperatura.setText("Zle miasto");
                wilgotnosc.setText("Zle miasto");
                cisnienie.setText("Zle miasto");
                predkoscWiatru.setText("Zle miasto");
                windDeg.setText("Zle miasto");
            }

            cancel(true);

        }
    }



}


 
0

Wrzuć logi z LogCata

1

Prawdopodobnie dostajesz z gdzieś z serwera null którego nie obsługujesz albo przychodzi coś z czym parser sobie nie radzi. Ale tylko mając treść błedu będziemy wiedzieć na 100%.

0

Aplikacja dziwnym trafem przestała crashować, na jakieś 200 zapytań scrashowała mi tylko raz przy uruchamianiu. Jeśli błąd wróci, będę pisał w tym wątku. Teraz nie mogę po prostu wygenerować logu z błędem. Co do tego nulla, serwer może zwrócić mi co najwyżej taki komunikat taki jak tu: http://api.openweathermap.org/data/2.5/weather?q=blalldslfs
Ale program jest ustawiony tak, że jeśli strumień danych przyjmie mniej niż 200 znaków ustawia wszystko na złe miasto, a tak jest w tym przypadku. Tak czy siak zauważyłem, że apka łapie crasha gdy jest zainstalowana na telefonie i telefon zostanie ponownie uruchomiony, czyli tak jakby pierwsze uruchomienie podczas pracy androida.

0

Odświeżam.
Dorzucam logi z logcata w trakcie crashu. Rzeczywiście jest nullpointer ale nie w parserze. Linia 159 to "if(data.length()>200) {"

05-27 19:18:13.722  14566-14566/com.example.sebastian.pogodainfo D/libEGL﹕ loaded /system/lib/egl/libEGL_mali.so
05-27 19:18:13.722  14566-14566/com.example.sebastian.pogodainfo D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_mali.so
05-27 19:18:13.732  14566-14566/com.example.sebastian.pogodainfo D/libEGL﹕ loaded /system/lib/egl/libGLESv2_mali.so
05-27 19:18:13.752  14566-14566/com.example.sebastian.pogodainfo D/OpenGLRenderer﹕ Enabling debug mode 0
05-27 19:18:19.288  14566-14569/com.example.sebastian.pogodainfo D/dalvikvm﹕ GC_CONCURRENT freed 195K, 10% free 9542K/10503K, paused 20ms+21ms, total 113ms
05-27 19:18:30.619  14566-14566/com.example.sebastian.pogodainfo W/IInputConnectionWrapper﹕ getSelectedText on inactive InputConnection
05-27 19:18:30.619  14566-14566/com.example.sebastian.pogodainfo W/IInputConnectionWrapper﹕ setComposingText on inactive InputConnection
05-27 19:18:30.639  14566-14566/com.example.sebastian.pogodainfo W/IInputConnectionWrapper﹕ getExtractedText on inactive InputConnection
05-27 19:18:42.470  14566-14569/com.example.sebastian.pogodainfo D/dalvikvm﹕ GC_CONCURRENT freed 431K, 12% free 9552K/10759K, paused 12ms+4ms, total 36ms
05-27 19:19:07.766  14566-14569/com.example.sebastian.pogodainfo D/dalvikvm﹕ GC_CONCURRENT freed 429K, 11% free 9588K/10759K, paused 12ms+13ms, total 46ms
05-27 19:19:17.096  14566-14569/com.example.sebastian.pogodainfo D/dalvikvm﹕ GC_CONCURRENT freed 404K, 11% free 9587K/10759K, paused 13ms+13ms, total 45ms
05-27 19:19:29.588  14566-14569/com.example.sebastian.pogodainfo D/dalvikvm﹕ GC_CONCURRENT freed 386K, 11% free 9597K/10759K, paused 12ms+14ms, total 44ms
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ java.io.FileNotFoundException: http://api.openweathermap.org/data/2.5/weather?q=hh-hhh-g
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:177)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at com.example.sebastian.pogodainfo.KlientHTTP.getWeatherData(KlientHTTP.java:31)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at com.example.sebastian.pogodainfo.MainActivity$JSONPogodaTask.doInBackground(MainActivity.java:159)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at com.example.sebastian.pogodainfo.MainActivity$JSONPogodaTask.doInBackground(MainActivity.java:151)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:287)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
05-27 19:19:32.901  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:137)
05-27 19:19:32.911  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
05-27 19:19:32.911  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
05-27 19:19:32.911  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
05-27 19:19:32.911  14566-14631/com.example.sebastian.pogodainfo W/System.err﹕ at java.lang.Thread.run(Thread.java:856)
05-27 19:19:32.911  14566-14631/com.example.sebastian.pogodainfo W/dalvikvm﹕ threadid=16: thread exiting with uncaught exception (group=0x417882a0)
05-27 19:19:32.931  14566-14631/com.example.sebastian.pogodainfo E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #5
    java.lang.RuntimeException: An error occured while executing doInBackground()
            at android.os.AsyncTask$3.done(AsyncTask.java:299)
            at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
            at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)
     Caused by: java.lang.NullPointerException
            at com.example.sebastian.pogodainfo.MainActivity$JSONPogodaTask.doInBackground(MainActivity.java:160)
            at com.example.sebastian.pogodainfo.MainActivity$JSONPogodaTask.doInBackground(MainActivity.java:151)
            at android.os.AsyncTask$2.call(AsyncTask.java:287)
            at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
            at java.util.concurrent.FutureTask.run(FutureTask.java:137)
            at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
            at java.lang.Thread.run(Thread.java:856)

EDIT: Działa, dodałem obsługę wyjątku. Wygląda na to, że raz na jakiś czas serwer oddaje złe odpowiedzi.

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