0

新しいチャットのために2秒ごとにサーバーをプルするチャットプログラムを作成しようとしています。

最初はスレッドを作成し、スレッドのUIを更新しただけで、クラッシュしました。

run メソッドが SendMessge というメソッドを呼び出す runnable を追加しました。SendMessage は、インターネット経由で更新された情報を取得し、UI を更新します。

runnable の run メソッドが自分のスレッドで実行されると思っていましたが、UI スレッドで実行されているようです。

Send Message のネットワーク コードにバグがあると、UI がフリーズしました。

次に、2 つのブレークポイントを設定します。ランナブルの前に 1 つ、ランナブルの後に 1 つ。次に、ネットワーク コードがフリーズするように、サーバーにブレーク ポイントを設定しました。アンドロイドでは、最初のブレークポイントがオフになり、サーバー上のブレークポイントを解放するのを待たずにランナブルの後にブレークポイントに移動しました。したがって、コードが実行されたため、ランナブルが別のスレッドで実行されていたと想定しています待ってはいけません。UIスレッドだと思います。

私がこの権利を持っていれば、わかりました。実行可能ファイルを作成する前に、ネットワーク コードがスレッドに含まれます。次に、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(){
}
4

1 に答える 1

0

スレッド化の目的で AsyncTask を使用してみてください。最も簡単なチュートリアルについては、Google を参照してください。

また、UI スレッド以外のスレッド内で UI 操作を行わないようにしてください。UI 操作には必ず activity.runOnUiThread() を実行してください。お気に入り

// 新しいテキストを取得

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

このコードは、エターナル スレッドではなく、UI スレッドで実行する必要があります。スレッドの run() メソッド内で呼び出すメソッドから、このコードの平和を取りました。

おねじで。処理とデータ作業を行う必要があります。UI の更新は UI スレッドで行う必要があり、UI スレッドで実行するには、常に activity.runOnUiThread() メソッドを使用します。

よろしく、 Aqif Hamid

于 2012-06-22T13:35:58.780 に答える