我正在嘗試創建一個聊天程序,它將每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