2013-10-06 22 views
0

我已经制作了一个应编译TextView的AsyncTask。这是我做过的很短的回顾。我删除了很多行,所以我希望我没有忘记任何东西。无法从AsyncTask内部触摸外部视图...但并不总是如此

public class MyClass extends RelativeLayout { 
     private TextView messageTextView; 


    public MyClass(Context context) { 
     super(context); 
     init(context); } 
    public MyClass(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(context); } 
    public MyClass(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(context); } 


    private void init(Context context) { 
     createLayoutContent(); 
       run(); 
    } 

    private void createLayoutContent (Context context) { 
     this.setLayoutParams(new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MATCH_PARENT, 0)); 

     messageView = new TextView(context); 
     messageView.setText("test"); 
     this.addView(messageView); 
    } 

    private void start() { 
     new AsyncTask<Void, String, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 
       try { 
        String s_message = "test2"; 
        messageView.setText(s_message); **// HERE IS WHERE THE ERROR IS //** 
       } catch (MalformedURLException e) { 
        e.printStackTrace(); 
       } catch (IOException e) { 
        e.printStackTrace(); 
       } catch (JSONException e) { 
        e.printStackTrace(); 
       } 
       return null; 
      } 
     }.execute(); 

    } 

} 

在此之后,我直接把对象的布局:

<<...>MyClass 
     android:id="@+id/test" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
    /> 

现在的问题是,在一些应用这个完美的作品。一旦活动运行,setContentView()创建UI对象,一切都很好。 在其他应用程序,我不断收到一个错误,指出该“只有创建一个视图层次可以触摸其观点原来的线程。

我得到这个错误,但我不明白为什么上一些应用程序工作正常... 更奇怪的是,它发生了一次,我通常给错误的应用程序,突然开始工作,然后在两次正确运行后又回到错误!

这很奇怪。

我知道,也许细节不足以检测到错误,所以请原谅我,但我检查了所有可以考虑的细节,并且找不到它在何时工作和何时不工作之间的显着区别。也许更多专家的眼睛可以检测到某些东西,解释一些东西或者建议我在哪里调试 有人能帮助我吗?

非常感谢。

回答

2

我不确定,为什么它可以工作一些。但它每次都会失败。 如果Android系统决定在UI线程中运行后台线程代码,可能会有效。

下面是修复您的问题的方法: 将“touch views”事物移动到onPostExcution()onProgressUpdate()。 用户界面只能从UI线程中触及。 AsyncTask帮助完成这项工作非常方便。所有AsyncTask's方法,但doInBackground()正在UI线程上运行。

所以,从来没有改变Views直接从doInBackground()

private void start() { 
    new AsyncTask<Void, String, String>() { 
     @Override 
     protected String doInBackground(Void... params) { 
      try { 
       String s_message = "test2"; 
       return s_message; 
      } catch (MalformedURLException e) { 
       e.printStackTrace(); 
      } catch (IOException e) { 
       e.printStackTrace(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      return null; 
     } 

     @Override 
     protected void onPostExecute(String s) { 
      messageView.setText(s); 
     } 
    }.execute(); 
} 
+0

Ooooh !! onPostExecute保存了我的一天!谢谢。 关于为什么它的工作原理...我不知道,但我确定它适用于目前在市场上在线的几个应用程序......只是为了确保我将编辑它们。 –

+0

任何方法,但'doInBackground()'。因为这个方法在后台线程中运行。 – flx

相关问题