您好我正在制作聊天应用程序但是当我尝试使用收到的字符串更新视图时,我得到CalledFromWrongThreadException
,但是它之前有效,我对处理程序的理解是它是为调用创建的从另一个线程。
public class ChatActivity extends ActionBarActivity {
ServerSocket serverSocket;
Thread listenThread;
Thread sendThread;
Socket socket = null;
String strIP = "";
volatile String error;
final static int port = 6000;
TextView chatView;
TextView errorView;
volatile static String rcv = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_chat);
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.add(R.id.container, new PlaceholderFragment()).commit();
}
if (socket == null) {
try {
this.listenThread = new Thread(new Listener());
this.listenThread.start();
} catch (Exception e) {
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.chat, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
} else if (id == R.id.action_connectIP) {
Intent intent = new Intent(this, ConnectActivity.class);
startActivityForResult(intent, 1);
}
return super.onOptionsItemSelected(item);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == 1) {
if (requestCode == 1) {
if (data.hasExtra("IP"))
strIP = data.getExtras().getString("IP");
Toast.makeText(this, strIP, Toast.LENGTH_LONG).show();
// luk for at forhindre flere i at forbinde
try {
serverSocket.close();
} catch (IOException e) {
error = e.toString();
Message message = new Message();
message.what = -1;
UpdateHandler.sendMessage(message); }
}
}
}
@Override
protected void onStop() {
super.onStop();
if (listenThread != null)
if (listenThread.isAlive())
try {
serverSocket.close();
} catch (IOException e) {
error = e.toString();
Message message = new Message();
message.what = -1;
UpdateHandler.sendMessage(message);
}
listenThread.interrupt();
if (sendThread != null)
if (sendThread.isAlive())
sendThread.interrupt();
}
Handler UpdateHandler = new Handler() {
public void handleMessage(Message msg) {
this.obtainMessage();
switch (msg.toString()) {
case "0":
// TODO: afbryd forbindelsen
break;
case "-1":
insertError();
break;
default:
InsertChat();
}
}
};
void ThreadHandler() {
}
void InsertChat() {
if(chatView != null)
chatView.setText(rcv);
else
{
chatView = (TextView) findViewById(R.id.txtViewChat);
chatView.setText(rcv);
}
}
void insertError()
{
errorView = (TextView) findViewById(R.id.viewFejl);
errorView.setText(error);
}
public void SendChat(View view) {
// gør det hele asynkront og send beskeder i en tråd for sig.
if(sendThread == null)
sendThread = new Thread(new SendMessage());
if (!sendThread.isAlive()) {
this.sendThread = new Thread(new SendMessage());
this.sendThread.start();
}
}
/**
* A placeholder fragment containing a simple view.
*/
public static class PlaceholderFragment extends Fragment {
public PlaceholderFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_chat, container,
false);
return rootView;
}
}
class Listener implements Runnable {
boolean shouldRun = true;
@Override
public void run() {
Looper.prepare();
// Looper.loop();
BufferedReader reader = null;
if (socket == null) {
try {
serverSocket = new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
}
Message message = new Message();
rcv = "debug1";
UpdateHandler.sendMessage(message);
try {
if(strIP != "")
socket = new Socket(strIP, port);
else if (socket == null)
socket = serverSocket.accept();
Toast.makeText( getApplicationContext(), socket.getInetAddress().toString()+ " er forbundet", Toast.LENGTH_LONG).show();
while (!Thread.currentThread().isInterrupted() && shouldRun) {
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
rcv = reader.readLine();
if(rcv == null) //er forbindelsen forsvundet?
shouldRun = false;
else
{
message.what = 0;
UpdateHandler.dispatchMessage(Message.obtain());
}
}
} catch (Exception e) {
error = e.toString();
message.what = -1;
UpdateHandler.dispatchMessage(message);
if(e != null)
e.printStackTrace();
}
try {
if (reader != null)
{
reader.close();
socket.close();
socket = null;
serverSocket.close();
}
} catch (IOException e) {
error = e.toString();
message.what = -1;
UpdateHandler.dispatchMessage(message);
if(e != null)
e.printStackTrace();
}
//Toast.makeText(getApplicationContext(), "lukker", Toast.LENGTH_LONG).show();
}
}
class SendMessage implements Runnable {
@Override
public void run() {
Looper.prepare();
try {
EditText textBox = (EditText) findViewById(R.id.txtChat);
PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())));
writer.println(textBox.getText().toString());
writer.flush(); //send før bufferen er fuld
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "fejl", Toast.LENGTH_LONG).show();
}
}
}
}
我无法弄清楚如何更新UI,因为你无法在UI线程上运行套接字。