我正在尝试制作一个聊天程序,它将每 2 秒拉一次服务器以获取新的 chts。
起初我只是创建了一个线程并更新了线程上的 ui,它崩溃了。
我添加了一个 runnable,其中 run 方法调用了一个名为 SendMessge 的方法。SendMessage 通过 Internet 获取更新的信息,然后更新 ui。
我以为runnable中的run方法将在我的线程下运行,它似乎在ui线程上运行。
当我在发送消息中的网络代码出现错误时,UI 冻结了。
然后我设置了2个断点。一个在runnable之前,下一个在runnable之后。接下来,我在我的服务器中设置了一个断点,这样网络代码就会冻结。那么在android上第一个断点消失了,然后它在runnable之后进入断点而没有等待我释放服务器上的断点,因此我假设runnable在不同的线程上运行,因为代码没有不要等待,我假设它是 ui 线程。
好吧,如果我有这个权利。在创建可运行文件之前,我的网络代码将在线程中。然后将在其运行方法中更新 ui。当我获得更新ui的新信息时出现问题,我如何将它发送到runnable中的run方法???
我的代码:
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(){
}