2011-05-02 58 views
0

有人可以解釋實現以下的最佳方式,我認爲這是一個相當簡單的問題,但我想知道最好的方法,因爲它可以通過幾種不同的方式實現。Android - 正確引用和更新小部件和控件

假設我想要一個將TextView的文本更新爲「Test」的類。當然,這不是我真正的問題,但我試圖讓這個問題儘可能簡單。我們也可以說這將接受任何文本視圖。

它調用的類不會繼承Activity。

我看到要做到這一點的方式如下,請解釋爲什麼以及爲什麼不應該或不應該使用這些方法。

傳遞TextView作爲參考並更新文本。

public class Test 

public void updateText(TextView tv) 
{ 
    tv.setText("Test"); 
} 

另一種選擇是通過活動,並呼籲findViewById,但這裏的問題是,如果ID不匹配的是,測試類期望,視圖將返回null,將不會更新的TextView 。

public class Test 

public void updateText(Activity act) 
{ 
    TextView tv = (TextView) act.findViewById(R.id.i_must_exist); 
    tv.setText("Test"); 
} 

另一種選擇是使用getters/setters。

public class Test 

private TextView mTvToUpdate; 

public void setTextView(TextView tv) 
{ 
    mTvToUpdate = tv; 
} 

public void updateText(Activity act) 
{ 
    mTvToUpdate.setText("Test"); 
} 

我想真正的問題是錯誤的傳遞一個對象引用作爲參數,是活動的首選方式?爲什麼?它更可能會遇到內存泄漏,這兩種解決方案都可以嗎?是否優先?

請不要回復「你爲什麼要這麼做?」就像在這個例子中,我顯然不想去做我想問的問題,但背後的問題仍然適用。

在此先感謝。

回答

1

如果沒有很好的理由,我不會用最後的方式去做,因爲當你持有對UI元素的引用時,你可能更容易泄漏內存。當您持有對Widget的引用時,您也持有對該活動的引用,因此如果該活動已被銷燬(可能使用WeakReference),則必須確保不保留對該Widget的引用。這在文章Avoiding Memory Leaks中描述。

除此之外,沒有真正的區別。

+0

因此,活動應該通過嗎?所以當活動被破壞時,所有的引用也是如此? – Ricky 2011-05-02 15:33:06

+0

沒關係。如果您持有對TextView的引用,則持有對該活動的引用。如果你持有一個強大的(而不是弱)引用一個活動(不管是通過它自己還是通過一些小部件),即使Android決定應該銷燬活動,它也會保持在那裏。因此,對Activity的這種引用只會與Test類一起被垃圾收集,只有在Activity沒有被引用的時候纔會發生(希望聽起來不太複雜)。如果您沒有參考「活動」或「小部件」,則無需擔心。 – Malcolm 2011-05-02 15:39:43

+0

好的,謝謝你的幫助。 – Ricky 2011-05-02 15:42:27

1

「擁有」文本字段的對象應該是實際調用setText方法的對象。所以在大多數情況下,這將是活動。在這種情況下,您的Test類似乎應該只提供一種方法,它將以字符串形式返回要顯示的文本。

因此,像

public class MyActivity extends Activity 
    { 
     @Override 
     protected void onCreate(Bundle savedInstanceState) 
     { 
      super.onCreate(savedInstanceState); 
      setContentView(...); 

      Test t = new Test(...); 

      String testText = t.getTestString(); 

      TextView tv = (TextView)findViewById(R.id.TestTextView); 
      tv.setText(testText) 
     } 
    } 

    public class Test 
    { 
     public String getTestString() 
     { 
      return "Test"; // Probably would be more dynamic in your case. 
     } 
    } 

這將抽象的數據從知識到測試類。你所有的活動需要知道的是,別人正在提供一個數據字符串,它可以設置文本本身。

+0

所以你說活動類(MyActivity,在你的例子中)應該始終實現更新控件的代碼? – Ricky 2011-05-02 15:31:15

+0

是的。沒有理由(至少在你有限的例子中和一般情況下)讓更多的參與者知道TextView,而不是一個從xml中抽取它的對象。這就是封裝和抽象的全部內容。 – Josh 2011-05-02 16:15:25