doInBackground()android出错

And*_*omi 0 java android android-asynctask

我试图从一个Android活动(一个简单的登录表单)做一个http请求/响应,但在我完成代码后它给了我一个错误,因为我必须把它放在一个线程,我不熟悉异步任务但我我试图实现它但是,现在当我运行程序并点击提交时,logcat给了我类似的东西

FATAL EXCEPTION: AsyncTask #1
Process: com.example.httpgetandroidexample, PID: 1131
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:6094)
at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:824)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.view.View.requestLayout(View.java:16431)
at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:352)
at android.view.View.requestLayout(View.java:16431)
at android.widget.TextView.checkForRelayout(TextView.java:6600)
at android.widget.TextView.setText(TextView.java:3813)
at android.widget.TextView.setText(TextView.java:3671)
at android.widget.TextView.setText(TextView.java:3646)
at com.example.httpgetandroidexample.MainActivity$AsyncTaskRunner.doInBackground(MainActivity.java:87)
at com.example.httpgetandroidexample.MainActivity$AsyncTaskRunner.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
... 4 more
Run Code Online (Sandbox Code Playgroud)

我不明白为什么!这是我的android活动:

package com.example.httpgetandroidexample;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public TextView content;
    EditText name,pass;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        name = (EditText)findViewById(R.id.name);
        pass = (EditText)findViewById(R.id.pass);
        content = (TextView)findViewById(R.id.text);

        Button button=(Button)findViewById(R.id.but);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AsyncTaskRunner runner = new AsyncTaskRunner();
                runner.execute();
            }
        });


    }
    class AsyncTaskRunner extends AsyncTask<String, String, String> {

        private String resp;

        @Override
        protected String doInBackground(String... params) {
            publishProgress("Working..."); // Calls onProgressUpdate()
            try{ 

                // URLEncode user defined data

                String nameValue    = URLEncoder.encode(name.getText().toString(), "UTF-8");
                String passValue    = URLEncoder.encode(pass.getText().toString(), "UTF-8");

                // Create http cliient object to send request to server

                HttpClient Client = new DefaultHttpClient();

                // Create URL string

                String URL = "http://localhost:8080/login/web?user="+nameValue+"&pass="+passValue;

                //Log.i("httpget", URL);

                try
                {
                    String SetServerString = "";

                    // Create Request to server and get response

                    HttpGet httpget = new HttpGet(URL);
                    ResponseHandler<String> responseHandler = new BasicResponseHandler();
                    SetServerString = Client.execute(httpget, responseHandler);

                    // Show response on activity 

                    content.setText(SetServerString);
                }
                catch(Exception ex)
                {
                    content.setText("fail");
                    System.out.println(ex);
                    resp="fail";
                }
            }
            catch(UnsupportedEncodingException ex)
            {
                content.setText("FailAndroid!");
                resp="fail";
            } 
            return resp;
        }
        @Override
        protected void onPostExecute(String result) {
            content.setText(result);
        }
        protected void onPreExecute() {
        }

        @Override
        protected void onProgressUpdate(String... text) {
            content.setText(text[0]);

        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我的代码显示没有错误,甚至没有警告,但是当我按下提交按钮时,它会在"工作"消息出现后强制关闭,是否有人知道为什么?先感谢您

在你的帮助下(谢谢大家!)我修改了我的活动代码,如下所示:

package com.example.httpgetandroidexample;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

               public TextView content;
                EditText name,pass;

            @Override
            protected void onCreate(Bundle savedInstanceState) {

                      super.onCreate(savedInstanceState);
                     setContentView(R.layout.activity_main);

                     name      =  (EditText)findViewById(R.id.name);
                     pass       =  (EditText)findViewById(R.id.pass);
                     content       =  (TextView)findViewById(R.id.text);

                   Button button=(Button)findViewById(R.id.but);

                   button.setOnClickListener(new View.OnClickListener() {
                       @Override
                       public void onClick(View v) {
                        AsyncTaskRunner runner = new AsyncTaskRunner();
                        runner.execute();
                       }
                      });


   }
            class AsyncTaskRunner extends AsyncTask<String, String, String> {

              private String resp;

              @Override
              protected String doInBackground(String... params) {
               publishProgress("Working..."); // Calls onProgressUpdate()
              try{ 

                                     // URLEncode user defined data

                                       String nameValue    = URLEncoder.encode(name.getText().toString(), "UTF-8");
                                       String passValue    = URLEncoder.encode(pass.getText().toString(), "UTF-8");

                                    // Create http cliient object to send request to server

                                       HttpClient Client = new DefaultHttpClient();

                                    // Create URL string

                                     String URL = "http://localhost:8080/login/web?user="+nameValue+"&pass="+passValue;

                                    //Log.i("httpget", URL);

                                   try
                                    {
                                                  String SetServerString = "";

                                                // Create Request to server and get response

                                                  HttpGet httpget = new HttpGet(URL);
                                                 ResponseHandler<String> responseHandler = new BasicResponseHandler();
                                                 SetServerString = Client.execute(httpget, responseHandler);

                                                  // Show response on activity 

                                                return SetServerString;
                                     }
                                   catch(Exception ex)
                                      {
                                     Log.i("MyActivity","Exception");
                                       }
                                }
                              catch(UnsupportedEncodingException ex)
                               {

                                   Log.i("MyActivity","UnsupportedEncodingException");
                                } 
              return resp;
                            }
              @Override
              protected void onPostExecute(String result) {
               content.setText(result);
              }
              protected void onPreExecute() {
              }

              @Override
              protected void onProgressUpdate(String... text) {
               content.setText(text[0]);

              }
             }
}
Run Code Online (Sandbox Code Playgroud)

但现在我得到了我的 Log.i("MyActivity","Exception");信息,我还在做错什么?

UPDATE

而对于我的最后一次尝试,我再次修改了代码,然后在线阅读了一些教程,这就是我所做的

package com.example.httpgetandroidexample;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;

import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

               public TextView content;
                EditText name,pass;
                String URL;
            @Override
            protected void onCreate(Bundle savedInstanceState) {

                      super.onCreate(savedInstanceState);
                     setContentView(R.layout.activity_main);

                     name      =  (EditText)findViewById(R.id.name);
                     pass       =  (EditText)findViewById(R.id.pass);
                     content       =  (TextView)findViewById(R.id.text);

                   Button button=(Button)findViewById(R.id.but);
                   try {
                    String nameValue    = URLEncoder.encode(name.getText().toString(), "UTF-8");
                       String passValue    = URLEncoder.encode(pass.getText().toString(), "UTF-8");
                       URL = "http://localhost:8080/login/web?user="+nameValue+"&pass="+passValue;
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }

                   button.setOnClickListener(new View.OnClickListener() {
                       @Override
                       public void onClick(View v) {
                        AsyncTaskRunner runner = new AsyncTaskRunner();
                        runner.execute(new String[ ] { URL });
                       }
                      });


   }
            private class AsyncTaskRunner extends AsyncTask<String, Void, String> {


                @Override
                protected String doInBackground(String... urls) {
                  String response = "";
                  for (String url : urls) {
                    DefaultHttpClient client = new DefaultHttpClient();
                    HttpGet httpGet = new HttpGet(url);
                    try {
                      HttpResponse execute = client.execute(httpGet);
                      InputStream content = execute.getEntity().getContent();

                      BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
                      String s = "";
                      while ((s = buffer.readLine()) != null) {
                        response += s;
                      }

                    } catch (Exception e) {
                      e.printStackTrace();
                    }
                  }
                  return response;
                }

                @Override
                protected void onPostExecute(String result) {
                  content.setText(result);
                }
              }
}
Run Code Online (Sandbox Code Playgroud)

