3

当客户端向服务器发送请求时,我想显示一个进度对话框..请求应该在后台完成......但是当我使用 AsyncTask 时我正在强制关闭..请帮助..谢谢

package com.example.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public static ProgressDialog Dialog;
    String s1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.button1).setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // sendreq();
                new SendUserTask().execute();
            }
        });
    }

    public String sendreq() {
        try {
            // TODO Auto-generated method stub
            SocketAddress sockaddr = new InetSocketAddress("192.168.7.116",
                    9011);
            Socket serversocket = new Socket();
            serversocket.connect(sockaddr, 10000);
            serversocket.setSoTimeout(10000);

            DataOutputStream out = new DataOutputStream(
                    serversocket.getOutputStream());
            out.flush();

            DataInputStream in = new DataInputStream(
                    serversocket.getInputStream());
            out.flush();
            String msg = "";

            msg = "hi";
            out.writeBytes(msg);
            out.flush();
            byte[] message = new byte[100];
            in.read(message);
            s1 = new String(message);
            Toast.makeText(getApplicationContext(), s1, Toast.LENGTH_LONG)
                    .show();

            ((TextView) findViewById(R.id.textView1)).setText(s1);
            in.close();
            out.close();
            serversocket.close();
        } catch (Exception e) {
            Toast.makeText(getApplicationContext(), String.valueOf(e),
                    Toast.LENGTH_LONG).show();
        }
        return null;
    }

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

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            Dialog = ProgressDialog.show(MainActivity.this, "",
                    "Logging In....", true);

            super.onPreExecute();
        }

        protected void onPostExecute(String s) {

            if (Dialog.isShowing())
                Dialog.dismiss();
        }

        @Override
        protected String doInBackground(Void... params) {
            // TODO Auto-generated method stub
            try {
                return sendreq();

            } catch (Exception e) {
                Toast.makeText(getApplicationContext(), String.valueOf(e),
                        Toast.LENGTH_SHORT).show();
            }
            return null;
        }
    }

}
4

3 回答 3

3

((TextView) findViewById(R.id.textView1)).setText(s1);是从后台线程执行的。您无法访问 UI 线程之外的 UI 元素。

您需要将该部分移动到 onProgressUpdate 或 onPostExecute,或者在 runOnUiThread Runnable 中运行它。

于 2012-10-08T14:32:30.820 回答
0

doInBackgorund()是一个非 UI 线程,您无法访问其中的 UI 元素。doInBackground() 中的代码在一个单独的非 UI 线程上运行,该线程无法访问布局中定义的 UI 元素。此外,由于您通过意图调用另一个 Activity,因此您应该始终牢记 Activity 在 UI 线程上运行,因此您永远不应该从非 UI 线程内启动另一个 Activity。

((TextView) findViewById(R.id.textView1)).setText(s1);因此,删除从 doInBackground() 内部访问 UI 元素的代码“ ”,而是将其放入内部onPostExecute(),这是一个 UI 线程,在 doInBackground() 完成后台处理后调用。

于 2012-10-08T16:20:35.900 回答
0

好的....在谷歌搜索了很多之后,我终于明白你不能从主线程访问 UI 元素到一个新的非 UI 线程......所以你不能使用像 textview 甚至 getApplicationContext mtd tht v 用于 toast 的元素在 dobackground mtd 甚至在 dobackground 正在调用的任何其他 mts 中......这也适用于使用 runnable 的新 Thread() ......谢谢 njzk2 的帮助:)

于 2012-10-09T09:16:53.573 回答