2

我有两个简单的类:

public class MainActivity extends Activity {
    NetworkTask task;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        [...]       
        task = new NetworkTask();
        task.execute();
    }

public void myClickHandler(View view) {
    switch(view.getId()) {
        case R.id.button1:
            // Why this line crash?
            task.connection("127.0.0.1");
        break;
        }
    }
}

public class NetworkTask extends AsyncTask<String, Void, String> {
    Socket sock;
    volatile boolean running = true;

    public int connection(String url){
        try{
            sock = new Socket(url, 4567)
        }
        catch (IOException ex){
            Logger.getLogger(NetworkTask.class.getName()).log(Level.SEVERE, null, ex);
            return -1;
        }
    }

    public String doInBackground(String... strings) {

        // If I do this, it works well
        //connection(127.0.0.1);

        while(running)
        {
            [...]
        }

        return null;
    }   
}

正如我在从 AsyncTask 方法外部调用连接方法时评论的那样,应用程序崩溃更特别 « sock = new Socket(...) » 行。但是当在 AsynTask 方法内完成连接调用时,会创建套接字。我不明白为什么。

发生了什么?

谢谢。

4

1 回答 1

4

这是因为当你这样做

task.connection("127.0.0.1");

您仍在主(UI)线程中工作 - 您没有正确使用 AsyncTask。相反,您像普通课程一样使用它,因此,您可以获得NetworkOnMainThreadException新的 Android 版本。

但是,当您调用 from 时doInBackground(),这意味着您通过启动 AsyncTaskexecute并且工作在单独的线程中完成,让一切正常工作。

请记住,如果你在做非网络的事情,你仍然可以从外面打电话。但是,我建议让您的 AsyncTask 尽可能少地依赖外部,因为 AsyncTasks 只运行一次。如果你想做更多的工作,你必须创建一个新实例,这意味着如果你依赖于 setter 方法或类似方法,你必须确保再次调用这些方法,这使得这个简单的类比需要的更复杂。

对于如何使用 AsyncTask,是一个很好的来源。当然还有官方文档

于 2013-02-09T21:11:29.610 回答