这里是详细模式的logcat:

Permission denied (missing INTERNET permission?)
at java.net.InetAddress.lookupHostByName(InetAddress.java:418)
at java.net.InetAddress.getAllByNameImpl(InetAddress.java:236)
at java.net.InetAddress.getAllByName(InetAddress.java:214)
at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:137)
at org.apache.http.impl.conn.AbstractPoolEntry.open(AbstractPoolEntry.java:164)
at org.apache.http.impl.conn.AbstractPooledConnAdapter.open(AbstractPooledConnAdapter.java:119)
at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:360)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:555)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:487)
at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:465)
at com.example.httpgetandroidexample.MainActivity$AsyncTaskRunner.doInBackground(MainActivity.java:69)
at com.example.httpgetandroidexample.MainActivity$AsyncTaskRunner.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by: libcore.io.GaiException: getaddrinfo failed: EAI_NODATA (No address associated with hostname)
at libcore.io.Posix.getaddrinfo(Native Method)
at libcore.io.ForwardingOs.getaddrinfo(ForwardingOs.java:61)
at java.net.InetAddress.lookupHostByName(InetAddress.java:405)
... 17 more
Caused by: libcore.io.ErrnoException: getaddrinfo failed: EACCES (Permission denied)
... 20 more
Run Code Online (Sandbox Code Playgroud)

