highlight.js

星期日, 7月 29, 2012

Android 程式中的 Activity.this 是甚麼?

在撰寫 Android 程式時, 許多地方都需要傳遞一個 Context 類別的物件, 這時常常會看到傳入的是 XXXActivity.this, 其中 XXXActivity 就是你的 Activity 類別的名稱, 如果對於 Java 不熟悉, 可能會覺得很奇怪, this 我知道, 但是 Activity.this 是甚麼?

其實這主要是因為在 Android 程式中, 大多數的程式可能都是在事件處理時執行, 而大多數的事件處理都是寫在匿名的內部類別 (Inner Class) 中, 也就是說, 當事件處理執行時, 所屬的物件是內部類別所產生的物件, 因此若是只寫 this, 那麼所指的其實是這個內部類別的物件, 但我們需要傳遞的是外部 Activity 類別的物件 (Activity 是 Context 的衍生類別), 這時就必須在 this 前冠上外部類別的名稱, 而這也就是你會看到 XXXActivity.this 的原因。

如果你還是不大了解, 請看以下這段程式:
public class MyOutterClass {
  String name = "Outter Class";
  MyInnerClass inner = null;

 void callout()  {
  System.out.println("(Outter)this.name=" + this.name);
  System.out.println("(Outter)MyOutterClass.this.name=" +
   MyOutterClass.this.name);
 } 

 public MyOutterClass() {
  inner = new MyInnerClass();
 }
 
 public static void main(String[] argv) {
  MyOutterClass outter = new MyOutterClass();
  outter.inner.callme();
 }
 
 class MyInnerClass {
  String name = "Inner Class";
  void callme() {
   System.out.println("(Inner)this.name=" + this.name);
   System.out.println("(Inner)MyOutterClass.this.name=" +
    MyOutterClass.this.name);
   callout();
  } 
 }
}
執行後的結果如下:
(Inner)this.name=Inner Class
(Inner)MyOutterClass.this.name=Outter Class
(Outter)this.name=Outter Class
(Outter)MyOutterClass.this.name=Outter Class
當內部類別的 callme() 執行時, 可以看到 this 與 MyOutterClass.this 指的分別是內部以及外部的物件, 但是當執行到外部類別的 callout() 時, 這兩種寫法指的都是外部的物件。

補充說明:內部類別是指非 static 的巢狀類別 (Nested Class), 所以每個內部類別的物件一定都有一個版隨的外部類別的物件。

沒有留言: