java - Android 和 Java 程序之间的 Socket 编程问题

标签 java android

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

Activity 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>

list 文件:

 <?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)

最佳答案

您正在线程下执行诸如 Toast 和 setText 之类的 UI 工作,这就是您遇到这样的问题的方式。 UI 是否在 runOnUiThread 下工作

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

关于java - Android 和 Java 程序之间的 Socket 编程问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22112320/

相关文章:

java - 线程中的异常 "main"java.lang.ArrayIndexOutOfBoundsException : 4 Error

java - 一个连接中的多种协议(protocol)

java - DecimalFormat 和 Double.valueOf()

android - Activity 与 Android 之间的动画

android - Http Get 请求返回 html?

java - 无法触发覆盖方法

java - 如何使用 switch 语句实现字符串堆栈?

Android Facebook SDK 3.0 session 状态 "Opening"

java - 尝试设置数据绑定(bind)时出错

android - onSMSArrive cordova 短信插件执行了不止一次