简体   繁体   中英

Issue With Socket Programming Between Android and Java Program

I am trying to exchange data using Socket Programming. I am using Android Application as Client and Server as Java Program, I am able to establish the connection, As soon as i press the send button, App stops Abnormally. I have attached my code.`

Activity Java Code:

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 Layout File:

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

String Resource:

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

Manifest File:

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

Please help me with this. I am attaching Errors From 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)

You are doing UI work like Toast and setText under thread thats way you getting problem like this. Do UI work under runOnUiThread like

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);
                }
            }
        });
    }    
Toast.makeText(MainActivity.this, "Sent "+sentence, Toast.LENGTH_LONG).show();
//...
Toast.makeText(MainActivity.this, "Received "+sentence, Toast.LENGTH_LONG).show();

You cannot use a Toast in a background thread, only in the UI thread.

Seems like you could use the android.util.Log class to get debugging output like this from your background thread.

You are not handling exception in a proper way. Try this

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM