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.