Android 使用异步任务强制关闭

Android 使用异步任务强制关闭,android,Android,当客户端向服务器发送请求时,我想显示一个progressdialog..请求应该在后台完成..但是当我使用AsyncTask时,我得到了一个强制关闭..请帮助..谢谢 package com.example.client; import java.io.DataInputStream; import java.io.DataOutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.n

当客户端向服务器发送请求时,我想显示一个progressdialog..请求应该在后台完成..但是当我使用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;
        }
    }

}
package com.example.client;
导入java.io.DataInputStream;
导入java.io.DataOutputStream;
导入java.net.InetSocketAddress;
导入java.net.Socket;
导入java.net.SocketAddress;
导入android.os.AsyncTask;
导入android.os.Bundle;
导入android.app.Activity;
导入android.app.ProgressDialog;
导入android.content.Intent;
导入android.view.Menu;
导入android.view.view;
导入android.view.view.OnClickListener;
导入android.widget.TextView;
导入android.widget.Toast;
公共类MainActivity扩展了活动{
公共静态进程对话框;
字符串s1;
@凌驾
创建时的公共void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(新的OnClickListener(){
@凌驾
公共void onClick(视图v){
//sendreq();
新建SendUserTask().execute();
}
});
}
公共字符串sendreq(){
试一试{
//TODO自动生成的方法存根
SocketAddress sockaddr=新的InetSocketAddress(“192.168.7.116”,
9011);
套接字服务器套接字=新套接字();
serversocket.connect(sockaddr,10000);
serversocket.setSoTimeout(10000);
DataOutputStream out=新的DataOutputStream(
serversocket.getOutputStream());
out.flush();
DataInputStream in=新的DataInputStream(
serversocket.getInputStream());
out.flush();
字符串msg=“”;
msg=“你好”;
out.writeBytes(msg);
out.flush();
字节[]消息=新字节[100];
阅读(信息);
s1=新字符串(消息);
Toast.makeText(getApplicationContext(),s1,Toast.LENGTH\u LONG)
.show();
((TextView)findViewById(R.id.textView1)).setText(s1);
in.close();
out.close();
serversocket.close();
}捕获(例外e){
Toast.makeText(getApplicationContext(),String.valueOf(e),
Toast.LENGTH_LONG).show();
}
返回null;
}
私有类SendUserTask扩展了AsyncTask{
@凌驾
受保护的void onPreExecute(){
//TODO自动生成的方法存根
Dialog=ProgressDialog.show(MainActivity.this,“,
“登录…”,正确);
super.onPreExecute();
}
受保护的void onPostExecute(字符串s){
if(Dialog.isShowing())
Dialog.dismise();
}
@凌驾
受保护字符串doInBackground(无效…参数){
//TODO自动生成的方法存根
试一试{
返回sendreq();
}捕获(例外e){
Toast.makeText(getApplicationContext(),String.valueOf(e),
吐司。长度(短)。show();
}
返回null;
}
}
}
((TextView)findViewById(R.id.textView1)).setText(s1)从后台线程执行。您无法访问UI线程之外的UI元素

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

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


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

确定。。。。在谷歌搜索了很多之后,我终于明白,你不能将UI元素从主线程访问到一个新的非UI线程中…因此你不能在dobackground mtd中,甚至在dobackground调用的任何其他mts中使用诸如textview或getApplicationContext mtd tht v之类的元素…这也适用于新线程()使用runnable..感谢njzk2的帮助:)

我不认为这是问题所在…因为使用AsyncTask调用mtd sendreq()不是问题所在…如果我直接通过onClick(我已经评论过的一个)调用它,它工作得很好…@user1729085是的,这就是他的观点。当从UI线程调用
sendreq()
中操纵UI的部分时,它们工作正常。当从
AsyncTask
中的后台线程调用它们时,它们将失败。因此,正如@njzk2所说,您需要在可以访问UI.ya的方法之一中执行UI操作。您是对的……我必须从sendreq()中删除settext和toast……并将其放在postexc中……现在工作正常……但这是否意味着我无法从UI线程访问任何元素?或者有没有办法做到这一点???对不起,我是说从非UI线程…有没有办法从doInBackground mtd访问UI元素???不,我认为你做不到。无法从后台线程访问UI元素。但是,您可以在任务执行时使用onProgressUpdate()访问UI。
runOnUiThread Runnable
是另一个选项,但我更喜欢usi