2017-04-13 40 views
0

我们有一个主要活动,其中有一个文本视图,要求它从LAN中的TCP服务器自动检索数据。 我们在updateData()中启用AsyncTask来调用Connect调用Handler以更新名为mTvVoc的TextView,并通过beginConnect()刷新连接。Android AsyncTask +处理程序,没有数据更新到主要活动UI

问题是mTvVoc没有更新,它似乎AsyncTask不能按预期方式工作?

public class MainActivity extends Activity { 

protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    updateData(); 
} 


    public void updateData(final String order) { 
     Connect(HOST, PORT, order); 
     new AsyncTask<Void, Void, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 
       System.out.println("get data from order--->" + order); 
       beginConnect(HOST, PORT, order); 
       return null; 
      } 

      @Override 
      protected void onPostExecute(Void aVoid) { 
       super.onPostExecute(aVoid);     
      } 

     }.execute(); 
    } 

    public String Connect(final String HOST, final int PORT, final String OderType) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        socket = new Socket(HOST, PORT); 
        bufferedInputStream = new  BufferedInputStream(socket.getInputStream()); 
        System.out.println("bufferedInputStream--->" + bufferedInputStream); 
        printWriter = new PrintWriter(new BufferedWriter(
          new OutputStreamWriter(socket.getOutputStream())), 
         true); 
        if (socket.isConnected()) { 
         if (!socket.isOutputShutdown()) { 
          printWriter.println(Integer.toHexString(Integer 
           .parseInt(OderType))); 
         } 
        } 

        while (true) { 
         if (!socket.isClosed() && socket.isConnected() && !socket.isInputShutdown()) { 
          int temp = 0; 
          byte[] buf = new byte[1024]; 
          while ((temp = bufferedInputStream.read(buf)) != -1) { 
           isConn(socket); 
           Log.d("Data received", new String(buf, 0, temp)); 
           acceptinfo = new String(buf, 0, temp); 
           System.out.println("Data received====》" + acceptinfo); 
           Message message = new Message(); 
           message.what = 1; 
           message.obj = acceptinfo; 
           handler.sendMessage(message); 
          } 
         } 
        } 
       } catch (UnknownHostException e) { 
        System.out.println("UnknownHostException-->connection failed"); 
        stopConnect(); 
        e.printStackTrace(); 
       } catch (IOException e) { 
        System.out.println("IOException-->connection failed"); 
        stopConnect(); 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
     return acceptinfo; 
    } 


    public String beginConnect(final String HOST, final int PORT, final String OderType) { 
     new Thread(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        socket = new Socket(HOST, PORT); 
        bufferedInputStream = new BufferedInputStream(socket.getInputStream()); 
        System.out.println("bufferedInputStream--->" + bufferedInputStream); 
        printWriter = new PrintWriter(new BufferedWriter(
         new OutputStreamWriter(socket.getOutputStream())), 
         true); 
        if (socket.isConnected()) { 
         if (!socket.isOutputShutdown()) { 
           printWriter.println(Integer.toHexString(Integer.parseInt(OderType))); 
         } 
        } 
       } catch (UnknownHostException e) { 
        System.out.println("UnknownHostException-->connection failed"); 
        stopConnect(); 
        e.printStackTrace(); 
       } catch (IOException e) { 
        System.out.println("IOException-->connection failed"); 
        stopConnect(); 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
     return acceptinfo; 
    } 


    public Handler handler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      super.handleMessage(msg); 
      Log.i("message", msg.obj.toString()); 
      if (msg.what == 0) { 
       mIvContent.setImageResource(R.drawable.wangluo_gray); 
       Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show(); 
       reGetData(); 
      } 
      if (msg.what == 1) { 
       String info = msg.obj.toString(); 
       if (info.length() != 18) { 
        mIvContent.setImageResource(R.drawable.wangluo_gray); 
        System.out.println("data verification failed"); 
        reGetData(); 
        return; 
       } 

       String iszeroupString = info.substring(1, 3); 
       String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16)); 
       String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16)); 
       mTvVoc.setText(getVOC((Integer.valueOf(vocValue)/100.00))); 

      } 
     } 
} 
+0

很奇怪你有一个连接()和一个连接到服务器的beginConnect()。所以两个客户端实例。你为什么这样做?没有意义。 – greenapps

+0

而你在doInBackground中开始新的主题是完全错误的。只需将代码直接放入doInBackground中,而无需将其包装在线程中。并且不要两次连接。那么除非你有很好的理由这样做,但你没有告诉我们。使用线程或异步任务。不是都。 – greenapps

+0

所以我需要删除beginConnect()? – Freshman

回答

0

你不能直接从后台线程传达给UI线程 更新任何UI组件。

使用此在后台线程从AsyncTask.

new Handler(Looper.getMainLooper()).post(new Runnable() { 
    @Override 
    public void run() { 
     Log.d("UI thread", "I am the UI thread"); 
     // update your text here 
    } 
}); 
0

更新textview要在UI更新,则需要在UIThread运行代码。请参见下面的代码,并在您的处理程序:

runOnUiThread(new Runnable() { 
    @Override 
    public void run() { 
     Log.i("message", msg.obj.toString()); 
     if (msg.what == 0) { 
      mIvContent.setImageResource(R.drawable.wangluo_gray); 
      Toast.makeText(MainActivity.this, "Server connection failed", Toast.LENGTH_SHORT).show(); 
      reGetData(); 
     } 
     if (msg.what == 1) { 
      String info = msg.obj.toString(); 
      if (info.length() != 18) { 
       mIvContent.setImageResource(R.drawable.wangluo_gray); 
       System.out.println("data verification failed"); 
       reGetData(); 
       return; 
      } 

      String iszeroupString = info.substring(1, 3); 
      String temperature = Integer.toString(Integer.parseInt(info.substring(3, 5), 16)); 
      String vocValue = Integer.toString(Integer.parseInt(info.substring(7, 9), 16)); 
      mTvVoc.setText(getVOC((Integer.valueOf(vocValue)/100.00))); 

     } 
    } 
}); 
0

非常糟糕编写一个处理程序,以更新GUI。因为AsyncTask已经提供了这样做的功能,所以放弃它。

你应该看看更多的例子。

使用publishProgress()onProgressUpdate()来更新进度条和/或其他gui元素。

如果必须在doInBackground()中执行代码,则不要将代码包装在线程中。