0

Android 客户端在 Android 2.2 上运行没有问题。但在 Android 4.2 中我需要使用 AsyncTask,我不知道如何正确设置它。按下按钮时客户端应连接到 TCP 服务器。我已经按照下面的代码进行了尝试,但我遇到了 FATAL EXCEPTION: AsyncTask #1 错误。请你看看我的代码!谢谢。

    // ----------------------- CONNECTION BUTTON EVENTLISTENER - begin ----------------------------
Button.OnClickListener buttonConnectOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View arg0) {



class connectTask extends AsyncTask<String, String, AndroidClientActivity> {
@Override
protected AndroidClientActivity doInBackground(String... message) {





    if(!connected){//if not connected yet
    outputText("connecting to Server");
    try {//try to create a socket and outputstream
    socket = new Socket("192.168.1.112",5353);//create a socket
    dataOutputStream = new DataOutputStream(socket.getOutputStream());//and stream
    outputText("successfully connected");//output the connection status
    changeConnectionStatus(true);//change the connection status
    } catch (UnknownHostException e) {//catch and
    outputText(e.getMessage());//display errors
    changeConnectionStatus(false);
    } catch (IOException e) {//catch and
    outputText(e.getMessage());//display errors
    changeConnectionStatus(false);
    }
    }else{
    outputText("disconnecting from Server...");
    try {//try to close the socket
    socket.close();
    outputText("successfully disconnected");
    changeConnectionStatus(false);//change the connection status
    } catch (UnknownHostException e) {//catch and
    outputText(e.getMessage());//display errors
    } catch (IOException e) {//catch and
    outputText(e.getMessage());//display errors
    }
    }




    return null;
    }

    @Override
    protected void onPostExecute(AndroidClientActivity jh) {



    }}
                new connectTask().execute();            
            }
        };

这是我得到的错误;

04-23 23:27:30.445: E/AndroidRuntime(12005): FATAL EXCEPTION: AsyncTask #1
04-23 23:27:30.445: E/AndroidRuntime(12005): java.lang.RuntimeException: An error occured while executing doInBackground()
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.os.AsyncTask$3.done(AsyncTask.java:278)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.FutureTask.run(FutureTask.java:137)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:208)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.lang.Thread.run(Thread.java:856)
04-23 23:27:30.445: E/AndroidRuntime(12005): Caused by: android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.ViewRootImpl.checkThread(ViewRootImpl.java:4039)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.ViewRootImpl.requestLayout(ViewRootImpl.java:709)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.View.requestLayout(View.java:12863)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.View.requestLayout(View.java:12863)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.View.requestLayout(View.java:12863)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.View.requestLayout(View.java:12863)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.RelativeLayout.requestLayout(RelativeLayout.java:273)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.view.View.requestLayout(View.java:12863)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.TextView.checkForRelayout(TextView.java:6985)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.TextView.setText(TextView.java:3333)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.TextView.setText(TextView.java:3189)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.TextView.append(TextView.java:2849)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.widget.TextView.append(TextView.java:2839)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at com.rovercontrollerandroid.AndroidClientActivity.outputText(AndroidClientActivity.java:249)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at com.rovercontrollerandroid.AndroidClientActivity$3$1connectTask.doInBackground(AndroidClientActivity.java:192)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at com.rovercontrollerandroid.AndroidClientActivity$3$1connectTask.doInBackground(AndroidClientActivity.java:1)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at android.os.AsyncTask$2.call(AsyncTask.java:264)
04-23 23:27:30.445: E/AndroidRuntime(12005):    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
04-23 23:27:30.445: E/AndroidRuntime(12005):    ... 5 more
4

2 回答 2

1

不要尝试doInBackground(...)AsyncTask.

错误出现在 logcat 中“只有创建视图层次结构的原始线程才能触及其视图。” .

doInBackground(...)方法在不同的线程上运行。如果您想显示进度,请将代码移入onProgressUpdate(...)并使用publishProgress(...)from doInBackground(...)

完成后需要访问 UI 的任何其他代码doInBackground(...)都应进入onPostExecute(...).

于 2013-04-23T22:44:10.947 回答
0

从您的 logcat 来看,它看起来像是outputText()一个执行操作的函数UI。看来您想显示进度。用于publishProgress()更新 的onProgressUpdate()方法AsyncTask。你不能UIdoInBackground()

一个简短的例子是

 class connectTask extends AsyncTask<String, String, AndroidClientActivity> {
  ProgressDialog progress = new ProgressDialog(MainActivity.this);  //create progress dialog

 @Override
 protected AndroidClientActivity doInBackground(String... message) {
  publishProgress("message to send");  // put this wherever you are trying to show a message while attempting to download

然后实施

@Override
protected void onProgressUpdate(String... values) {
    progress.setTitle("Trying");
    progress.setMessage(values[0]);  // this will be the value set in `publishProgress() of doINBackground()
    progress.show();
}

progress.dismiss()然后打电话onPostExecute()

于 2013-04-23T22:44:51.090 回答