代码如下:
package com.cxw.seventask;import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.sql.Date;
import java.text.SimpleDateFormat;import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;public class SevenTaskMainActivity extends Activity implements Runnable{
private EditText username,serverIP,historyEdit,messageEdit;
private Button loginButton,cancelButton,sendButton;
private String username1,ip,chat_txt,chat_in;
public static final int PORT=8521;
Socket socket;
Thread thread;
DataInputStream in;
DataOutputStream out;
boolean flag=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
username=(EditText)findViewById(R.id.editText1);
serverIP=(EditText)findViewById(R.id.editText2);
historyEdit=(EditText)findViewById(R.id.editText3);
messageEdit=(EditText)findViewById(R.id.editText4);
    loginButton=(Button)findViewById(R.id.button1);
    cancelButton=(Button)findViewById(R.id.button2);
    sendButton=(Button)findViewById(R.id.button3);
    loginButton.setOnClickListener(listener);
    cancelButton.setOnClickListener(listener);
    sendButton.setOnClickListener(listener);

}
    View.OnClickListener listener=new View.OnClickListener() {

@Override
public void onClick(View view) {
// TODO Auto-generated method stub
switch(view.getId())
{
case R.id.button1:
if(flag==true)
{
Toast.makeText(SevenTaskMainActivity.this, "已经登录过了!", Toast.LENGTH_SHORT).show();
return;
}
username1=username.getText().toString();
ip=serverIP.getText().toString();
if(username1!=""&&username!=null&&username1!="用户输入"&&ip!=null)
{
try{

socket=new Socket(ip,PORT);
//创建客户端数据输入,输出流,用于对服务器发送或接收数据
in=new DataInputStream(socket.getInputStream());
out=new DataOutputStream(socket.getOutputStream());
Date now =new Date(System.currentTimeMillis());
SimpleDateFormat format=new SimpleDateFormat("hh:mm:ss");
String nowStr=format.format(now);
out.writeUTF("$$"+username1+" "+nowStr+" 上线了");
}catch(IOException e1)
{
System.out.println("无法连接");
}
thread=new Thread(SevenTaskMainActivity.this);
thread.start();
flag=true;
}
break;
case R.id.button3:
if(flag==false)
{
Toast.makeText(SevenTaskMainActivity.this, "没有登录过!", Toast.LENGTH_SHORT).show();
return;
}
chat_txt=messageEdit.toString().toString();
if(chat_txt!=null)
{
Date now=new Date(System.currentTimeMillis());
SimpleDateFormat format=new SimpleDateFormat("hh:mm:ss");
String nowstr=format.format(now);
try
{
out.writeUTF("^_^"+username1+" "+nowstr+"说\n"+chat_txt);
}catch(IOException e2)
{

}
}
else
{
try
{
out.writeUTF("请说话");
     }catch(IOException e3)
{

}
}
break;
case R.id.button2:
if(flag==true)
{
     if(flag==false)
     {
Toast.makeText(SevenTaskMainActivity.this, "没有登录过,请登录!", Toast.LENGTH_SHORT).show();
return;
        }
try
{
out.writeUTF("=="+username1+"下线了");
out.close();
in.close();
socket.close();
}catch(IOException e4)
{

}
}
flag=false;
Toast.makeText(SevenTaskMainActivity.this, "已退出", Toast.LENGTH_SHORT).show();
break;
}

}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_seven_task_main, menu);
return true;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true)
{
try
{
chat_in=in.readUTF();
chat_in=chat_in+"\n";
mHandler.sendMessage(mHandler.obtainMessage());
}catch(IOException e)
{}
}

}
Handler mHandler=new Handler()
{
public void handleMessage(Message msg)
{
historyEdit.append(chat_in);
super.handleMessage(msg);
}
};}错误如下:
0-01 06:58:25.195: D/AndroidRuntime(22152): Shutting down VM
10-01 06:58:25.195: W/dalvikvm(22152): threadid=1: thread exiting with uncaught exception (group=0x40a70930)
10-01 06:58:25.272: E/AndroidRuntime(22152): FATAL EXCEPTION: main
10-01 06:58:25.272: E/AndroidRuntime(22152): android.os.NetworkOnMainThreadException
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1117)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at libcore.io.IoBridge.connectErrno(IoBridge.java:127)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at libcore.io.IoBridge.connect(IoBridge.java:112)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.Socket.startupSocket(Socket.java:566)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.Socket.tryAllAddresses(Socket.java:127)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.Socket.<init>(Socket.java:177)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.net.Socket.<init>(Socket.java:149)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at com.cxw.seventask.SevenTaskMainActivity$1.onClick(SevenTaskMainActivity.java:65)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.view.View.performClick(View.java:4202)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.view.View$PerformClick.run(View.java:17340)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.os.Handler.handleCallback(Handler.java:725)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.os.Handler.dispatchMessage(Handler.java:92)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.os.Looper.loop(Looper.java:137)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at android.app.ActivityThread.main(ActivityThread.java:5039)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.lang.reflect.Method.invokeNative(Native Method)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at java.lang.reflect.Method.invoke(Method.java:511)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-01 06:58:25.272: E/AndroidRuntime(22152):  at dalvik.system.NativeStart.main(Native Method)
10-01 06:58:39.496: I/Process(22152): Sending signal. PID: 22152 SIG: 9
android通讯socket

