java.lang.RuntimeException:无法在未调用 Looper.prepare() 的线程上进行祝酒

Pri*_*oes 4 javascript java android toast android-studio

我正在按照 Udemy 的教程制作天气应用程序。这也是我第一次使用 JSON 数据,所以我不确定这是否会影响我的情况。然而,每次我运行我的应用程序时,它都会打开;当我按下应该显示给定城市天气的按钮时,应用程序崩溃了。

\n\n

我研究了 Looper.prepare() 因为它包含在错误中,但是添加循环程序不起作用(我是编码新手,我可能做得不正确)我也尝试添加 runOnUiThread (新的 Runnable) 无济于事(我可能又做错了)。

\n\n
    public class MainActivity extends AppCompatActivity {\n\n    EditText editText;\n    TextView resultTextView;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        editText = findViewById(R.id.editText);\n        resultTextView = findViewById(R.id.resultTextView);\n\n    }\n\n    public void getWeather(View view) {\n        try {\n            DownloadTask task = new DownloadTask();\n            String encodedCityName = \nURLEncoder.encode(editText.getText().toString(), "UTF-8");\n\n            task.execute("http://openweathermap.org/data/2.5/weather?q=" \n+ encodedCityName + "&appid=b1b15e88fa797225412429c1c50c122a1");\n\n            InputMethodManager mgr = (InputMethodManager) \ngetSystemService(Context.INPUT_METHOD_SERVICE);\n            mgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);\n        } catch (Exception e) {\n            e.printStackTrace();\n            Toast.makeText(getApplicationContext(), "Could not find \nweather :(", Toast.LENGTH_SHORT).show();\n        }\n    }\n\n    public class DownloadTask extends AsyncTask<String, Void, String> {\n\n\n        @Override\n        protected String doInBackground(String... urls) {\n            String result = "";\n            URL url;\n            HttpURLConnection urlConnection = null;\n            try {\n\n                url = new URL(urls[0]);\n                urlConnection = (HttpURLConnection) url.openConnection();\n                InputStream in = urlConnection.getInputStream();\n                InputStreamReader reader = new InputStreamReader(in);\n                int data = reader.read();\n\n                while (data != -1) {\n                    char current = (char) data;\n                    result += current;\n                    data = reader.read();\n                }\n\n                return result;\n\n            } catch (Exception e) {\n                e.printStackTrace();\n\n                Toast.makeText(getApplicationContext(), "Could not find \nweather :(", Toast.LENGTH_SHORT).show();\n                return null;\n            }\n        }\n\n        @Override\n        protected void onPostExecute(String s) {\n            super.onPostExecute(s);\n\n            Looper.prepare();\n            try {\n                JSONObject jsonObject = new JSONObject(s);\n\n                String weatherInfo = jsonObject.getString("weather");\n\n                Log.i("Weather content", weatherInfo);\n\n                JSONArray arr = new JSONArray(weatherInfo);\n\n                String message = "";\n\n                for (int i = 0; i < arr.length(); i++) {\n                    JSONObject jsonPart = arr.getJSONObject(i);\n\n                  String main = jsonPart.getString("main");\n                  String description = jsonPart.getString("description");\n\n                    if (!main.equals("") && !description.equals("")) {\n                        message += main + ": " + description + "\\r\\n";\n                    }\n                }\n\n                if (!message.equals("")) {\n                    resultTextView.setText(message);\n                } else {\n                    Toast.makeText(getApplicationContext(), "Could not \n                    find weather :(", Toast.LENGTH_SHORT).show();\n                }\n\n            } catch (Exception e) {\n\n                Toast.makeText(getApplicationContext(), "Could not find \n                weather :(", Toast.LENGTH_SHORT).show();\n\n                e.printStackTrace();\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的 Logcat 中出现的错误

\n\n
2019-09-11 13:24:52.431 \n7574-7658/com.example.whatstheweather E/AndroidRuntime: FATAL EXCEPTION: \nAsyncTask #1\n\nProcess: com.example.whatstheweather, PID: 7574\njava.lang.RuntimeException: An error occurred while executing \ndoInBackground()\n        at android.os.AsyncTask$4.done(AsyncTask.java:399)\n        at \n    java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)\n    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)\n    at java.util.concurrent.FutureTask.run(FutureTask.java:271)\n    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)\n    at java.lang.Thread.run(Thread.java:919)\n\nCaused by: java.lang.RuntimeException: Can\'t toast on a thread that has \nnot called Looper.prepare()\n    at android.widget.Toast$TN.<init>(Toast.java:407)\n    at android.widget.Toast.<init>(Toast.java:121)\n    at android.widget.Toast.makeText(Toast.java:286)\n    at android.widget.Toast.makeText(Toast.java:276)\n\natcom.example.whatstheweather.MainActivity$DownloadTask. \ndoInBackground(MainActivity.java:81)\natcom.example.whatstheweather.MainActivity$DownloadTask. \ndoInBackground(MainActivity.java:53)\n    at android.os.AsyncTask$3.call(AsyncTask.java:378)\n    at java.util.concurrent.FutureTask.run(FutureTask.java:266)\n    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)\xc2\xa0\n    atjava.util.concurrent.ThreadPoolExecutor. \n    runWorker(ThreadPoolExecutor.java:1167)\xc2\xa0\n\natjava.util.concurrent.ThreadPoolExecutor$Worker. \nrun(ThreadPoolExecutor.java:641)\xc2\xa0\n    at java.lang.Thread.run(Thread.java:919)\xc2\xa0\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下内容来自“运行”选项卡

\n\n
E/AndroidRuntime: FATAL EXCEPTION: main\n    Process: com.example.whatstheweather, PID: 11228\n    java.lang.IllegalStateException: Could not execute method for \n    android:onClick\n    at \nandroidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. \nonClick(AppCompatViewInflater.java:390)\n    at android.view.View.performClick(View.java:7140)\n    at android.view.View.performClickInternal(View.java:7117)\n    at android.view.View.access$3500(View.java:801)\n    at android.view.View$PerformClick.run(View.java:27351)\n    at android.os.Handler.handleCallback(Handler.java:883)\n    at android.os.Handler.dispatchMessage(Handler.java:100)\n    at android.os.Looper.loop(Looper.java:214)\n    at android.app.ActivityThread.main(ActivityThread.java:7356)\n    at java.lang.reflect.Method.invoke(Native Method)\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. \nrun(RuntimeInit.java:492)\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)\n Caused by: java.lang.reflect.InvocationTargetException\n    at java.lang.reflect.Method.invoke(Native Method)\n    at \nandroidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. \nonClick(AppCompatViewInflater.java:385)\n    at android.view.View.performClick(View.java:7140)\xc2\xa0\n    at android.view.View.performClickInternal(View.java:7117)\xc2\xa0\n    at android.view.View.access$3500(View.java:801)\xc2\xa0\n    at android.view.View$PerformClick.run(View.java:27351)\xc2\xa0\n    at android.os.Handler.handleCallback(Handler.java:883)\xc2\xa0\n    at android.os.Handler.dispatchMessage(Handler.java:100)\xc2\xa0\n    at android.os.Looper.loop(Looper.java:214)\xc2\xa0\n    at android.app.ActivityThread.main(ActivityThread.java:7356)\xc2\xa0\n    at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. \nrun(RuntimeInit.java:492)\xc2\xa0\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)\xc2\xa0\n Caused by: java.lang.RuntimeException: Only one Looper may be created \nper thread\n    at android.os.Looper.prepare(Looper.java:108)\n    at android.os.Looper.prepare(Looper.java:103)\n    at \ncom.example.whatstheweather.MainActivity.getWeather(MainActivity.java:43)\n    at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n    at \nandroidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener. \nonClick(AppCompatViewInflater.java:385)\xc2\xa0\n    at android.view.View.performClick(View.java:7140)\xc2\xa0\n    at android.view.View.performClickInternal(View.java:7117)\xc2\xa0\n    at android.view.View.access$3500(View.java:801)\xc2\xa0\n    at android.view.View$PerformClick.run(View.java:27351)\xc2\xa0\n    at android.os.Handler.handleCallback(Handler.java:883)\xc2\xa0\n    at android.os.Handler.dispatchMessage(Handler.java:100)\xc2\xa0\n    at android.os.Looper.loop(Looper.java:214)\xc2\xa0\n    at android.app.ActivityThread.main(ActivityThread.java:7356)\xc2\xa0\n    at java.lang.reflect.Method.invoke(Native Method)\xc2\xa0\n    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller. \nrun(RuntimeInit.java:492)\xc2\xa0\n    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)\n
Run Code Online (Sandbox Code Playgroud)\n

小智 5

您的Toast.makeText方法应该在主线程上调用。你可以这样做:

runOnUiThread(new Runnable() {
    public void run() {
        Toast.makeText(getApplicationContext(), "Could not find weather :(", Toast.LENGTH_SHORT).show();
    }
});
Run Code Online (Sandbox Code Playgroud)