使用异步任务强制关闭

时间:2012-10-08 14:28:09

标签: android

我想在客户端向服务器发送请求时显示progressdialog ..请求应该在后台完成...但是当我使用AsyncTask时,我会收到一个强制关闭..请帮助..谢谢你< / p>

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;
        }
    }

}

3 个答案:

答案 0 :(得分:3)

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

Ok ....经过google搜索后我终于明白你无法从主线程中访问UI元素到一个新的非UI线程....所以你不能使用像textview这样的元素甚至是getApplicationContext mtd tht v在dobackground mtd中使用toast,甚至在dobackground正在调用的任何其他mts中使用....这也适用于使用runnable的新Thread()。感谢你njzk2的帮助:)