编辑:我的解决方案是使用此代码获得一个常量类:
static EditText Port = (EditText) MainActivity.mDialog.findViewById(R.id.txtPort); static int mPort = Integer.parseInt(Port.getText().toString()); public static final int PORT = mPort;
我试图看到其他问题而且我明白我必须对UIThread做些什么?老实说,我什么都不懂。我是新的Android。
应用程序(聊天应用程序)工作正常,直到我想拥有多个端口选项,具体取决于我是托管(port 5050
)还是加入(port 80
)聊天室。从一开始我只有一个恒定的端口值(public static final int PORT
)但现在我不能拥有那个ofc。如果你们有关于如何获得两个PORT值的任何其他建议,请分享你的提示。
无论如何,在尝试了一切之后我决定在我的主类中放一个方法,然后在其他类中声明它。这是端口值的方法:
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
这是我的MainActivity
package chat.chris.android.se.chatup;
import android.app.Activity;
import android.app.Dialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.TextView.OnEditorActionListener;
import android.widget.Toast;
import java.util.ArrayList;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.Networking.Client;
import chat.chris.android.se.chatup.Networking.Server;
import chat.chris.android.se.chatup.Utilities.ServerUtils;
import static chat.chris.android.se.chatup.R.id.rdioHost;
import static chat.chris.android.se.chatup.R.id.rdioJoin;
public class MainActivity extends Activity {
private Adapter chatAdapter;
private Button btnSendMessage;
private EditText txtMessage;
private ListView lstMessages;
private static Dialog mDialog;
private Client mClient;
private Server mServer;
private EditText txtPORT;
private RadioButton mJoin;
private RadioButton mHost;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
showChatSelection();
chatAdapter = new Adapter(this, new ArrayList<ChatItem>());
lstMessages = (ListView) findViewById(R.id.lstChat);
lstMessages.setAdapter(chatAdapter);
txtMessage = (EditText) findViewById(R.id.txtSay);
txtMessage.setOnEditorActionListener(txtMessageEditorActionListener);
btnSendMessage = (Button) findViewById(R.id.btnSend);
btnSendMessage.setOnClickListener(btnSendMessageClickListener);
Client.setOnChatListener(chatListener);
Client.setOnConnectionListener(connectionListener);
}
public void showChatSelection() {
mDialog = new Dialog(this);
mDialog.setContentView(R.layout.layout_chat_choose);
mDialog.setTitle("Chat Room");
mDialog.setCancelable(false);
final EditText txtServer = (EditText) mDialog.findViewById(R.id.txtAddress);
final TextView lblServer = (TextView) mDialog.findViewById(R.id.lblAddress);
final TextView txtPort = (EditText) mDialog.findViewById(R.id.txtPort);
final RadioButton mHost = (RadioButton) mDialog.findViewById(rdioHost);
final RadioButton mJoin = (RadioButton) mDialog.findViewById(rdioJoin);
try {
lblServer.setText(ServerUtils.getLocalIp(this));
} catch (NullPointerException e) {
mHost.setEnabled(false);
mHost.setChecked(false);
lblServer.setText("Wifi must be enabled to host");
mJoin.setChecked(true);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
}
mDialog.findViewById(R.id.btnChoose).setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
mDialog.findViewById(R.id.progLoading).setVisibility(View.VISIBLE);
new SetupChat().execute(mHost.isChecked(), mJoin.isChecked() ? txtServer.getText().toString() : "");
}
});
mHost.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mJoin.setChecked(false);
txtServer.setVisibility(View.INVISIBLE);
txtPort.setVisibility(View.INVISIBLE);
lblServer.setVisibility(View.VISIBLE);
}
}
});
mJoin.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (isChecked) {
mHost.setChecked(false);
txtServer.setVisibility(View.VISIBLE);
txtPort.setVisibility(View.VISIBLE);
lblServer.setVisibility(View.INVISIBLE);
}
}
});
mDialog.show();
}
private final OnClickListener btnSendMessageClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
sendMessage();
}
};
private final OnEditorActionListener txtMessageEditorActionListener = new OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int id, KeyEvent event) {
if (id == EditorInfo.IME_ACTION_NEXT || id == EditorInfo.IME_ACTION_DONE)
sendMessage();
return true;
}
};
private final ChatListener chatListener = new ChatListener() {
@Override
public void onChat(String message) {
chatAdapter.addItem(new ChatItem("<html>" + message + "</html>", "Friend"));
}
};
private final ConnectionListener connectionListener = new ConnectionListener() {
@Override
public void onDisconnect(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " left the chat room", ""));
}
@Override
public void onJoin(Client client) {
chatAdapter.addItem(new ChatItem(client.getName() + " joined the chat room", ""));
}
};
public void sendMessage() {
String message = txtMessage.getText().toString();
if(message == null || message.isEmpty())
return;
message = message.replace(">", ">");
message = message.replace("<", "<");
try {
if (mServer != null) {
mServer.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else if (mClient != null) {
mClient.sendMessage(message);
chatAdapter.addItem(new ChatItem(message, "You"));
} else {
return;
}
} catch (Exception e) {
chatAdapter.addItem(new ChatItem(e.getMessage(), "<font color='red'>Error</font>"));
return;
}
txtMessage.setText("");
}
public int getPORT() {
txtPORT = (EditText) findViewById(R.id.txtPort);
//String txtPORTa = txtPORT.getText().toString();
int dennaPORT = 0;
if (mJoin.isChecked()) {
dennaPORT = Integer.parseInt(txtPORT.getText().toString());
return dennaPORT;
}
else if (mHost.isChecked()) {
dennaPORT = 5050;
return dennaPORT;
}
return dennaPORT;
}
private class SetupChat extends AsyncTask<Object,Void, Boolean> {
@Override
protected Boolean doInBackground(Object... args) {
try {
if ((Boolean)args[0]) {
mServer = new Server();
new Thread(mServer).start();
} else {
String address = args[1].toString();
mClient = Client.connect(address);
if (mClient == null)
return true;
new Thread(mClient).start();
}
} catch (Exception e) {
e.printStackTrace();
return true;
}
return false;
}
@Override
protected void onPostExecute(Boolean errors) {
if (errors)
Toast.makeText(getApplicationContext(), "Någonting gick fel\nSkrev du in allting rätt?", Toast.LENGTH_LONG).show();
else
mDialog.dismiss();
}
}
}
这是客户端类
package chat.chris.android.se.chatup.Networking;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import chat.chris.android.se.chatup.Listeners.ChatListener;
import chat.chris.android.se.chatup.Listeners.ConnectionListener;
import chat.chris.android.se.chatup.MainActivity;
import chat.chris.android.se.chatup.Utilities.Crypto;
public class Client implements Runnable {
private BufferedReader reader;
private DataOutputStream writer;
private boolean disconnecting;
private byte[] cryptoKey;
private String name;
private static ChatListener chatListener;
private static ConnectionListener connectionListener;
//Instansierar ny klient
public Client(Socket s) throws IOException {
cryptoKey = new byte[16];
try {
reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
writer = new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
disconnect();
return;
}
}
//Ger klienten ett namn
public String getName() {
return name;
}
//Sätter namnet
public void setName(String name) {
this.name = name;
}
public static void setOnChatListener(ChatListener listener) {
chatListener = listener;
}
public static void setOnConnectionListener(ConnectionListener listener) {
connectionListener = listener;
}
public BufferedReader getReader() {
return reader;
}
public byte[] getKey(){
return cryptoKey;
}
public void setKey(byte[] key) {
cryptoKey = key;
}
@Override
public void run() {
if (connectionListener != null) {
connectionListener.onJoin(this);
}
try {
while (!disconnecting) {
String read;
if ((read = reader.readLine()) != null) {
if (chatListener != null) {
chatListener.onChat(Crypto.decrypt(read, cryptoKey));
}
}
else{
return;
}
Thread.sleep(5);
}
} catch (IOException e) {
disconnect();
} catch (Exception e) {
e.printStackTrace();
disconnect();
}
}
//Connectar till adressen och returnerar klienten
public static Client connect(String address) throws IOException {
MainActivity porten = new MainActivity();
int PORT;
PORT = porten.getPORT();
InetAddress localAddress = InetAddress.getByName(address);
InetSocketAddress localSocketAddress = new InetSocketAddress(localAddress, PORT);
Socket socket = new Socket();
socket.connect(localSocketAddress, 5000);
Client client = new Client(socket);
socket.getInputStream().read(client.cryptoKey, 0, 16);
System.out.println("Client -> " + new String(client.cryptoKey));
return client;
}
public void sendMessage(String message) throws Exception {
if(message == null || message.isEmpty())
return;
writer.writeUTF(Crypto.encrypt(message, cryptoKey));
}
public void disconnect() {
if (connectionListener != null) {
connectionListener.onDisconnect(this);
}
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
reader = null;
writer = null;
}
}
这是服务器类
package chat.chris.android.se.chatup.Networking;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Random;
import chat.chris.android.se.chatup.MainActivity;
import static chat.chris.android.se.chatup.Utilities.Constants.MAX_USERS;
//import static chat.chris.android.se.chatup.Utilities.Constants.PORT;
public class Server implements Runnable {
private ArrayList<Client> clientList;
private ServerSocket mSocket;
private byte[] cryptoKey;
private boolean shuttingDown;
MainActivity porten = new MainActivity();
//Instansierar en ny server chatt
public Server() throws IOException {
int PORT = porten.getPORT();
mSocket = new ServerSocket(PORT);
clientList = new ArrayList<>();
Random mRand = new SecureRandom();
cryptoKey = new byte[16];
mRand.nextBytes(cryptoKey);
System.out.println("Server ->" + new String(cryptoKey));
}
public boolean isShuttingDown() {
return shuttingDown;
}
public void setShuttingDown(boolean shuttingDown) {
this.shuttingDown = shuttingDown;
}
@Override
public void run() {
while (!shuttingDown) {
Socket socket = null;
Client client;
try {
socket = this.mSocket.accept();
if (clientList.size() >= MAX_USERS) {
socket.close();
return;
}
socket.getOutputStream().write(cryptoKey);
client = new Client(socket);
client.setKey(cryptoKey);
new Thread(client).start();
clientList.add(client);
} catch (IOException e) {
e.printStackTrace();
try {
if (socket != null)
socket.close();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}
}
public void sendMessage(String message) throws Exception {
for (Client client : clientList) {
if (shuttingDown)
return;
client.sendMessage(message);
}
}
public void shutdown() {
shuttingDown = true;
try {
mSocket.close();
} catch (IOException e) {
} finally {
mSocket = null;
}
}
}
使用此设置即可获得以下错误:
05-04 00:41:58.969 12319-12370/chat.chris.android.se.chatup W/System.err﹕ java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
05-04 00:41:58.970 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:200)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.Handler.<init>(Handler.java:114)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.app.Activity.<init>(Activity.java:793)
05-04 00:41:58.975 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity.<init>(MainActivity.java:32)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.Networking.Server.<init>(Server.java:21)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:229)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at chat.chris.android.se.chatup.MainActivity$SetupChat.doInBackground(MainActivity.java:221)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$2.call(AsyncTask.java:288)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.FutureTask.run(FutureTask.java:237)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
05-04 00:41:58.976 12319-12370/chat.chris.android.se.chatup W/System.err﹕ at java.lang.Thread.run(Thread.java:818)
答案 0 :(得分:2)
从不自己创建Activity
,Service
或ContentProvider
的实例。这些是由框架始终创建的。删除:
MainActivity porten = new MainActivity();
通过其他方式将端口传递到奇怪命名的Server
类,例如构造函数参数或setter方法。