2014-04-17 79 views
0

我試圖想出一個與C#服務器交談的Android客戶端應用程序。我想用服務器回覆消息同時更新我的​​TextView。我使用此代碼收到消息Android的TCP客戶端TextView不更新

public class LogedInActivity extends ActionBarActivity { 
private Spinner meterBrands; 
private EditText sayacNo,plcNo; 
private String serverMessage="Message is"; 
private TextView serverStatus; 
private String messageID="120"; 
private String messageEnd="*?/"; 
private Thread clientThread; 
private static final int SERVERPORT = sss; 
private static final String SERVER_IP = "sss"; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_loged_in); 
    serverStatus= (TextView) findViewById(R.id.serverStatus); 

    if (savedInstanceState == null) { 
     getSupportFragmentManager().beginTransaction() 
     .add(R.id.container, new PlaceholderFragment()).commit(); 
    } 

} 
public void sendMessage(View view) { 

    hideSoftKeyboard(this); 
    meterBrands= (Spinner) findViewById(R.id.brandsSpinner); 
    String temp=String.valueOf(meterBrands.getSelectedItem()); 
    if(isValidMeterAndPLC()){ 
     new Thread(new Runnable() { 
      public void run() { 
       connectSocket(messageToSend()); 

       } 
      }).start(); 

    } else { 
     new Thread(new Runnable() { 
      public void run() { 
       connectSocket("1"); 
        } 
      }).start(); 
    } 


} 


private String connectSocket(String message){ 

String finalText = ""; 
try { 
    InetAddress serverAddr = InetAddress.getByName(SERVER_IP); 
    Log.d("TCP", "C: Connecting..."); 
    Socket socket = new Socket(serverAddr, SERVERPORT); 



    PrintWriter out = null; 
    BufferedReader in = null; 

    try { 
     Log.d("TCP", "C: Sending: '" + message + "'"); 
     out = new PrintWriter(new BufferedWriter(new  OutputStreamWriter(socket.getOutputStream())),true); 
     in = new BufferedReader(new InputStreamReader(socket.getInputStream()));     
     out.println(message); 
     String text = ""; 
     while ((text = in.readLine()) != null) { 
      finalText += text; 
      serverStatus.setText(finalText); 
      } 


     Log.d("TCP", "C: Sent."); 

     Log.d("TCP", "C: Done.");    

    } catch(Exception e) { 
     Log.e("TCP", "S: Error", e); 
    } finally { 
     socket.close(); 
    } 

} catch (UnknownHostException e) { 
    // TODO Auto-generated catch block 
    Log.e("TCP", "C: UnknownHostException", e); 
    e.printStackTrace(); 
} catch (IOException e) { 
    // TODO Auto-generated catch block 
    Log.e("TCP", "C: IOException", e); 
    e.printStackTrace(); 
}  
return finalText; 
} 


public String messageToSend(){ 
    String infoString; 
    sayacNo= (EditText) findViewById(R.id.sayacNoTextBox); 
    plcNo= (EditText) findViewById(R.id.plcNoTextBox); 

    infoString= messageID+"-"+sayacNo.getText()+"-"+meterBrands.getSelectedItem().toString()+"-"+plcNo.getText()+ "-" +messageEnd+"-" ; 
    infoString+=checkSum(infoString); 

    return infoString; 

} 
public int checkSum(String str){ 
    int checkSum=0; 
    char [] strChars= str.toCharArray(); 
    for(int i=0;i<strChars.length;i++){ 
     checkSum+= (int) strChars[i]; 

    } 


    return checkSum; 
} 
public void messageDisplay(String servermessage){ 
    serverStatus= (TextView) findViewById(R.id.serverStatus); 
    serverStatus.setText(servermessage); 

} 


