2013-12-20 24 views
0

當我點擊第一次登錄按鈕時,數據發送到服務器和服務器接收到的數據作爲回報,第一次點擊數據不顯示在Android客戶端屏幕上。當我再次按登錄按鈕時,它再次發送數據,然後顯示客戶端屏幕上的數據... PLZ幫助我。爲什麼數據收到後,我希望我的數據在我第一次點擊時收到? 下面是代碼:爲什麼雙擊android客戶端收到的數據?

客戶TCPIP代碼...

public class SockProg { 

    private Socket socket; 
    DataOutputStream dataOutputStream; 
    DataInputStream dataInputStream; 
    String data; 
    String serverip = "192.168.1.7"; 
    int serverport = 4444; 



    public void connetToServer(){ 
     try { 
      socket = new Socket(serverip, serverport); 
      Log.i("AsyncTank", "doInBackgoung: Created Socket"); 
     } catch (UnknownHostException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     if (socket.isConnected()) { 
      try { 
       dataOutputStream = new DataOutputStream(
         socket.getOutputStream()); 
       dataInputStream = new DataInputStream(socket.getInputStream()); 


      } catch (IOException e) { 
       e.printStackTrace(); 
      } 

     } 
    } 
    public void writeToStream(String message) { 
     try { 
      if (socket.isConnected()){ 
       dataOutputStream.writeUTF(message.toString()); 
      } else { 
       Log.i("AsynkTask", "writeToStream : Cannot write to stream, Socket is closed"); 
      } 
      } catch (Exception e) { 
      Log.i("AsynkTask", "writeToStream : Writing failed"); 
      } 
    } 
    public String readFromStream() { 
     String ret = null; 
     try { 
      if (socket.isConnected()) { 
       Log.i("AsynkTask", "readFromStream : Reading message"); 
       ret=dataInputStream.readUTF(); 
       Log.i("AsynkTask", "readFromStream : read "+ret); 

      } else { 
       Log.i("AsynkTask", "readFromStream : Cannot Read, Socket is closed"); 
      } 
     } catch (Exception e) { 
      Log.i("AsynkTask", "readFromStream : Reading failed"+e.getClass()); 
     } 
     return ret; 
     } 
    public void CloseSockets(){ 
     if (socket != null) { 
      try { 
       socket.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     if (dataOutputStream != null) { 
      try { 
       dataOutputStream.close(); 
      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 
     } 

     if (dataInputStream != null) { 
      try { 
       dataInputStream.close(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } 
     } 
    } 
} 

這裏是sychronized線程

public class TCP implements Runnable { 


    String data; 
    SockProg sp; 
    Thread thh; 
    private static String rdata; 

    public TCP(SockProg spr, String val) { 
     sp = spr; 
     data = val; 
     thh = new Thread(this); 
     thh.start(); 
    } 


    @Override 
    public void run() { 
     synchronized(sp) { // synchronized block 
      //rdata= sp.DataSendRecive(data); 
      sp.connetToServer(); 
      sp.writeToStream(data); 
      rdata=sp.readFromStream(); 
      sp.CloseSockets(); 
      } 
    } 
    public static String getData(){ 
     return rdata; 
    } 


} 

這裏的代碼是登錄活動的代碼。 ..

@Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_login); 
     msg = (TextView) findViewById(R.id.msg_log); 
     login = (Button) findViewById(R.id.btn_login); 

     login.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       // try{ 

       txtph = (EditText) findViewById(R.id.txt_phnum); 
       txtpass = (EditText) findViewById(R.id.txt_pass); 
       ph = txtph.getText().toString(); 
       pass = txtpass.getText().toString(); 

       int ch = 0; 

       if (ph.equals("") || ph == null) { 
        msg.setText("Please Enter Mobile Number....\n"); 
        ch++; 
       } 
       if (pass.equals("") || pass == null) { 
        if (ch == 0) { 
         msg.setText("Please Enter your Password....\n"); 
        } else { 
         msg.append("Please Enter your Password....\n"); 
        } 

        ch++; 
       } 
       if (ch == 0) { 

        ArrayList<String> ph_pass = new ArrayList<String>(); 
        ph_pass.add(0, "LoginAccount"); 
        ph_pass.add(1, ph); 
        ph_pass.add(2, pass); 
        SockProg sp=new SockProg(); 
        TCP t=new TCP(sp, ph_pass.toString()); 
        data=t.getData(); 
        msg.setText(data); 


       } 
      } 

     }); 

    } 

回答

0

這看起來像是異步編碼延遲的經典案例。 TCP類是可運行的,併爲此當它被稱爲第一次(在登錄按鈕的第一次點擊)它開始運行,但該線程沒有足夠的時間來完成

rdata=sp.readFromStream(); 

在run()方法,因此data=t.getData();不會返回任何有用的東西。第二次點擊,爲runnable提供足夠的時間用一些數據填充rdata,因此您的程序可以工作。

使用異步代碼時,您需要一個更好的方式來等待代碼完成正在執行的操作。

rdata爲什麼是靜態類型?使其成爲非靜態,然後更改像這樣的getData()方法:

public synchronized String getData() 
+0

我明白你在說什麼...但我的第一次點擊,我想我的數據recived這是由服務器發送..有任何改變你在這段代碼中建議我? – Aamir

+0

是的,閱讀我的文章的最後一行,並使rdata非靜態,並使getData方法同步 – Husman

+0

我做到了你說的,但結果是一樣的:(:( – Aamir

相關問題