原因:无法在未调用 Looper.prepare() 的线程上敬酒

Posted

技术标签:

【中文标题】原因:无法在未调用 Looper.prepare() 的线程上敬酒【英文标题】:caused by: Can't toast on a thread that has not called Looper.prepare() 【发布时间】:2021-10-06 15:10:52 【问题描述】:

所以每当我在 EditText 中输入城市名称并按下按钮时,我的应用程序就会崩溃并且不显示 toast

在 logcat 中显示此错误:used by: java.lang.NullPointerException: Can't toast on a thread that has not called Looper.prepare()

有谁知道谁来修复这个错误? 我正在使用安卓工作室

package com.example.whatstheweather;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

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

import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;

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.editTextTextPersonName);
        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 + "&APPID=9eebb30a9664baf113136d98e764ffb5");
    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<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 = 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);
            try 
                JSONObject jsonObject = new JSONObject(s);
                String weatherInfo = jsonObject.getString("weather");
                JSONArray arr = new JSONArray(weatherInfo);
                String message = "";
                for (int i = 0; i< arr.length(); i++)
                    JSONObject jsonPart =arr.getJSONObject(i);

                    String main = jsonPart.getString("main");
                    String description = jsonPart.getString("description");
                    if (!main.equals("") && !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)
                e.printStackTrace();
                Toast.makeText(getApplicationContext(),"Could not find weather :(",Toast.LENGTH_SHORT).show();

            
        
    


【问题讨论】:

您在 DownloadTask 内调用 Toast.makeText,它在不同的线程上运行。这就是错误消息告诉您的内容。您只能在主线程上运行 Toaster 【参考方案1】:
 try 
    //add her code
  catch (java.text.ParseException e) 
    runOnUiThread(new Runnable()
      public void run() 
          Toast.makeText(getApplicationContext(),"Please key in 
                      the correct input",    
            Toast.LENGTH_LONG).show();
      
    );
   e.printStackTrace();
    return true; // attention here

【讨论】:

以上是关于原因:无法在未调用 Looper.prepare() 的线程上敬酒的主要内容,如果未能解决你的问题,请参考以下文章

CountDownTimer:“无法在未调用 Looper.prepare() 的线程内创建处理程序”

无法在未调用 Looper.prepare()3 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare() 的线程内创建处理程序

无法在未调用 Looper.prepare()-Alertdialogbox 的线程内创建处理程序 [重复]

无法在未调用 Looper.prepare() Graphhopper 的线程内创建处理程序