private boolean isValidMeterAndPLC(){ 
    boolean check=true; 
    int sayacNoInt=0; 
    sayacNo=(EditText) findViewById(R.id.sayacNoTextBox); 
    plcNo=(EditText) findViewById(R.id.plcNoTextBox); 

    sayacNoInt=Integer.parseInt(sayacNo.getText().toString()); 
    if(sayacNoInt<100 || sayacNoInt>65530){ 
     alertbox("Yanlış Sayaç Numarası","Yanlış sayaç numarası girdiniz. Lütfen tekrar deneyin."); 
     check=false; 

    } 
    if(plcNo.getText().toString().length()!=8){ 
     alertbox("Yanlış PLC Numarası","Yanlış PLC numarası girdiniz. Lütfen tekrar deneyin."); 
     check=false; 
    } 
    return check; 

} 
protected void alertbox(String title, String mymessage) 
{ 

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(
      this); 

    // set title 
    alertDialogBuilder.setTitle(title); 

    // set dialog message 
    alertDialogBuilder 
    .setMessage(mymessage) 
    .setCancelable(false) 
    .setPositiveButton("Okay",new DialogInterface.OnClickListener() { 
     public void onClick(DialogInterface dialog,int id) { 
      // if this button is clicked, close 
      // current activity 

     } 
    }); 

    // create alert dialog 
    AlertDialog alertDialog = alertDialogBuilder.create(); 

    // show it 
    alertDialog.show(); 
} 

@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    // Handle action bar item clicks here. The action bar will 
    // automatically handle clicks on the Home/Up button, so long 
    // as you specify a parent activity in AndroidManifest.xml. 
    int id = item.getItemId(); 
    if (id == R.id.action_settings) { 
     return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

/** 
* A placeholder fragment containing a simple view. 
*/ 
public static class PlaceholderFragment extends Fragment { 

    public PlaceholderFragment() { 
    } 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
      Bundle savedInstanceState) { 
     View rootView = inflater.inflate(R.layout.fragment_loged_in, 
       container, false); 
     return rootView; 
    } 
} 
@Override 
public boolean onTouchEvent(MotionEvent event) { 

    hideSoftKeyboard(this); 

    return false; 
} 

/*back button override. 
@Override 
public boolean onKeyDown(int keyCode, KeyEvent event) { 
    if (keyCode == KeyEvent.KEYCODE_BACK) { 
     alertbox("asasda","5333434"); 
     return true; 
    } 

    return super.onKeyDown(keyCode, event); 
} 
*/ 
public static void hideSoftKeyboard(Activity activity) { 

    InputMethodManager inputMethodManager = (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE); 
    inputMethodManager.hideSoftInputFromWindow(activity.getCurrentFocus().getWindowToken(), 0); 
} 

} 

然而,因爲它是在一個線程

 new Thread(new Runnable() { 
      public void run() { 
       connectSocket(messageToSend()); 

        } 
      }).start(); 

回答

0

簡單的包裝,你與runOnUiThread()聲明更新句話我不能更新我的TextView。例如:

your_context.runOnUiThread(new Runnable() { 
    public void run() { 
    myTextView.setText("..."); 
    } 
}); 

任何包裹在runOnUiThread()聲明實際上將在主界面Thread運行,所以要小心不要在此處添加一些昂貴的操作。

---- ----編輯

new Thread(new Runnable() { 
    public void run() { 
    connectSocket(messageToSend()); 

    // Do whatever you need 
    ... 

    // Once you want to update your TextView... 
    final myTextView tv = (TextView) your_context.findViewById(R.id.myTextView); 
    final String myText = "whatever"; 

    your_context.runOnUiThread(new Runnable() { 
     public void run() { 
     myTextView.setText(myText); 
     } 
    }); 
    } 
}).start(); 
+0

我有2個問題這一點。 1)如果我在我使用connectSocket方法的地方做了它,我得到一個異常,說你不能在UIthread中建立網絡連接。 2)如果我這樣做,我settext(這是在connectSocket方法)它說文本應該是最終的。 – Barbaros

+0

但是,只需在'runOnUiThread'的'run()'方法內部通過'.setText()'將文本分配給'TextView'的語句就行了!正如我寫的,這將在UI線程中運行,所以你必須在這裏放置必要的。這樣你就不會有網絡連接,你不會得到異常。 – nKn

+0

只需將'text'變量聲明爲'final String text = ...'。 – nKn