【问题标题】:Android : Network on main thread exception even when using AsyncTaskAndroid:即使在使用 AsyncTask 时,主线程上的网络异常
【发布时间】:2015-10-04 12:05:15
【问题描述】:

我正在开发一个 Android 项目,为了登录,我正在与服务器通信以进行身份​​验证。即使我使用的是 AsyncTask,我也会收到 NetworkOnMain 线程异常。这是为什么。这是我的代码:

public class Login extends Activity {

    public static RestTemplate rest = new RestTemplate();
    Button loginButton = (Button) findViewById(R.id.LoginButton);
        loginButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!(v == null)) {
                    EditText userEmail = (EditText) findViewById(R.id.usernameText);
                    EditText userPassword = (EditText) findViewById(R.id.PasswordField);
                    if (!(userEmail.getText().toString().isEmpty())) {
                        if (!(userPassword.getText().toString().isEmpty())) {
                            loginUserViaRest(userEmail.getText().toString(), userPassword.getText().toString());
                            if (!(StaticRestTemplate.jsessionid == null)) {
                                if (!(StaticRestTemplate.jsessionid.isEmpty())) {

                                    executeRestLogin executeRestLogin = new executeRestLogin();
                                    executeRestLogin.doInBackground();

 private class executeRestLogin extends AsyncTask<Void,Void,Void>{

        @Override
        protected Void doInBackground(Void... params) {
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);

// Below line gives me an error
            HttpEntity<String> rssResponse = rest.exchange(
                    "http://192.168.178.60:8080/dashboard",
                    HttpMethod.GET,
                    requestEntity,
                    String.class);
            StaticRestTemplate.jsessionid = rssResponse.getBody();
            return null;
        }
    }

我做错了什么。另外,如何从异步任务中获取自定义对象作为响应?

更新

到下一个问题:

  ExecuteRestLogin executeRestLogin = new ExecuteRestLogin();
// The below execute method works, but I cannot get the result of postExecute in it, it shows me its not of the type Void, Void, String. 
 String result =  executeRestLogin.execute();

private class ExecuteRestLogin extends AsyncTask<Void,Void,String>{

        @Override
        protected String doInBackground(Void... params) {
            HttpHeaders requestHeaders = new HttpHeaders();
            requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
            HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);

            HttpEntity<String> rssResponse = rest.exchange(
                    "http://192.168.178.60:8080/dashboard",
                    HttpMethod.GET,
                    requestEntity,
                    String.class);
            StaticRestTemplate.jsessionid = rssResponse.getBody();
            return StaticRestTemplate.jsessionid;
        }

        @Override
        protected void onPostExecute(String aVoid) {
            super.onPostExecute(aVoid);
        }
    }

【问题讨论】:

  • 实现onPostExecute(.... ).. 参考这个tutorial

标签: java android multithreading android-asynctask


【解决方案1】:

更改您的代码,如:

private class ExecuteRestLogin extends AsyncTask<Void,Void,Boolean> {
 @Override
    protected Boolean doInBackground(Void... params) {
        HttpHeaders requestHeaders = new HttpHeaders();
        requestHeaders.add("Cookie", "JSESSIONID=" + StaticRestTemplate.jsessionid);
        HttpEntity<String> requestEntity = new HttpEntity<>(requestHeaders);

        HttpEntity<String> rssResponse = rest.exchange(
                "http://192.168.178.60:8080/dashboard",
                HttpMethod.GET,
                requestEntity,
                String.class);
        StaticRestTemplate.jsessionid = rssResponse.getBody();
        result = StaticRestTemplate.jsessionid; // result is a global String.
        return true;
    }

 @Override
    protected void onPostExecute(final Boolean success) {
         if (success) {
            //You can use your result string now.
        }
    }
}

【讨论】:

    【解决方案2】:

    您应该将 doInBackground() 替换为 execute()。这样,doInBackground 方法中的代码将在另一个线程中执行。(您不应该创建新线程,Android 会为您创建。)

    【讨论】:

      【解决方案3】:

      您正在从 UI 调用 doInBackground! 为了启动一个AsyncTask,你需要调用executeexecuteRestLogin.execute()

      编辑:

      不要忘记类以大写开头的约定。

      在 AysnTask 对象上调用 execute 将启动任务。这个tutorial会更清楚。

      【讨论】:

      • 它需要一个 Runnable 对象,所以我必须创建一个新线程吗?那么使用 Async 有什么意义,因为我已经可以在一个线程中完成所有这些工作了。
      【解决方案4】:
      executeRestLogin.doInBackground();
      

      调用execute() 在后台线程上执行异步任务。直接调用doInBackground() 只是在当前线程上运行该方法。

      如何从异步任务中获取自定义对象作为响应

      将处理异步任务结果的代码放在onPostExecute()。它在 UI 线程上运行。

      【讨论】:

      • 所以我必须创建一个新线程,如 Thread thread = new Thread(new Runnable( ) ),并在其中调用 doInBackground 方法,但是我可以直接在线程中调用实际代码,为什么那么我应该处理 AsyncTask 的所有这些细微差别吗?
      • 没有。只需将您的doInBackground() 电话替换为execute()。异步任务框架将从那里获取它。
      • 谢谢,成功了。但我无法在 PostExecute 中得到结果。我已经在主帖中更新了我的代码。你能看看吗。
      猜你喜欢
      • 1970-01-01
      • 2013-06-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多