Android和Java程序之间的套接字编程问题

Android和Java程序之间的套接字编程问题,java,android,Java,Android,我正在尝试使用套接字编程来交换数据。我使用Android应用程序作为客户端,服务器作为Java程序,我能够建立连接,只要我按下发送按钮,应用程序就会异常停止。我已附上我的代码` 活动Java代码: package com.example.communidemo; import java.io.IOException; import java.net.InetAddress; import java.net.Socket; import java.io.DataOutputStream; impo

我正在尝试使用套接字编程来交换数据。我使用Android应用程序作为客户端,服务器作为Java程序,我能够建立连接,只要我按下发送按钮,应用程序就会异常停止。我已附上我的代码`

活动Java代码:

package com.example.communidemo;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
import java.io.DataOutputStream;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.widget.EditText;

public class MainActivity extends Activity implements OnClickListener {


    private EditText ipBox, msgbox;
    private ToggleButton connBtn;
    private Button sendBtn;
    private TextView txtView;
    private Socket client;
    private DataOutputStream out;
    private BufferedReader in;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setUpAllViews(R.layout.activity_main);  
    }

    void setUpAllViews(int layout)
    {
     setContentView(layout);
     ipBox = (EditText) findViewById(R.id.ipBox);
     msgbox = (EditText) findViewById(R.id.msgbox);
     connBtn = (ToggleButton) findViewById(R.id.connect);
     sendBtn = (Button) findViewById(R.id.send);
     txtView = (TextView) findViewById(R.id.text);

     connBtn.setOnClickListener(this);     
    }


    @Override
    public void onClick(View v)
    {       
     Toast.makeText(this, ipBox.getText(), Toast.LENGTH_LONG).show();
     Toast.makeText(this, v.getId(), Toast.LENGTH_LONG).show();
     switch(v.getId())
     {
     case R.id.connect:
         if(connBtn.isChecked())
         {
             Toast.makeText(this, "Enabling", Toast.LENGTH_LONG).show();
             enableConnection();
         }
         else
         {
             Toast.makeText(this, "Disabling", Toast.LENGTH_LONG).show();
             disableConnection();
         }
         break;
     case R.id.send:
         sendDataOverCommunication();
         break;
     }     
    }

    private void setValues(int id, boolean value)    
    {
     switch(id)
     {
     case R.id.ipBox: ipBox.setEnabled(value); break;
     case R.id.msgbox: msgbox.setEnabled(value); break;
     case R.id.send: sendBtn.setEnabled(value); break;
     case R.id.connect: connBtn.setChecked(value); break;
     }
    }
    private void setUpIOStreams()
    {
     try
     {

     Thread thread = new Thread(new Runnable(){
            @Override
            public void run() {
                try {
                    InetAddress addr = InetAddress.getByName(ipBox.getText().toString());
                    client = new Socket(addr,5800);
                    out = new DataOutputStream(client.getOutputStream());
                    in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });

        thread.start(); 
     /*
     InetAddress addr = InetAddress.getByName(ipBox.getText().toString());
     client = new Socket(addr,5800);
     out = new DataOutputStream(client.getOutputStream());
     in = new BufferedReader(new InputStreamReader(client.getInputStream()));*/
     }
     catch(Exception e)
     {
      Toast.makeText(this, "Connection Problem", Toast.LENGTH_LONG).show();
      Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
     }
    }

    private void enableConnection()
    {
      try
      {
       setUpIOStreams();                         
       setValues(R.id.connect,true);
       setValues(R.id.send,true);
       setValues(R.id.ipBox,false);
       setValues(R.id.msgbox,true);
       sendBtn.setOnClickListener(this);
      }
      catch(Exception e)
      {
       setValues(R.id.connect,false);
       Toast.makeText(this, "Enable Problem", Toast.LENGTH_LONG).show();
       Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();
      }
    }

    private void disableConnection()
    {
     if(client != null)
     {
      try
       {     
        client.close();
       }
      catch(Exception e)
       {
        Toast.makeText(this, "Disable Problem", Toast.LENGTH_LONG).show();  
        Toast.makeText(this, e.toString(), Toast.LENGTH_LONG).show();     
       }
      setValues(R.id.connect,false);
      setValues(R.id.ipBox,true);
      setValues(R.id.msgbox,false);
      setValues(R.id.send,false);         
    }
     else
     {
      setValues(R.id.connect,false);     
     }
    }

    private void sendDataOverCommunication()
    {
     Thread thread = new Thread(new Runnable(){
         @Override
         public void run(){                  
      try
      {                           
              if(client.isClosed())
                  setUpIOStreams();
              String sentence = msgbox.getText().toString();
              out.writeBytes(sentence);
              Toast.makeText(MainActivity.this, "Sent "+sentence, Toast.LENGTH_LONG).show();
              out.flush();
              out.close();
              sentence = in.readLine();
              msgbox.setText(sentence);
              Toast.makeText(MainActivity.this, "Received "+sentence, Toast.LENGTH_LONG).show();
              client.close();                                   
      }      
     catch(IOException e)
     {
      Toast.makeText(MainActivity.this, "Problem in sending", Toast.LENGTH_LONG).show();     
      Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
      setValues(R.id.ipBox,true);
      setValues(R.id.connect,false);
      setValues(R.id.send,false);
      setValues(R.id.msgbox,false);
     }}}
      );
     thread.start();
    }    
}
XML布局文件:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <LinearLayout
        android:id="@+id/linearlayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

    <EditText
       android:id="@+id/ipBox"
       android:layout_width="fill_parent"
       android:layout_height="wrap_content"
       android:layout_weight="1"
       android:hint="@string/ip_address"
        >
       <requestFocus /> 
    </EditText>

    <ToggleButton
        android:id="@+id/connect"
        android:onClick="onclick"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:textOn="@string/disconnected"
        android:textOff="@string/connected"
        >
    </ToggleButton>    

</LinearLayout>

<LinearLayout
    android:id="@+id/linearlayout2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <EditText
        android:id="@+id/msgbox"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:enabled="false" 
        >
    </EditText>

    <Button
        android:id="@+id/send"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:text="@string/send"
        android:enabled="false"
        >      
    </Button>

</LinearLayout>

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/connect_prompt"/>

</LinearLayout>

字符串资源:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">CommuniDemo</string>
    <string name="hello_world">Hello world!</string>
    <string name="connect_prompt">Start the client by pressing the connect button</string>
    <string name="send_prompt">Enter your message and press the send button</string>
    <string name="ip_address">IP Address</string>enter code here
    <string name="message_prompt">Say something</string>
    <string name="device_ip">Device\'s IP Address: </string>
    <string name="server_ip">Server\'s IP Address: </string>
    <string name="connected">Connect</string>
    <string name="disconnected">Disconnect</string>
    <string name="send">Send</string>


</resources>

通讯演示
你好,世界!
按connect按钮启动客户端
输入您的信息,然后按发送按钮
IP地址在此输入代码
说点什么
设备的IP地址:
服务器的IP地址:
连接
断开
发送
清单文件:

 <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.communidemo"
        android:versionCode="1"
        android:versionName="1.0" >

        <uses-permission android:name="android.permission.INTERNET"/> 
        <uses-sdk
            android:minSdkVersion="8"
            android:targetSdkVersion="16" />


        <application
            android:allowBackup="true"
            android:icon="@drawable/ic_launcher"
            android:label="@string/app_name"
            android:theme="@style/AppTheme">      
            <activity
                android:name="com.example.communidemo.MainActivity"
                android:label="@string/app_name" >
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category android:name="android.intent.category.LAUNCHER" `enter code here`/>
                </intent-filter>
            </activity>
        </application>enter code here

    </manifest>

在这里输入代码
请帮我做这个。 我正在附加来自LOG-CAT的错误

``03-01 09:16:32.468: E/Trace(1852): error opening trace file: No such file or directory (2)
03-01 09:17:39.288: E/AndroidRuntime(1852): FATAL EXCEPTION: Thread-156
03-01 09:17:39.288: E/AndroidRuntime(1852): java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
03-01 09:17:39.288: E/AndroidRuntime(1852):     at android.os.Handler.<init>(Handler.java:197)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at android.os.Handler.<init>(Handler.java:111)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at android.widget.Toast$TN.<init>(Toast.java:324)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at android.widget.Toast.<init>(Toast.java:91)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at android.widget.Toast.makeText(Toast.java:238)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at com.example.communidemo.MainActivity$2.run(MainActivity.java:171)
03-01 09:17:39.288: E/AndroidRuntime(1852):     at java.lang.Thread.run(Thread.java:856)
`03-01 09:16:32.468:E/Trace(1852):打开跟踪文件时出错:没有这样的文件或目录(2)
03-01 09:17:39.288:E/AndroidRuntime(1852):致命异常:线程156
03-01 09:17:39.288:E/AndroidRuntime(1852):java.lang.RuntimeException:无法在未调用Looper.prepare()的线程内创建处理程序
03-01 09:17:39.288:E/AndroidRuntime(1852):位于android.os.Handler.(Handler.java:197)
03-01 09:17:39.288:E/AndroidRuntime(1852):位于android.os.Handler.(Handler.java:111)
03-01 09:17:39.288:E/AndroidRuntime(1852):在android.widget.Toast$TN.(Toast.java:324)
03-01 09:17:39.288:E/AndroidRuntime(1852):在android.widget.Toast(Toast.java:91)
03-01 09:17:39.288:E/AndroidRuntime(1852):在android.widget.Toast.makeText(Toast.java:238)上
03-01 09:17:39.288:E/AndroidRuntime(1852):位于com.example.communidemo.MainActivity$2.run(MainActivity.java:171)
03-01 09:17:39.288:E/AndroidRuntime(1852):位于java.lang.Thread.run(Thread.java:856)
不能在后台线程中使用
Toast
,只能在UI线程中使用


似乎您可以使用android.util.Log类从后台线程中获得类似这样的调试输出。

您在线程下执行的UI工作就像Toast和setText,这就是您遇到类似问题的方式。用户界面在RunNuithRead下工作吗

private void sendDataOverCommunication()
    {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                try
                {                           
                    if(client.isClosed())
                        setUpIOStreams();
                    String sentence = msgbox.getText().toString();
                    out.writeBytes(sentence);
                    Toast.makeText(MainActivity.this, "Sent "+sentence, Toast.LENGTH_LONG).show();
                    out.flush();
                    out.close();
                    sentence = in.readLine();
                    msgbox.setText(sentence);
                    Toast.makeText(MainActivity.this, "Received "+sentence, Toast.LENGTH_LONG).show();
                    client.close();                                   
                }      
                catch(IOException e)
                {
                    Toast.makeText(MainActivity.this, "Problem in sending", Toast.LENGTH_LONG).show();     
                    Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
                    setValues(R.id.ipBox,true);
                    setValues(R.id.connect,false);
                    setValues(R.id.send,false);
                    setValues(R.id.msgbox,false);
                }
            }
        });
    }    

您没有以正确的方式处理异常。试试这个

catch (UnknownHostException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (Exception e) {};

发布完整的堆栈跟踪,并指出哪一行引发异常。连接的长度有多长?在我单击“发送”按钮之前,连接已建立。我的服务器一直在运行。“不能在未调用Looper.prepare()的线程内创建处理程序”的哪一部分您不明白吗?
catch (UnknownHostException e) {
  e.printStackTrace();
} catch (IOException e) {
  e.printStackTrace();
} catch (Exception e) {};