2013-10-06 20 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

相關問題