0

So i'm into a tutorial at Udemy "The Complete Android N Developer Course" and trying to make lecture 86 about a weather app.

I use the API from here https://openweathermap.org/current#cityid and use JSON to get the data needed.

The app is working properly when i input a correct city name, but when the input is wrong or empty the app crashes without catching any exceptions.

I don't know why it is crashing and where to look. So i give you all the code i wrote. I tried to implement if statements here and there to try and find it but without any luck.

I would like to know where the problem is and how to fix it so the app doesn't crash anymore.

Thanks in advance.

public class MainActivity extends AppCompatActivity {

    EditText editText;
    String city = "";
    TextView textView;

    public void getWeather (View view)  {
        try {
            city = URLEncoder.encode(editText.getText().toString(), "UTF-8");

            if (editText.getText().toString() == "") {
                Toast.makeText(MainActivity.this, "Could not find weather", Toast.LENGTH_SHORT).show();
                textView.setText("Please enter a city.");
            } else  {
                DownloadTask task = new DownloadTask();
                task.execute("http://api.openweathermap.org/data/2.5/weather?q=" + city + "&appid=c6ef169a79d84674ef7e1414301eb5c4");
            }

            InputMethodManager mgr = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
            mgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);

        } catch (UnsupportedEncodingException e1) {
            Toast.makeText(MainActivity.this, "UnsupportedEncodingException", Toast.LENGTH_SHORT).show();
        }catch (Exception e) {
            Toast.makeText(MainActivity.this, "General exception (getWeather)", Toast.LENGTH_SHORT).show();
        }
    }


    public class DownloadTask extends AsyncTask<String, Void, String> {

        @Override
        protected String doInBackground(String... urls) {

            String result = "";
            URL url;
            HttpURLConnection urlConnection = null;

            try {
                url = new URL(urls[0]);
                urlConnection = (HttpURLConnection)url.openConnection();
                InputStream in = null;
                in = urlConnection.getInputStream();
                InputStreamReader reader = new InputStreamReader(in);

                int data = reader.read();
                while (data != -1) {
                    char current = (char) data;
                    result += current;
                    data = reader.read();
                }
                return result;
            } catch (MalformedURLException e1) {
                Toast.makeText(MainActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
            } catch (IOException e2) {
            Toast.makeText(MainActivity.this, "IOException", Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                Toast.makeText(MainActivity.this, "General exception (doInBackground)", Toast.LENGTH_SHORT).show();
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            super.onPostExecute(result);

            try {
                String message = "";
                JSONObject jsonObject = null;
                jsonObject = new JSONObject(result);
                String weatherInfo = jsonObject.getString("weather");
                JSONArray jsonArray = new JSONArray(weatherInfo);

                for (int i = 0; i < jsonArray.length(); i++)    {

                    JSONObject jsonPart = jsonArray.getJSONObject(i);
                    String main = "";
                    String description = "";

                    main = jsonPart.getString("main");
                    description = jsonPart.getString("description");

                    if (main != "" && description != "")    {
                        message += main + ": " + description + "\r\n";
                    }
                }

                if (message != "") {
                    textView.setText(message);
                } else  {
                    Toast.makeText(MainActivity.this, "Could not find weather", Toast.LENGTH_SHORT).show();
                }
            } catch (JSONException e1) {
                Toast.makeText(MainActivity.this, "JSONException", Toast.LENGTH_SHORT).show();
            } catch (Exception e) {
                Toast.makeText(MainActivity.this, "General exception (onPostExecute)", Toast.LENGTH_SHORT).show();
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        editText = (EditText) findViewById(R.id.editText);
        textView = (TextView) findViewById(R.id.textView);

    }
}
Kevin Robatel
  • 8,025
  • 3
  • 44
  • 57
Geokiren
  • 34
  • 6
  • What happens if you take the try catch block out? – Toofy Mar 25 '19 at 17:20
  • you still can check the error in Android Studio even though you are using phone instead of emulator. – John Joe Mar 25 '19 at 17:21
  • It requires the try and catch blocks or the app doesn't run at all. I'll look into android studio for errors, thanks John Joe. – Geokiren Mar 25 '19 at 17:26
  • check the error and post here – John Joe Mar 25 '19 at 17:28
  • 3
    Guess you have an exception in the asynctask running on worker thread, and trying to display a toast on a non-UI thread crashes the app. Remove the try-catch to crash the app with the root cause issue and fix that. – laalto Mar 25 '19 at 17:30
  • it must be cause of changing UI from background thread.. remove toast from doinBackground().. if you really want to display that toast run in using new Runnable.. – Masoom Badi Mar 25 '19 at 17:53
  • Indeed the problem was Toast in 'doInBackground'. I replaced it with 'e.printStackTrace();'. Now i understand and everything works as expected. Thanks a lot everyone :D – Geokiren Mar 25 '19 at 18:46
  • 1
    You should check the logcat. It's always say you what crash the application. – Kevin Robatel Mar 25 '19 at 18:57

1 Answers1

0

It is because you're trying to changes UI with background thread inside the doInBackground(Params...) method of AsyncTask with this line:

try {
     ...
    return result;
} catch (MalformedURLException e1) {
    Toast.makeText(MainActivity.this, "MalformedURLException", Toast.LENGTH_SHORT).show();
} catch (IOException e2) {
Toast.makeText(MainActivity.this, "IOException", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
    Toast.makeText(MainActivity.this, "General exception (doInBackground)", Toast.LENGTH_SHORT).show();
}

You should not call Toast inside the doInBackground(Params...). Do that inside the onPostExecute(Result).

You can avoid that by either ignoring the error or returning specific text in doInBackground. Something like this:

public class DownloadTask extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... urls) {

        String result = "";
        ...

        try {
            ...
            return result;
        } catch (MalformedURLException e1) {
            result= "MalformedURLException";
        } catch (IOException e2) {
            result= "IOException";
        } catch (Exception e) {
            // do nothing and returning empty
            result= "Exception";
        }
        return result;
    }

    @Override
    protected void onPostExecute(String result) {
        // check if there is an error
        String errorMessage = "";
        switch(result) {
          case "MalformedURLException":
            errorMessage = "MalformedURLException";
            break;
          case ""IOException":
            errorMessage = "IOException";
            break;
          case "Exception":
            errorMessage = "Exception";
            break;
        }

         // there is an error, show a message.
        if(!errorMessage.isEmpty()) {
            Toast.makeText(MainActivity.this, "Could not find weather: " + errorMessage, Toast.LENGTH_SHORT).show();
            return; // stop the process.
        }

         // do something when no error found.

    }
}
ישו אוהב אותך
  • 28,609
  • 11
  • 78
  • 96