2012-03-13 59 views
0

我有一個BroadcastReceiver作爲單獨的類文件,在後臺監聽來自服務的傳感器動作。我希望它在Occassions上的屏幕上顯示文字。不允許調用我自己的方法(「靜態」之謎)

我想讓BroadcastClass在我的Activity類中調用一個方法,該方法負責顯示字符串。但我的廣播接收器類不能調用它們不是靜態的(?)「不能讓一個靜態引用從類型myActivity非靜態方法showString(字符串)」

方法如果我做的特定方法靜態的,我的Activity類,它沒有找到findViewById,它有效地失去了與它自己的活動的UI的聯繫「無法對類型爲Activity的非靜態方法findViewById(int)進行靜態引用。

在另一個小應用程序中,我有一個BroadcastReceiver作爲Activity類文件內部的類。然後我沒有直接從它訪問UI的問題。然後我將相關視圖聲明爲類文件字段。但我希望更好地構建事物,將UI與廣播接收和分析分開。它變得非常混亂,無法將整個應用程序源代碼放在同一個文件中。

創建活動的實例意味着什麼?我應該在活動本身還是在BroadcastReceiver中執行此操作?我不想要一個以上的UI實例,但我可能需要從幾個不同的類訪問它。

編輯附加: 我從書中嘗試這種單例模式,但myActivity不能實例化,不允許訪問構造函數。輸入onCreate之前發生崩潰:

public class MyStartupActivity extends Activity { 
    private static MyStartupActivity uniqueInstance; 
    private MyStartupActivity() {} 
    public static MyStartupActivity instantiate() { 
     if (uniqueInstance == null) { 
      uniqueInstance = new MyStartupActivity(); 
     } 
     return uniqueInstance; 
    } 

回答

1

您需要一個類的實例將靜態函數調用到靜態函數中。


您不能將Activity本身作爲singelton對象。 Androud必須有權訪問構造函數。更好地實現一個Application,它就像你的應用程序的singelton對象。

你必須將其申報爲您的清單如下:

<manifest package="your.personal.package"> 
... 
    <application android:label="@string/app_name" 
       android:icon="@drawable/icon" 
       android:description="@string/desc" 
       android:name=".MySingeltonClass" 
       android:debuggable="true"> 
    ... 

這爲您的應用程序,你可以簡單地通過調用getApplicationContext()訪問該應用程序實例。

這是一個更大的例子:

((MySingeltonClass)getApplicationContext()).doSomething(); 

請注意,您Application類在這裏被稱爲MySingeltonClass

public class MySingeltonClass extends Application { 
    public void doSomething() { ... } 
} 

在任何你對你的應用程序的活動,你可以通過這個代碼調用函數doSomething()有自己的上下文,以便您可以調用afik每個需要上下文的函數。

+0

是什麼意思創建活動的實例?我應該在活動本身還是在BroadcastReceiver中執行此操作?我不想要一個以上的UI實例,但我可能需要從幾個不同的類訪問它。 – Tombola 2012-03-13 12:47:53

+0

您需要調用新的ClassName()。比你有一個合作的實例。 – rekire 2012-03-13 12:49:26

+0

每當我這樣做時,我不會得到一個新實例嗎?例如我的BroadcastReceiver類工作的Activity的一個實例,以及我的Service類工作的另一個實例。當應用程序與Activity一起啓動時,它是否是第三個實例? – Tombola 2012-03-13 12:57:14

2

你必須添加一個字段爲活動對象在你的廣播接收器類,像這樣:

class MyBroadcastReceiver extends BroadcastReceiver { 
    private final Activity activity; 

    public MyBroadcastReceiver(Activity activity) { 
     this.activity = activity; 
    } 

    public void onReceive(...) { 
     View v = activity.findViewById(ID); 
     // ... 
    } 
} 

初始化像這樣

class MyActivity extends Activity { 
    public void onCreate(...) { 
     MyBroadcastReceiver receiver = new MyBroadcastReceiver(this); 
     // ... 
    } 
} 

編輯:如果你不想每創建一次就可以安裝接收器,您可以(例如)引入一個設置器到MyBroadcastReceiver

class MyBroadcastReceiver extends BroadcastReceiver { 
    private Activity activity; 

    public void setActivity(Activity activity) { 
     this.activity = activity; 
    } 

    public void onReceive(...) { 
     if (activity != null) { 
      View v = activity.findViewById(ID); 
      // ... 
     } else { 
      // we don't have an activity, do whatever you can do without it... 
     } 
     // ... 
    } 
} 

,並用它在活動:

class MyActivity extends Activity { 
    private static MyBroadcastReceiver receiver; 

    public void onCreate(...) { 
     if (receiver == null) { 
      receiver = new MyBroadcastReceiver(); 
      // ... 
     } 
     receiver.setActivity(this); 

     // ... 
    } 
} 
+0

好吧,現在它幾乎是有道理的。但是你似乎安裝了BroadcastReceiver,而不是Activity。每次調用Activity.onCreate時都不會實例化一個新的MyBroadcastReceiver(就像打開手機屏幕一樣)?或者通過每個活動它需要訪問(作爲用戶切換屏幕)? – Tombola 2012-03-13 13:08:32

+0

請參閱我的編輯 - 如果您有多個活動,則必須爲變量'receiver'找到另一個地方 – hjhill 2012-03-13 22:28:34