2014-10-11 40 views
0

代码第一:活动挂起TextView.setText()

public class MyActivity extends Activity { 

    Button send; 
    TextView textv; 
    String answer; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 

     super.onCreate(savedInstanceState); 
     setContentView(R.layout.my_activity); 

     send = (Button)findViewById(R.id.sendButton); 
     textv = (TextView)findViewById(R.id.textViewv); 

     send.setOnClickListener(new OnClickListener() { 
      @Override 
      public void onClick(View v) {  
       MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION"); 
       myClientTask.execute(); 
      } 
     });  
    } 


    void processAnswer() { 
     Log.i("DEBUG", "in processAnswer - before setting text"); 
     Log.i("DEBUG", "ANSWER"); 

     textv.setText("ANSWER\n"); // <-------- H E R E ----------- 

     Log.i("DEBUG", "in processAnswer - after setting text"); 
    } 



    public class MyClientTask extends AsyncTask<Void, Void, Void> { 

      String dstAddress; 
      int dstPort; 

      String message; 
      String response; 

      MyClientTask(String addr, int port, String msg){ 
      dstAddress = addr; 
      dstPort = port; 
      message = msg; 
      response = ""; 
      } 

      @Override 
      protected Void doInBackground(Void... arg0) { 

      Socket socket = null; 

      try { 
       InetAddress serverAddr = InetAddress.getByName(dstAddress); 

       socket = new Socket(serverAddr, dstPort); 
       OutputStream out = socket.getOutputStream();  
       out.write(message.getBytes()); 
       out.flush(); 

       String msgrc = ""; 
       int charsRead = 0; 
       char[] inputBuf = new char[4096]; 

       InputStream is = socket.getInputStream(); 
       InputStreamReader isr = new InputStreamReader(is); 
       BufferedReader in = new BufferedReader(isr); 
       while ((charsRead = in.read(inputBuf)) != -1) { 
         msgrc += new String(inputBuf).substring(0, charsRead); 
       } 

       // outer class variable 
       MyActivity.this.answer = msgrc; 

       out.close(); 
       is.close(); 
       socket.close(); 


       Log.i("DEBUG", "before processing answer"); 
       MyActivity.this.processAnswer(); 
       Log.i("DEBUG", "after processing answer"); 

      } catch (Exception e) { 

      } 

      return null; 
      } 
    } 
} 

上述代码简单地发送一些消息给服务器,并接收一个答案。这个答案应该显示在TextView中(见标记行)。然而,该应用挂在该线上,即LogCat显示

[...] 
before processing answer 
in processAnswer - before setting text 
ANSWER 

然后没有更多的行被写入LogCat。有没有人对此作出解释?如果标记行注释掉,logcat的样子

[...] 
before processing answer 
in processAnswer - before setting text 
ANSWER 
in processAnswer - after setting text 
after processing answer 
+0

其中日志变量在代码中声明? – 2014-10-11 12:58:57

+0

对不起,应该是textv。我编辑了代码。 – user236012 2014-10-11 12:59:44

+0

textv分配在哪里?既然你一直试着抓住你,那么你也不例外。应用程序正在抛出空指针异常 – 2014-10-11 13:02:10

回答

0

如果您移动到MyActivity.this.processAnswer()呼叫onPostExecute()相反,也许是可能的工作 - IIRC,在UI线项目应该只从更新UI线程。

+0

工程就像一个魅力!谢谢。根据你的解释,“onPostExecute”然后由主线程执行,而“doInBackground”由单独的线程运行? – user236012 2014-10-11 13:21:19

+0

没错 - 还有一个onPreExecute – Shadru 2014-10-11 22:57:20

0

首先通过以下方式初始化文本视图,然后在doInBackground方法下面添加onPostExecute方法。并在那里设置你的文字。贝娄是我改变的代码。

public class MyActivity extends Activity { 

Button send; 
TextView textv; 
String answer; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 

    super.onCreate(savedInstanceState); 
    setContentView(R.layout.my_activity); 

    send = (Button)findViewById(R.id.sendButton); 
    textv = (TextView)findViewById(R.id.textview); 

    send.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) {  
      MyClientTask myClientTask = new MyClientTask("localhost", 1234, "QUESTION"); 
      myClientTask.execute(); 
     } 
    });  
} 



public class MyClientTask extends AsyncTask<Void, Void, Void> { 

     String dstAddress; 
     int dstPort; 

     String message; 
     String response; 

     MyClientTask(String addr, int port, String msg){ 
     dstAddress = addr; 
     dstPort = port; 
     message = msg; 
     response = ""; 
     } 

     @Override 
     protected Void doInBackground(Void... arg0) { 

     Socket socket = null; 

     try { 
      InetAddress serverAddr = InetAddress.getByName(dstAddress); 

      socket = new Socket(serverAddr, dstPort); 
      OutputStream out = socket.getOutputStream();  
      out.write(message.getBytes()); 
      out.flush(); 

      String msgrc = ""; 
      int charsRead = 0; 
      char[] inputBuf = new char[4096]; 

      InputStream is = socket.getInputStream(); 
      InputStreamReader isr = new InputStreamReader(is); 
      BufferedReader in = new BufferedReader(isr); 
      while ((charsRead = in.read(inputBuf)) != -1) { 
        msgrc += new String(inputBuf).substring(0, charsRead); 
      } 

      // outer class variable 
      MyActivity.this.answer = msgrc; 

      out.close(); 
      is.close(); 
      socket.close(); 


      Log.i("DEBUG", "before processing answer"); 
      MyActivity.this.processAnswer(); 
      Log.i("DEBUG", "after processing answer"); 

     } catch (Exception e) { 

     } 

     return null; 
     } 


     @Override 
    protected void onPostExecute(Void result) { 
     // TODO Auto-generated method stub 
     super.onPostExecute(result); 

     textv.setText(msgrc); 

    } 
} 
} 
+0

onPostExecute的签名应该是“protected void onPostExecute(Void result)”---代码“MyActivity.this.processAnswer()”应该移到“onPostExecute”,那么它就可以工作。在Shadru看到答案。谢谢! – user236012 2014-10-11 13:18:54

+0

我已编辑我的答案,如果它是有帮助的PLZ upvote我的回答 – Harshad07 2014-10-11 13:20:45

+0

我会,但没有足够的声誉:/ – user236012 2014-10-11 13:22:32