从我可以理解它缺少的权限,但问题是我有我的清单文件:

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" android:permission="android.permission.INTERNET">
Run Code Online (Sandbox Code Playgroud)

Sha*_*tan 5

Logcat错误:

引起:android.view.ViewRootImpl $ CalledFromWrongThreadException:只有创建视图层次结构的原始线程才能触及其视图.

你尝试使用UI线程doInBackground,

content.setText("fail");
Run Code Online (Sandbox Code Playgroud)

你不能在后台线程中使用onPostExecuteUI 来触摸ui线程中的任何东西

这是你想要的一个样本.

 private class DownloadWebPageTask extends AsyncTask<String, Void, String> {
    @Override
    protected String doInBackground(String... urls) {
      String response = "";
      for (String url : urls) {
        DefaultHttpClient client = new DefaultHttpClient();
        HttpGet httpGet = new HttpGet(url);
        try {
          HttpResponse execute = client.execute(httpGet);
          InputStream content = execute.getEntity().getContent();

          BufferedReader buffer = new BufferedReader(new InputStreamReader(content));
          String s = "";
          while ((s = buffer.readLine()) != null) {
            response += s;
          }

        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      return response;
    }

    @Override
    protected void onPostExecute(String result) {
      textView.setText(result);
    }
  }
Run Code Online (Sandbox Code Playgroud)

你需要从中返回你的String doInBackground

在样本中: return response;

返回,你需要改变:

在样本中:

1- AsyncTask<String, Void, String><--- last value是您希望从本网站获得的doInBackground更多信息

2- protected String doInBackground<---将返回类型更改为String

3 - 返回你的价值 return response;

4- protected void onPostExecute(String result) <---这也必须是String

然后使用UI onPostExecute

在Sample onPostExecute(String result) <--- result中是你的String

来自Vogella文章的复制代码 6.5. Example: AsyncTask

UPDATE

您再次使用UI:

String nameValue    = URLEncoder.encode(name.getText().toString(), "UTF-8");
String passValue    = URLEncoder.encode(pass.getText().toString(), "UTF-8");
Run Code Online (Sandbox Code Playgroud)

如果你想要这个值,你可以将它们发送到asynctask的构造函数或发送为参数doInBackground,我推荐第二种方式

作为try catch语句中的代码,你的应用程序没有关闭,因为你没有打印任何对catch有用的东西你不能得到你的错误,如果你使用catch它更合适的打印错误太像:

catch(UnsupportedEncodingException ex)
 {
    ex.printStackTrace();
 } 
Run Code Online (Sandbox Code Playgroud)

更新2

您在代码中声明您的Android权限如下:

android:permission="android.permission.INTERNET">
Run Code Online (Sandbox Code Playgroud)

但你必须添加你的权限,如:

<manifest xlmns:android...>
 ...
 <uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
Run Code Online (Sandbox Code Playgroud)

你的清单必须像:

<?xml version="1.0" encoding="utf-8"?>
<manifest  
    ......
    ......
    .....>

<uses-sdk
    ...... />

<uses-permission android:name="android.permission.INTERNET" />

<application
     .......
     .......
</application>

</manifest>
Run Code Online (Sandbox Code Playgroud)