我正在尝试创建一个聊天程序,它将每2秒为新的聊天服务器拉动服务器。在线程中需要帮助
起初我只是简单地创建了一个线程并更新了线程中的ui,它崩溃了。
我添加了runnable,其中run方法调用了名为SendMessge的方法。 SendMessage通过互联网获取更新的通知,然后更新UI。
我虽然runnable中的run方法会在我的线程下运行,但它好像在ui线程上运行一样。
当我在发送消息中的网络代码错误时,UI冻结。
然后我设置了2个断点。一个在可运行之前,另一个在可运行之后。接下来,我在服务器上放置一个断点,以便网络代码可以freez。那么在android上,第一个断点就会熄灭,然后它在可运行后进入中断点,而不用等待我释放服务器上的brek点。因此,我假设runnable运行在不同的线程上,因为代码确实不要等待,我假设它的UI线程。
好吧,如果我有这个权利。在创建可运行之前,我的网络代码将在线程中。然后将在其运行方法中更新ui。问题,当我得到新的信息来更新用户界面,我如何将它发送到runnable的运行方法?
我的代码:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.chat);
strComment=new String("na");
mUsers=(TextView) findViewById(R.id.viewusers);;
mComments=(TextView) findViewById(R.id.viewchats);
mUserChat=(EditText) findViewById(R.id.viewedit);
mScroll=(ScrollView) findViewById(R.id.scrollcomments);
mHome=(Button) findViewById(R.id.butHome);
mHome.setOnClickListener(this);
mEnter=(Button) findViewById(R.id.butEnter);
mEnter.setOnClickListener(this);
Thread thread = new Thread(){
@Override
public void run() {
try {
int t=0;
flagEnter=true;
while(true){
handler.post(new Runnable() {
// I put a break point here
@Override
public void run() {
SendMessage();
}
});
// I put another break point here, it went right here without waiting for the sendmessage to finish
sleep(1000*10);
//while(true);
}
}catch (InterruptedException e) {
e.printStackTrace();
}
}
};
thread.start();
}
public void onClick(View v) {
Intent i;
switch(v.getId()) {
case R.id.butEnter:
Editable e = mUserChat.getText();
strComment=e.toString();
flagAdd=true;
break;
case R.id.butHome:
i = new Intent(this, TellaFortuneActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
break;
}
} // end function
// send a uypdate message to chat server
// return reply in string
void SendMessage(){
//////////////////////////////////
// handle flags
String de=new String("");
String strUsers=new String("");
String strComments=new String("");
String comment=new String("NA");
if (flagHome){
Intent i;
i = new Intent(this, TellaFortuneActivity.class);
i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(i);
return;
}
String flag="update";
if (flagAdd){
// get new text
Editable text=mUserChat.getText();
comment=text.toString();
mUserChat.setText("");
flag="add";
}
if (flagEnter)
flag="enter";
if (flagExit){
flag="exit";
flagHome=true;
}
// clear all flags
try {
URL url = new URL("http://50.63.66.138:1044/"+flag);
System.out.println("make connection");
String data = URLEncoder.encode("username", "UTF-8") + "=" + URLEncoder.encode("tedpottel", "UTF-8");
data += "&" + URLEncoder.encode("comment", "UTF-8") + "=" + URLEncoder.encode(comment, "UTF-8");
URLConnection conn = url.openConnection();
// set timeouts to 5 seconds
conn.setConnectTimeout(1000*5);
conn.setReadTimeout(5*1000);
conn.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(conn.getOutputStream());
wr.write(data);
wr.flush();
wr.close();
// if (flagAdd==false){
BufferedReader rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line=new String();
int state=0;
while ((line= rd.readLine() ) != null) {
de=de+line;
switch(state){
case 0:
if (line.contains("START USER"))
state=1;
if (line.contains("START COMMENTS"))
state=2;
break;
case 1:
if (line.contains("END USER"))
state=0;
else{
strUsers+=line;
strUsers+="\n";
}
break;
case 2:
// NOTE: end of comments is end, but......
// if we do not read in ALL the dat from server
// could cause connection errors
if (line.contains("END COMMENTS"))
state=0;
else {
strComments+=line;
strComments+="\n";
}
break;
} // end switch
} // end loop
rd.close();
}
// the next line will cause a exception
// mUsers.setText(strUsers);
// mComments.setText(strComments);
} catch (Exception e) {
i++; // use this to see if it goes here in debugger
System.out.println("exception");
System.out.println(e.getMessage());
}
flagAdd=false;
flagEnter=false;
flagExit=false;
} // end methed
void Test(){
}
这可能是有点过分线程和轮询在你的主线程,可以考虑使用'Service'(它实际上并不难/复杂的),至少在投票。我做了这样的经验,只要你只使用1个活动,简单的线程就可以很好地工作,而不是更多。但是在一个'Service'中运行'ScheduledThreadPoolExecutor'进行轮询非常强大。 – trichner