在新线程中出现android.os.networkonmainthreadexception

11

我知道自从 Android 3.0 开始,不能在主线程中进行网络操作。因此,我将我的调用放在了一个新的 Thread 中:

button.setOnClickListener(new OnClickListener() {

    @Override
    public void onClick(View v) {
        user=login.getText().toString();
        password=pass.getText().toString();
        params.add(new BasicNameValuePair("user", user));
        params.add(new BasicNameValuePair("pass", password));
        Thread thread=new Thread(){
            public void run(){
                try {
                    // Throws exception here
                    response=CustomHttpClient.executeHttpPost(urlogin, params); 
                    response=response.replaceAll("\\s+","");

                } catch (Exception e) {
                    e.printStackTrace();
                }
                if(response.equals("ok")){

                    Intent home=new Intent(c, HomeActivity.class);
                    home.putExtra("username", user);
                    startActivity(home);
                    Toast toast=Toast.makeText(
                        c, getString(R.string.welcome), Toast.LENGTH_LONG);
                    toast.show();
                }else{
                    if(response.equals("fallo")){
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                Toast toast=Toast.makeText(
                                    c, R.string.nologin, Toast.LENGTH_LONG);
                                toast.show();
                                login.setText("");
                                pass.setText("");
                            }
                        });
                    }else if(response.equals("nologin")){
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                Toast toast=Toast.makeText(
                                    c, R.string.nouser, Toast.LENGTH_LONG);
                                toast.show();
                                login.setText("");
                                pass.setText("");

                            }
                        });
                    }
                }
            }
        };
        thread.run();
    }
});

但是,尽管我不是在主线程上(或者至少我认为我不是...),我仍然收到了那个异常。

3个回答

52

使用run()并不会启动一个独立的线程,而是在它被启动的同一线程上启动一个可运行对象。

若要启动新线程,你需要使用start()方法。


1
我也遇到了同样的问题,一直找不出为什么会出现这个错误,最后发现就是这个问题。 - tyczj
是的,我也一样。从Java开发中休息一段时间,甚至线程有点让人困惑 :) - Michał Ziobro
请注意,您仍需要在 run() 函数中编写您的代码。start() 中的网络操作也会导致此错误。 - Corbie

0

这些行

Toast toast=Toast.makeText(c, getString(R.string.welcome), Toast.LENGTH_LONG);
toast.show();

需要在 UI 线程 上运行,因为您在下面使用了几次 runOnUiThread()Toast 是一个 UI 元素。


是的,这是另一个错误...但是由于异常,调用甚至没有离开电话。尝试了你的解决方案,但我仍然得到相同的异常。感谢您的答案,并提醒我 :) - Fustigador
@tyczj 你是对的,但我知道那是个问题,并认为问题的作者对此感到困惑。我没有注意到 Thread 是如何启动的...很棒的捕捉 - codeMagic

-2

你可以使用这段代码

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = 
        new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

为了避免异常,对于SDK > 9,您需要在单独的线程上执行网络操作,而不是UI线程,或者您可以使用AsyncTask


这不是处理这个问题的最佳或适当方式。应该像AsyncTask一样使用后台线程,或者像OP那样进行一些更改。 - codeMagic
1
@Fustigador 我知道这是一种不好的做法,但我试着为你提供最快的方式来避免这个异常。 - Nitin Misra

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接