2014-03-01 22 views
0

我想用Socket編程來交換數據。我使用Android應用程序作爲客戶端和服務器Java程序,我可以建立連接,只要我按發送按鈕,應用程序停止異常。我重視我的code.`Android與Java程序之間的Socket編程問題

活動的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> 

清單文件:

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

郵政全堆棧跟蹤,並指出該行拋出異常。 – nKn

+0

發佈您的日誌貓 –

+0

連接的長度有多長? – Behnam

回答

0
Toast.makeText(MainActivity.this, "Sent "+sentence, Toast.LENGTH_LONG).show(); 
//... 
Toast.makeText(MainActivity.this, "Received "+sentence, Toast.LENGTH_LONG).show(); 

在後臺線程中,您不能使用Toast,僅在UI線程。

好像你可以使用android.util.Log類從後臺線程得到像這樣的調試輸出。

2

你正在做像吐司和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); 
       } 
      } 
     }); 
    }  
0

您還沒有以適當的方式處理異常。試試這個

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