简体   繁体   中英

What I am doing wrong here : Android Socket Connection?

I'm converting a Client-Server Application which I learned from theneboston.com to Android App, it's an instant messaging application which uses Sockets (TCP connection) to communicate, in my Android App one device is the server and the other is the client. Now there is a problem when running the server side app on the emulator, the app freezes for about 40 seconds and then an error message pops up saying:

Activity ServerIM (in application Android Server Instant Messaging ) is not responding

I think the problem is in creating the ServerSocket. I really need this, so I appreciate it id anyone could help me through.

This is my ServeIM Android Class:

package com.example.android.server.instant.messenger;

import java.io.EOFException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.view.View.OnClickListener;

public class ServerIM extends Activity {

    private ScrollView scrollView;
    private EditText userText;
    private Button connectButton;
    private Button sendButton;
    private TextView chatLog;

    private ObjectOutputStream output;
    private ObjectInputStream input;
    private ServerSocket server;
    private Socket connection;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_server_im);

        scrollView = (ScrollView) findViewById(R.id.ScrollView);
        userText = (EditText) findViewById(R.id.user_Text);
        connectButton = (Button) findViewById(R.id.button_connect);
        sendButton = (Button) findViewById(R.id.button_send);
        chatLog = (TextView) findViewById(R.id.chat_Log);

        ableToType(false);

        connectButton.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                showMessage("1"); // this message doesn't appends to the
                                    // TextView
                startRunning();
            }
        });

    }

    public void startRunning() {
        try {
            (new Thread(new Runnable() {
                public void run() {
                    try {
                        server = new ServerSocket(5678, 100);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            })).start();
            while (true) {
                try {
                    waitForConnection();
                    setupStreams();
                    whileChatting();
                } catch (EOFException eofException) {
                    showMessage("\n Server ended the connection!");
                } finally {
                    closeCrap();
                }
            }
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }

    }

    // wait for connection, then display connection information
    private void waitForConnection() throws IOException {
        showMessage("Waiting for someone to connect... \n");
        connection = server.accept();
        showMessage("Now connected to "
                + connection.getInetAddress().getHostName());
    }

    // get stream to send and recieve data
    private void setupStreams() throws IOException {
        output = new ObjectOutputStream(connection.getOutputStream());
        output.flush();
        input = new ObjectInputStream(connection.getInputStream());
        showMessage("\n Streams are now setup! \n");
    }

    // during the chat conversation
    private void whileChatting() throws IOException {
        String message = " You are now connected! ";
        sendMessage(message);
        ableToType(true);
        do {
            // have a conversation
            try {
                message = (String) input.readObject();
                showMessage("\n" + message);
            } catch (ClassNotFoundException classNotFoundException) {
                showMessage("\n idk wtf that user sent! ");
            }
        } while (!message.equals("CLIENT - END"));
    }

    // close streams ans sockets after you are done chatting
    private void closeCrap() {
        showMessage("\n Closing Connections... \n");
        ableToType(false);
        try {
            output.close();
            input.close();
            connection.close();
        } catch (IOException ioException) {
            ioException.printStackTrace();
        }
    }

    // send message to client
    private void sendMessage(String message) {
        try {
            output.writeObject("SERVER - " + message);
            output.flush();
            showMessage("\n Server - " + message);
        } catch (IOException ioException) {
            chatLog.append("\n ERROR: I can't send this message");
        }
    }

    // update chatWindow
    private void showMessage(final String text) {
        final Handler myHandler = new Handler();

        (new Thread(new Runnable() {
            public void run() {
                myHandler.post(new Runnable() {
                    public void run() {
                        chatLog.append(text + "\n");
                    }
                });
            }
        })).start();
    }

    // let the user type stuff into their box
    private void ableToType(final boolean tof) {

        final Handler myHandler = new Handler();

        (new Thread(new Runnable() {
            public void run() {
                myHandler.post(new Runnable() {
                    public void run() {
                        userText.setEnabled(tof);
                    }
                });
            }
        })).start();

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_server_im, menu);
        return true;
    }
}

And this is the XML file:

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

    <ScrollView
        android:id="@+id/ScrollView"
        android:layout_width="fill_parent"
        android:layout_height="150dp"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

        <TextView
            android:id="@+id/chat_Log"
            android:layout_width="wrap_content"
            android:layout_height="339dp"
            android:text="" />
    </ScrollView>

    <EditText
        android:inputType="text"
        android:id="@+id/user_Text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/ScrollView"
        android:layout_marginTop="39dp"
        android:ems="10" />

    <Button
        android:id="@+id/button_send"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/user_Text"
        android:layout_toRightOf="@+id/user_Text"
        android:minWidth="100dip"
        android:text="Send" />

    <Button
        android:id="@+id/button_connect"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/button_send"
        android:layout_alignRight="@+id/button_send"
        android:layout_below="@+id/button_send"
        android:text="Connect" />

</RelativeLayout>

And the Manifest:

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.android.server.instant.messenger"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-permission android:name="android.permission.INTERNET" />

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".ServerIM"
            android:label="@string/title_activity_server_im" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

The ServerSocket.accept() function is running in the UI thread, and will block until it gets a connection.

You had the right idea, in creating the ServerSocket in a different thread, but you have to run the accept() function in the background.

事件处理程序(ServerIM.java:68)中有while (true) ),这会使EDT挂起。

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