2011-07-21 103 views
10

我已經寫了一些Android應用,並一直宣稱起始Activity爲:Android應用程序VS活動

<intent-filter> 
    <action android:name="android.intent.action.MAIN" /> 
<category android:name="android.intent.category.LAUNCHER" /> 
</intent-filter> 

這將是偉大的作用域一些全局方法,靜態,共享的首選項,等等,如果我可以使用Application啓動我的應用程序,然後在設置首選項等後調用onCreate()中的第一個Activity,但我一直無法找到此設計模式的任何示例......當我在代碼中嘗試此操作時, a ClassCastException

public class MyApplication extends Application { 
@Override 
    public void onCreate() { 
     super.onCreate(); 

     // do stuff (prefs, etc) 

     // start the initial Activity 
     Intent i = new Intent(this, InitialActivity.class); 
    startActivity(i); 
    } 
} 

InitialActivity.class確實是一個Activity,如果我將它設置爲MAIN,但是嘗試從MyApplication開始,它會聲明MAIN生成錯誤,該工作正常。可能是一個非常愚蠢的問題,但我解決這一切都是錯誤的?

感謝,

保羅

+3

你的意思是你將MyApplication定義爲Activity?這確實會導致ClassCastException。 令人高興的是,如果我正確理解你想要做什麼,Android已經爲你做了你想做的事情。您只需將您的應用程序的名稱設置爲該MyApplication的路徑和名稱即可。它將在您的活動開始之前創建,並將供所有人使用。像這樣:

+0

有趣 - 我將如何從其中一個活動訪問應用程序的自定義方法? –

+1

從你的Activity中你可以得到一個對應用程序的句柄:getApplicationContext(),如果它在你的清單中被配置成如上所示的結果,將會轉換爲MyApplication。 –

回答

19

您可以通過使用FLAG_ACTIVITY_NEW_TASK標誌解決這個問題:

Intent intent = new Intent(this, ApplicationActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent); 

那是因爲你需要開始時活動開始活動內容以外的新任務。但我強烈建議不要從您的應用程序的onCreate()開始Activity。


Android有4個組件:Activity,Service,ContentProvider和Broadcast。

當Android需要從您的應用程序激活這些組件之一時,它會查看您的應用程序是否已存在正在運行的進程。如果沒有,那麼Android會啓動新進程,初始化它,然後初始化您的自定義應用程序實例。然後激活所需組件之一。

現在,讓我們考慮下一個場景:您的應用程序在AndroidManifest.xml中聲明瞭內容提供者,而Android正要啓動您的應用程序,以便您可以將某些數據提供給另一個前臺應用程序。

  1. 內容提供商請求被髮送
  2. 您的應用程序沒有運行,而Android爲它開始新的進程。
  3. 您的自定義應用程序實例已創建
  4. Application.onCreate()被調用。
  5. 你開始一個活動
  6. 你的內容提供商接收請求

有人只是想連接到您的內容提供商,但你的應用程序啓動的活動來代替。同樣適用於啓動後臺服務和有時廣播接收器。

而且還要考慮一些其他應用程序的活動A是否想從應用程序中啓動活動X.但是在onCreate()中,您開始了活動Y,然後X也由Android啓動。然後用戶按下。應該發生什麼?它的棘手...

ApplicationonCreate開始活動可能會導致相當奇怪的用戶體驗。所以不要這樣做。


UPDATE: 由於Android保證創建應用程序只有一次,任何其他組件之前,你可以用下面的代碼來訪問你的應用程序的單一實例:

public class MyApplication extends Application 
{ 
    private static MyApplication s_instance; 

    public MyApplication() 
    { 
     s_instance = this; 
    } 

    public static MyApplication getApplication() 
    { 
     return s_instance; 
    } 
} 
+0

非常好,謝謝。因此,在MyApplication中聲明自定義方法的方面,我可以將其暴露給「Activity」的其餘部分,這可能嗎?我將如何訪問它們('getApplication()'似乎沒有辦法) –

+0

我已經更新了答案。 – inazaruk

+0

因此,我想在MyApplication中訪問的任何方法都可以通過MyApplication.getApplication()。myMethod()來訪問? –

0

你設置它在你爲這個意圖明顯的活動代碼你開始(除了你的主要另一個)?

</activity> 
      <activity android:name=".InitialActivity"       
        android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="com.package.INITACT" /> <--- this is only name by which you activity can be called. 
       <category android:name="android.intent.category.DEFAULT" /> 
      </intent-filter> 
     </activity>