title: java.lang.RuntimeException: Can't toast on a thread that has not called Looper.prepare()
body: <p>I am following a tutorial from Udemy to make a weather app. This is my first time working with JSON data as well so I'm not sure if that is impacting my situation. Every time I run my app, it opens, however; when I press the button that is supposed to display the weather of the given city, the app crashes.  </p>
  
  <p>I researched Looper.prepare() as that was included in the error, but adding the looper did not work (I'm new to coding and I may have done so incorrectly) I also tried adding runOnUiThread (new Runnable) to no avail (again I may have done so incorrectly).</p>
  
  <pre><code>    public class MainActivity extends AppCompatActivity {
  
      EditText editText;
      TextView resultTextView;
  
      @Override
      protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
  
          editText = findViewById(R.id.editText);
          resultTextView = findViewById(R.id.resultTextView);
  
      }
  
      public void getWeather(View view) {
          try {
              DownloadTask task = new DownloadTask();
              String encodedCityName = 
  URLEncoder.encode(editText.getText().toString(), "UTF-8");
  
              task.execute("http://openweathermap.org/data/2.5/weather?q=" 
  + encodedCityName + "&amp;appid=b1b15e88fa797225412429c1c50c122a1");
  
              InputMethodManager mgr = (InputMethodManager) 
  getSystemService(Context.INPUT_METHOD_SERVICE);
              mgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);
          } catch (Exception e) {
              e.printStackTrace();
              Toast.makeText(getApplicationContext(), "Could not find 
  weather :(", Toast.LENGTH_SHORT).show();
          }
      }
  
      public class DownloadTask extends AsyncTask&lt;String, Void, String&gt; {
  
  
          @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 = 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 (Exception e) {
                  e.printStackTrace();
  
                  Toast.makeText(getApplicationContext(), "Could not find 
  weather :(", Toast.LENGTH_SHORT).show();
                  return null;
              }
          }
  
          @Override
          protected void onPostExecute(String s) {
              super.onPostExecute(s);
  
              Looper.prepare();
              try {
                  JSONObject jsonObject = new JSONObject(s);
  
                  String weatherInfo = jsonObject.getString("weather");
  
                  Log.i("Weather content", weatherInfo);
  
                  JSONArray arr = new JSONArray(weatherInfo);
  
                  String message = "";
  
                  for (int i = 0; i &lt; arr.length(); i++) {
                      JSONObject jsonPart = arr.getJSONObject(i);
  
                    String main = jsonPart.getString("main");
                    String description = jsonPart.getString("description");
  
                      if (!main.equals("") &amp;&amp; !description.equals("")) {
                          message += main + ": " + description + "\r\n";
                      }
                  }
  
                  if (!message.equals("")) {
                      resultTextView.setText(message);
                  } else {
                      Toast.makeText(getApplicationContext(), "Could not 
                      find weather :(", Toast.LENGTH_SHORT).show();
                  }
  
              } catch (Exception e) {
  
                  Toast.makeText(getApplicationContext(), "Could not find 
                  weather :(", Toast.LENGTH_SHORT).show();
  
                  e.printStackTrace();
              }
          }
      }
  }
  </code></pre>
  
  <p>Here are the errors that appeared in my Logcat</p>
  
  <pre><code>2019-09-11 13:24:52.431 
  7574-7658/com.example.whatstheweather E/AndroidRuntime: FATAL EXCEPTION: 
  AsyncTask #1
  
  Process: com.example.whatstheweather, PID: 7574
  java.lang.RuntimeException: An error occurred while executing 
  doInBackground()
          at android.os.AsyncTask$4.done(AsyncTask.java:399)
          at 
      java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
      at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
      at java.util.concurrent.FutureTask.run(FutureTask.java:271)
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)       atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
      at java.lang.Thread.run(Thread.java:919)
  
  Caused by: java.lang.RuntimeException: Can't toast on a thread that has 
  not called Looper.prepare()
      at android.widget.Toast$TN.&lt;init&gt;(Toast.java:407)
      at android.widget.Toast.&lt;init&gt;(Toast.java:121)
      at android.widget.Toast.makeText(Toast.java:286)
      at android.widget.Toast.makeText(Toast.java:276)
  
  atcom.example.whatstheweather.MainActivity$DownloadTask. 
  doInBackground(MainActivity.java:81)
  atcom.example.whatstheweather.MainActivity$DownloadTask. 
  doInBackground(MainActivity.java:53)
      at android.os.AsyncTask$3.call(AsyncTask.java:378)
      at java.util.concurrent.FutureTask.run(FutureTask.java:266)
      at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289) 
      atjava.util.concurrent.ThreadPoolExecutor. 
      runWorker(ThreadPoolExecutor.java:1167) 
  
  atjava.util.concurrent.ThreadPoolExecutor$Worker. 
  run(ThreadPoolExecutor.java:641) 
      at java.lang.Thread.run(Thread.java:919) 
  </code></pre>
  
  <p><strong>This following is from the Run tab</strong></p>
  
  <pre><code>E/AndroidRuntime: FATAL EXCEPTION: main
      Process: com.example.whatstheweather, PID: 11228
      java.lang.IllegalStateException: Could not execute method for 
      android:onClick
      at 
  androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. 
  onClick(AppCompatViewInflater.java:390)
      at android.view.View.performClick(View.java:7140)
      at android.view.View.performClickInternal(View.java:7117)
      at android.view.View.access$3500(View.java:801)
      at android.view.View$PerformClick.run(View.java:27351)
      at android.os.Handler.handleCallback(Handler.java:883)
      at android.os.Handler.dispatchMessage(Handler.java:100)
      at android.os.Looper.loop(Looper.java:214)
      at android.app.ActivityThread.main(ActivityThread.java:7356)
      at java.lang.reflect.Method.invoke(Native Method)
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. 
  run(RuntimeInit.java:492)
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
   Caused by: java.lang.reflect.InvocationTargetException
      at java.lang.reflect.Method.invoke(Native Method)
      at 
  androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. 
  onClick(AppCompatViewInflater.java:385)
      at android.view.View.performClick(View.java:7140) 
      at android.view.View.performClickInternal(View.java:7117) 
      at android.view.View.access$3500(View.java:801) 
      at android.view.View$PerformClick.run(View.java:27351) 
      at android.os.Handler.handleCallback(Handler.java:883) 
      at android.os.Handler.dispatchMessage(Handler.java:100) 
      at android.os.Looper.loop(Looper.java:214) 
      at android.app.ActivityThread.main(ActivityThread.java:7356) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. 
  run(RuntimeInit.java:492) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930) 
   Caused by: java.lang.RuntimeException: Only one Looper may be created 
  per thread
      at android.os.Looper.prepare(Looper.java:108)
      at android.os.Looper.prepare(Looper.java:103)
      at 
  com.example.whatstheweather.MainActivity.getWeather(MainActivity.java:43)
      at java.lang.reflect.Method.invoke(Native Method) 
      at 
  androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. 
  onClick(AppCompatViewInflater.java:385) 
      at android.view.View.performClick(View.java:7140) 
      at android.view.View.performClickInternal(View.java:7117) 
      at android.view.View.access$3500(View.java:801) 
      at android.view.View$PerformClick.run(View.java:27351) 
      at android.os.Handler.handleCallback(Handler.java:883) 
      at android.os.Handler.dispatchMessage(Handler.java:100) 
      at android.os.Looper.loop(Looper.java:214) 
      at android.app.ActivityThread.main(ActivityThread.java:7356) 
      at java.lang.reflect.Method.invoke(Native Method) 
      at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. 
  run(RuntimeInit.java:492) 
      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
  </code></pre>