0

Iam making a weather app but whenever Iam not entering or entering wrong city name in EditText the app crashes even though I have used try and catch blocks for error handling.The below is the java,xml code and the logs where it is showing a runtime error.

Java

 package com.atul.whatstheweather;

    import android.os.AsyncTask;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.EditText;
    import android.widget.TextView;
    import android.widget.Toast;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.MalformedURLException;
    import java.net.URL;


    public class MainActivity extends AppCompatActivity {

        EditText cityName;
        TextView weatherInfo;


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

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

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

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

                    int data = reader.read();

                    while(data != -1)
                    {
                        char current = (char)data;

                        result += current;

                        data = reader.read();
                    }
                    return result;
                } catch (Exception e) {

                    Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show();

                }
                return null;
            }

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

                try {
                    JSONObject jsonObject = new JSONObject(result);
                    String weatherData = jsonObject.getString("weather");

                    JSONArray array = new JSONArray(weatherData);

                    for(int i=0;i<array.length();i++)
                    {
                        JSONObject jsonPart = array.getJSONObject(i);

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

                        weatherInfo.setText("Weather: "+main+"\n\n"+"Description: "+description);
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }

            }
        }

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


            cityName = (EditText)findViewById(R.id.cityName);
            weatherInfo = (TextView)findViewById(R.id.textView);

        }

        public void clicked(View view)
        {

            Content content = new Content();

            content.execute("https://api.openweathermap.org/data/2.5/weather?q=" + cityName.getText().toString() + "&appid=c20cea76c84b519d67d4e6582064db92");

            Log.i("clicked","is working");
        }


    }

In the Logs given below it is showing Runtime error

Run Logs

05/03 17:35:25: Launching app
Cold swapped changes.
$ adb shell am start -n "com.atul.whatstheweather/com.atul.whatstheweather.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER
Connected to process 18757 on device xiaomi-redmi_note_3-9b51ac51
I/art: Late-enabling -Xcheck:jni
D/TidaProvider: TidaProvider()
W/ReflectionUtils: java.lang.NoSuchMethodException: android.os.MessageQueue#enableMonitor()#bestmatch
                       at miui.util.ReflectionUtils.findMethodBestMatch(ReflectionUtils.java:338)
                       at miui.util.ReflectionUtils.findMethodBestMatch(ReflectionUtils.java:375)
                       at miui.util.ReflectionUtils.callMethod(ReflectionUtils.java:800)
                       at miui.util.ReflectionUtils.tryCallMethod(ReflectionUtils.java:818)
                       at android.os.BaseLooper.enableMonitor(BaseLooper.java:47)
                       at android.os.Looper.prepareMainLooper(Looper.java:111)
                       at android.app.ActivityThread.main(ActivityThread.java:5586)
                       at java.lang.reflect.Method.invoke(Native Method)
                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:774)
                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:652)
W/ResourceType: No package identifier when getting name for resource number 0x00000000
W/System: ClassLoader referenced unknown path: /data/app/com.atul.whatstheweather-1/lib/arm64
I/InstantRun: Instant Run Runtime started. Android package is com.atul.whatstheweather, real application class is null.
W/System: ClassLoader referenced unknown path: /data/app/com.atul.whatstheweather-1/lib/arm64
W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
D/AccessibilityManager: current package=com.atul.whatstheweather, accessibility manager mIsFinalEnabled=false, mOptimizeEnabled=false, mIsUiAutomationEnabled=false, mIsInterestedPackage=false
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@9df51ef
V/BoostFramework: BoostFramework() : mPerf = com.qualcomm.qti.Performance@ce6e4fc
D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
I/Adreno: QUALCOMM build                   : a7823f5, I59a6815413
          Build Date                       : 09/23/16
          OpenGL ES Shader Compiler Version: XE031.07.00.00
          Local Branch                     : mybranch22028469
          Remote Branch                    : quic/LA.BR.1.3.3_rb2.26
          Remote Branch                    : NONE
          Reconstruct Branch               : NOTHING
I/OpenGLRenderer: Initialized EGL, version 1.4
E/HAL: hw_get_module_by_class: module name gralloc
E/HAL: hw_get_module_by_class: module name gralloc
I/clicked: is working
I/DpmTcmClient: RegisterTcmMonitor from: com.android.okhttp.TcmIdleTimerMonitor
E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
                  Process: com.atul.whatstheweather, PID: 18757
                  java.lang.RuntimeException: An error occurred while executing doInBackground()
                      at android.os.AsyncTask$3.done(AsyncTask.java:309)
                      at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:354)
                      at java.util.concurrent.FutureTask.setException(FutureTask.java:223)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:242)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234)
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
                      at java.lang.Thread.run(Thread.java:818)
                   Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
                      at android.os.Handler.<init>(Handler.java:200)
                      at android.os.Handler.<init>(Handler.java:114)
                      at android.widget.Toast$TN.<init>(Toast.java:356)
                      at android.widget.Toast.<init>(Toast.java:101)
                      at android.widget.Toast.makeText(Toast.java:266)
                      at com.atul.whatstheweather.MainActivity$Content.doInBackground(MainActivity.java:60)
                      at com.atul.whatstheweather.MainActivity$Content.doInBackground(MainActivity.java:31)
                      at android.os.AsyncTask$2.call(AsyncTask.java:295)
                      at java.util.concurrent.FutureTask.run(FutureTask.java:237)
                      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 
                      at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113) 
                      at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588) 
                      at java.lang.Thread.run(Thread.java:818) 
I/Process: Sending signal. PID: 18757 SIG: 9
Application terminated.
  • doInBackground method of AsyncTask class runs on a separate thread not on UI thread. You can not display a Toast inside this function . Remove `Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show();` from Catch block. – Alpha 1 May 03 '20 at 12:36
  • You should try retrofit, viewmodels and livedata. And avoid to overload your class with more than one responsability. – Ricardo May 03 '20 at 17:46

2 Answers2

0

App crashes because you are calling Toast in background thread.

Replace your Toast line in catch block Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show(); with :

    new Handler(Looper.getMainLooper()).post(new Runnable() {
        @Override
        public void run() {
            Toast.makeText(MainActivity.this, "URL malfunctioned", Toast.LENGTH_SHORT).show();
        }
    });
Nilesh B
  • 937
  • 1
  • 9
  • 14
-1

Just delete the Toast.makeText

Peyman Mohamadpour
  • 17,954
  • 24
  • 89
  • 100
Murad
  • 104
  • 1
  • 1
  • 10