解决方案 »

  1.   

    NetworkOnMainThreadException
    在UI主线程做网络操作,在操作返回前,UI不会响应用户操作,或者5秒后还未返回会造成ANR,影响了用户体验。
    4.0以后已经不允许这样做了,你需要把网络操作放在一个新线程里。
      

  2.   

    怎么改?大神。或者给我些4.0版以上的socket编程
      

  3.   

    你的程序或许可以在低版本的ANDROID运行,但是不代表这样就是对的。 即使可以运行,也仅限于用于测试啊之类的,真正完整的程序,不许把耗时线程脱离UI线程。
      

  4.   

    刚开始学android的,这种知识书本上都没有,为什么你知道我不知道呢?能否给些你学习android Socket的葵花宝典
      

  5.   

    package com.cxw.seventask;import java.io.DataInputStream;
    import java.io.DataOutputStream;
    import java.io.IOException;
    import java.net.Socket;
    import java.sql.Date;
    import java.text.SimpleDateFormat;import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.app.Activity;
    import android.view.Menu;
    import android.view.View;
    import android.widget.Button;
    import android.widget.EditText;
    import android.widget.Toast;public class SevenTaskMainActivity extends Activity implements Runnable {
    private EditText username, serverIP, historyEdit, messageEdit;
    private Button loginButton, cancelButton, sendButton;
    private String username1, ip, chat_txt, chat_in;
    public static final int PORT = 8521;
    Socket socket;
    Thread thread;
    DataInputStream in;
    DataOutputStream out;
    boolean flag = false; @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    username = (EditText) findViewById(R.id.editText1);
    serverIP = (EditText) findViewById(R.id.editText2);
    historyEdit = (EditText) findViewById(R.id.editText3);
    messageEdit = (EditText) findViewById(R.id.editText4);
    loginButton = (Button) findViewById(R.id.button1);
    cancelButton = (Button) findViewById(R.id.button2);
    sendButton = (Button) findViewById(R.id.button3);
    loginButton.setOnClickListener(listener);
    cancelButton.setOnClickListener(listener);
    sendButton.setOnClickListener(listener); } View.OnClickListener listener = new View.OnClickListener() { @Override
    public void onClick(View view) {
    // TODO Auto-generated method stub
    switch (view.getId()) {
    case R.id.button1:
    if (flag == true) {
    Toast.makeText(SevenTaskMainActivity.this, "已经登录过了!",
    Toast.LENGTH_SHORT).show();
    return;
    }
    username1 = username.getText().toString();
    ip = serverIP.getText().toString();
    if (username1 != "" && username != null && username1 != "用户输入"
    && ip != null) {
    (new Thread(){//这里有一个新线程,网络操作放到这里线程里 @Override
    public void run() {
    super.run();
    try { socket = new Socket(ip, PORT);
    // 创建客户端数据输入,输出流,用于对服务器发送或接收数据
    in = new DataInputStream(socket.getInputStream());
    out = new DataOutputStream(socket.getOutputStream());
    Date now = new Date(System.currentTimeMillis());
    SimpleDateFormat format = new SimpleDateFormat(
    "hh:mm:ss");
    String nowStr = format.format(now);
    out.writeUTF("$$" + username1 + " " + nowStr + " 上线了");
    } catch (IOException e1) {
    System.out.println("无法连接");
    }
    }

    }).start(); thread = new Thread(SevenTaskMainActivity.this);
    thread.start();
    flag = true;
    }
    break;
    case R.id.button3:
    if (flag == false) {
    Toast.makeText(SevenTaskMainActivity.this, "没有登录过!",
    Toast.LENGTH_SHORT).show();
    return;
    }
    chat_txt = messageEdit.toString().toString();
    if (chat_txt != null) {
    Date now = new Date(System.currentTimeMillis());
    SimpleDateFormat format = new SimpleDateFormat("hh:mm:ss");
    String nowstr = format.format(now);
    try {
    out.writeUTF("^_^" + username1 + " " + nowstr + "说\n"
    + chat_txt);
    } catch (IOException e2) { }
    } else {
    try {
    out.writeUTF("请说话");
    } catch (IOException e3) { }
    }
    break;
    case R.id.button2:
    if (flag == true) {
    if (flag == false) {
    Toast.makeText(SevenTaskMainActivity.this,
    "没有登录过,请登录!", Toast.LENGTH_SHORT).show();
    return;
    }
    (new Thread(){//这里有一个新线程,网络操作放到这里线程里 @Override
    public void run() {
    super.run();
    try {
    out.writeUTF("==" + username1 + "下线了");
    out.close();
    in.close();
    socket.close();
    } catch (IOException e4) { }
    }

    }).start(); }
    flag = false;
    Toast.makeText(SevenTaskMainActivity.this, "已退出",
    Toast.LENGTH_SHORT).show();
    break;
    } }
    }; @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_seven_task_main, menu);
    return true;
    } @Override
    public void run() {
    // TODO Auto-generated method stub
    while (true) {
    try {
    chat_in = in.readUTF();
    chat_in = chat_in + "\n";
    mHandler.sendMessage(mHandler.obtainMessage());
    } catch (IOException e) {
    }
    } } Handler mHandler = new Handler() {
    public void handleMessage(Message msg) {
    historyEdit.append(chat_in);
    super.handleMessage(msg);
    }
    };}看一下注释的那两个地方,把网络操作放在新线程里了。这样就不会出现NetworkOnMainThreadException。