2013-05-08 51 views
0

这是我的代码:(一些随机文本完成问题osdifhgsoid hgodfhgo hsdhoigifdshgnvfa oidvojd nobndisfn vbjobsf)。如何从AsynkTask更新TextView?

private class DownloadFilesTask extends AsyncTask<String, Integer, Long> { 
    protected Long doInBackground(String... urls) { 
     try{ 
      Listen(); 
     } 
     catch (Exception x) 
     { 
      textIn.setText("shit! " + x.toString()); 
     } 
     long i = 10; 
     return i; 
    } 
} 

(再次一些随机的文字,完成问题(愚蠢的系统)dpfgojd ipgsdigjsidoignsdog

public void Listen(){ 
    int count = 0; 
    TextView msg = MyActivity.msg; 
    ServerSocket server; 
    Socket client; 
    try { 
     server = new ServerSocket(9797); 
     Log.d("My log", "server started"); 
     Log.d("My log", "waiting for connnections"); 
     while (started) { 
      try{ 
       msg.setText("waiting for connection"); <=== here crashing 
       client = server.accept(); 
       count++; 
       Log.d("My Log", "Connected"); 
       Log.d("My Log", "aha" + count); 
       int i = 0; 
       String data = null; 
       byte[] bytes = new byte[1024]; 
       InputStream is = client.getInputStream(); 
       OutputStream os = client.getOutputStream(); 
       while (is.available() == 0) { 
        try{ 
         Thread.sleep(50); 
        }catch (Exception cc){} 
       } 
       is.read(bytes, 0, is.available()); 
       os.write("hala".getBytes()); 
       client.close(); 
      }catch (Exception cc) 
      { 
       cc.toString(); 
      } 
     } 

    } catch (Exception el) { 
     el.printStackTrace(); 
    } 
} 

(一些随机的文字,完成问题)。请帮助

+0

我不太确定为什么你的AsyncTask预计一个Long作为返回值,如果你不打算使用它。更好的方法是将Void作为返回值。我会更新我自己的答案。 – britzl 2013-05-08 12:15:04

回答

3

通过onPostExecute方法改变它!

+0

我在DownloadFilesTask里面添加了onPostExecute扩展AsyncTask并且粘贴了msg.setText(action),这不起作用。 如何调用此方法? – Halabella 2013-05-08 12:47:34

-1

我猜runOnUiThread。你不能从UI线程以外的任何其他线程更新UI。

+0

AsyncTask的目的是不必担心runOnUiThread之类的问题。覆盖onPostExecute()并在那里更新。 – britzl 2013-05-08 12:00:49

+0

啊,那里好点,我还是个初学者,所以我不知道'AsyncTask'可以这样使用。感谢您指出它;) – 2013-05-08 12:07:52

0

是的,因为您试图在doInBackground()方法内设置TextView,并且这是不允许的。

因此,如果您想在doInBackground()方法内设置TextView,请在runOnUiThread方法内执行UI更新操作。

否则,建议您在onPostExecute()方法内执行所有与UI显示/更新相关的操作,而不是您的AsyncTask类的doInBackground()方法。

+0

但它使用互联网!它如何在UI线程中运行? – Halabella 2013-05-08 12:54:47

0

好主意会返回一个字符串在doInBackground(),说exceptionCatched。您可以将它设置为Exception标题catch()块,然后在onPostExecuted()只需检查if(!TextUtils.isEmpty(exceptionCatched)) textIn.setText(exceptionCatched);就是这样!

+0

更好的方法是将异常保存在成员变量中(因为他是继承AsyncTask)并在onPostExecute()方法中检索它 – britzl 2013-05-08 12:10:27

+0

不确定它是好还是坏,但它也是一种好方法;) – lomza 2013-05-08 12:15:48

1

AsyncTask的目的是在单独的线程中执行长时间运行的任务,然后通过onPostExecute()将结果传回给UI线程。

另外,我不确定为什么你使用Long作为你的返回值,因为你似乎没有使用它。一个更好的解决办法是有空隙的返回值,并保存异常,并使用它作为一个指标,如果出了什么差错:

private class DownloadFilesTask extends AsyncTask<String, Integer, Void> { 

    private Exception exception = null; 

    @Override 
    protected Void doInBackground(String... urls) { 
     try{ 
      Listen(); 
     } 
     catch (Exception x) { 
      exception = x; 
     } 
    } 

    @Override 
    public void onPostExecute(Void result) { 
     if(exception != null) { 
      textIn.setText("shit! " + exception.toString()); 
     } 
     else { 
      // long running task was completed successfully 
     } 
    } 
} 
+0

OnPost ..不能@Overriden,并且在我的测试过程中未调用此方法.. – Halabella 2013-05-08 12:52:14

+0

对不起,但你错了。看看这个文档:http://developer.android.com/reference/android/os/AsyncTask。html – britzl 2013-05-08 17:54:35

0
private class DownloadFilesTask extends AsyncTask<Void, Void,Long>{ 

    @Override 
    protected Long doInBackground(Void... params) { 
     publishProgress(progress); 
     //calculate progress and value from your downloading logic 
    try { 

     } catch (Exception e) { 
      return (long) 0; 
     } 
     return null; 
    } 
    @Override 
    protected void onProgressUpdate(Void... values) { 
     super.onProgressUpdate(values); 
     //dis method run deafult on UI thread , so every time u publish ur onProgressUpdate will be called and update ur text here 
    } 


    @Override 
    protected void onPostExecute(Long result) { 
     super.onPostExecute(result); 
     if(result==0){ 
      //error occured 
     } 
    } 

//异常的情况下返回结果,只要值promt onPostExceute()

+0

为什么要使用0作为错误的指示符,并使用null作为任务成功的指示符? – britzl 2013-05-08 12:08:54

+0

这只是为了您的使用,我只是简单地为他的问题 – 2013-05-08 12:12:06

+0

提供了正确的实现,如果不出现任何异常并且用户希望看到进度可能在textview中,那么他必须发布它。 – 2013-05-08 12:13:36