【问题标题】:Android TCP Client TextView doesn't UpdateAndroid TCP 客户端 TextView 不更新
【发布时间】:2014-04-17 15:07:26
【问题描述】:

我正在尝试开发一个与 C#server 对话的 android 客户端应用程序。我想与服务器回复消息同时更新我的​​ 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);
}

}

但是,我无法更新我的 TextView,因为它在一个线程中

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

                    }
            }).start();

【问题讨论】:

    标签: android multithreading tcpclient settext


    【解决方案1】:

    只需使用runOnUiThread() 语句将您更新的句子包装起来。例如:

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

    runOnUiThread() 语句中包含的任何内容实际上都会在主 UI 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();
    

    【讨论】:

    • 我有两个问题。 1) 如果我在使用connectSocket 方法的地方执行此操作,则会出现异常,提示您无法在UIthread 中建立网络连接。 2)如果我在我设置文本的地方(在 connectSocket 方法中)这样做,它说文本应该是最终的。
    • 但只需在runOnUiThreadrun() 方法中放入通过.setText() 将文本分配给TextView 的句子,仅此而已!正如我所写,这将在 UI 线程中运行,因此您必须在此处放置必要的内容。这样你就不会在里面有网络连接,也不会出现异常。
    • 只需将text 变量声明为final String text = ...
    • 我退出了 android 并更新了我的问题。你能告诉我在哪里以及如何?
    • 也许AsyncTask 更合适。
    猜你喜欢
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 2012-03-29
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-21
    相关资源
    最近更新 更多