在线程方面需要帮助

时间:2012-06-22 13:15:38

标签: android

我正在尝试制作一个聊天程序,每隔2秒就会为新chts拉一次服务器。

起初我只是创建了一个线程并在线程上更新了ui,它崩溃了。

我添加了一个runnable,其中run方法调用一个名为SendMessge的methed。 SendMessage通过互联网获取更新的信息,然后更新了ui。

我认为runnable中的run方法将在我的线程下运行,好像它在ui线程上运行。

当发送消息中的网络代码出现问题时,用户界面就会冻结。

然后我设置2个断点。一个在runnable之前,另一个在runnable之后。接下来,我在我的服务器中设置了一个断点,以便网络代码可以冻结。好吧,在android上第一个断点消失了,然后它在runnable之后转到了断点,而没有等我释放服务器上的brek点,因此我认为runnable在不同的线程上运行,因为代码没有不等待,我假设它的ui线程。

好的,如果我有这个权利。在创建runnable之前,我的网络代码将在线程中。然后将在其run方法中更新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(){
}

1 个答案:

答案 0 :(得分:0)

尝试使用AsyncTask进行线程处理。 谷歌最简单的教程。

并确保您不在UI线程之外的线程中执行任何UI操作。始终为UI操作执行activity.runOnUiThread()。喜欢

//获取新文字

Editable text = mUserChat.getText();
comment = text.toString();
mUserChat.setText("");

此代码必须在不在永久线程上的UI线程上运行。我从你在线程的run()方法中调用的方法中获取了这段代码。

在外部线程中。您必须进行处理和数据工作。和UI更新必须在UI线程上完成,并在UI上运行东西线程总是使用activity.runOnUiThread()方法。

的问候, Aqif Hamid