2011-07-13 48 views
5

我有一個Android應用程序與一些活動。有時會開始錯誤的活動。Android - 錯誤的活動有時開始

通常情況下,一個應用程序子類開始,然後開始活動(StartAct ...機器人:名字= 「android.intent.action.MAIN」,機器人:名字= 「android.intent.category.LAUNCHER」) 做了一些工作,然後啓動InitializeActivity。這做了一些工作,然後觸發我的主要顯示活動(MainAct)。前兩個活動進行一些基本的初始化,包括在MainAct的啓動意向之前設置靜態「isInitialized」標誌。

使用startActivity()使用特定的intent(... activity.class指定)啓動活動,並在startActivity()後調用finish()。

然而,這裏是時有發生,我不知道爲什麼...

總之,應用程序被殺害,並且當按下圖標來啓動它,它直接跳到第三( MainAct)活動。這會導致應用程序檢測錯誤(將IsInitialized標誌是假的),並停止:

  • 啓動應用程序通常與圖標:
  • ... Application子類開始,也激發了一些工作線程
  • ... StartActivity運行,然後觸發InitializeActivity並完成
  • ... InitializeActivity運行,然後將將IsInitialized並開始MainAct並完成
  • ... MainAct開始,運行好
  • ...主頁按鈕被擊中,憤怒的小鳥運行
  • ... MainAct日誌的onPause,然後onStop
  • ...應用程序子類擁有的工作線程繼續定期做東西和日誌。
  • 25分鐘後,整個應用程序突然死亡。這個觀察是基於日誌活動的thhe結束,
  • 時間的推移
  • Home鍵擊
  • 啓動器圖標被按下應用
  • Application子類的onCreate被調用,並返回
  • * MainAct.onCreate被稱爲!(無StartAct,沒有InitializeActivity *

我缺少什麼?

注意:由於這個問題,添加了初始化標誌。它僅在啓動主要活動的代碼中設置,並且僅在主活動中的onCreate中進行檢查。

[每個請求] 清單文件(稍微編輯)。請注意,此處的服務目前尚未使用。

<manifest 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    package="xxx.yyy.zzz" 
    android:versionCode="1" android:versionName="1.0.1"> 
    <application 
    android:icon="@drawable/icon_nondistr" 
    android:label="@string/app_name" 
    android:name=".app.MainApp" 
    android:debuggable="true"> 
    <activity 
     android:label="@string/app_name" 
     android:name=".app.StartAct" android:theme="@android:style/Theme.NoTitleBar"> 
     <intent-filter> 
     <action 
      android:name="android.intent.action.MAIN" /> 
     <category 
      android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <activity 
     android:label="Html" 
     android:name=".app.HtmlDisplayAct"/> 
    <activity 
     android:label="Init" 
     android:configChanges="orientation" 
     android:name=".app.InitializeActivity" android:theme="@android:style/Theme.NoTitleBar"/> 
    <activity 
     android:label="MyPrefs" 
     android:name=".app.PrefsAct" /> 
    <activity 
     android:label="@string/app_name" 
     android:theme="@android:style/Theme.NoTitleBar" 
     android:name=".app.MainAct"> 
    </activity> 
    <service 
     android:name=".app.svcs.DataGetterService" /> 
    </application> 
    <uses-sdk android:minSdkVersion="4"/> 
    <uses-permission 
    android:name="android.permission.INTERNET" /> 
    <uses-permission 
    android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission 
    android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission 
    android:name="com.android.vending.CHECK_LICENSE" /> 
    <uses-feature 
    android:name="android.hardware.location.network" 
    android:required="false" /> 
</manifest> 
+0

你能證明你的清單文件......像接縫的問題在那裏..根據您的要求增加 – Dinash

+0

。 – Mesocyclone

+0

這是一個很舊的帖子,但我很高興你發佈了它,我很高興我找到了它。否則我不會相信我真的體驗了Android使用我的應用程序所做的事情。不幸的是,唯一的答案是相當成問題的 - 我必須將kludgy代碼添加到大約20個Activity類以捕獲所有可能的情況。你有沒有找到更好的解決方案? – RenniePet

回答

2

應用程序因內存不足而死的事實對用戶應該是透明的。這就是爲什麼當應用程序被終止時,Android會記住在這個應用程序中運行的最後一個活動,並在用戶返回應用程序時直接創建這個活動。

也許你可以在你的Application(或你的MainAct)的onCreate()方法中做一些事情,以確保一切都被正確初始化。順便說一句,除非你真的需要,否則當用戶不使用你的應用程序時,你不應該讓工作線程做一些工作。這取決於你做什麼,這可能會快速耗盡電池,或使用戶認爲它可能會快速耗盡電池(這更糟糕,因爲用戶將卸載您的應用程序!)

您也可以使應用程序完成每活動當用戶退出應用程序,

+0

部分功能是在後臺執行定期工作,所以我確實需要工作線程在某處(可能在服務中,但它們不是)。雖然我可以onCreate()確保初始化,但這並不容易(在初始化期間,我有一個不同的活動,所以我可以顯示有關初始化的東西)。我無法在文檔中找到Android執行此操作或者我不會詢問的文檔。你確定嗎?請注意,它對用戶不透明 - 用戶必須再次點擊活動圖標才能重新啓動它。只備份堆棧不會啓動應用程序。韓國社交協會。 – Mesocyclone

+0

如果你把你的工作線程放在一個服務中,你的應用程序可能不會被殺死,你也不會遇到問題。我並不完全確定我所說的是正確的,但是醫生說,如果一個活動暫停或停止,系統可以通過要求完成或者簡單地終止其進程來從內存中刪除該活動。當它再次顯示給用戶時,它必須完全重新啓動並恢復到以前的狀態。[這裏](http://developer.android.com/reference/android/app/Activity.html),不知道是什麼它的意思是。 –

+0

另一個想法是,不知道它是否會起作用,將聲明MainAct是主要活動(其圖標顯示在啓動器中),並使應用程序的onCreate()運行「StartActivity」(您可能需要等待'MainAct'完成初始化)。 –

0

這實際上是一個「添加侮辱傷害」的情況 - 第一個Android殺死我的真棒應用,然後當用戶重新啓動我的應用時,Android嘗試通過啓動「有用」錯誤的活動,導致我的應用程序崩潰。嘆。

這是我非常克魯格的解決方法來抵消Android的幫助。我的應用程序要求StartActivity必須是第一個活動,因此對於所有其他活動,我將一行添加到onCreate()方法。例如:

public class HelpActivity extends AppCompatActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if (StaticMethods.switchToStartActivityIfNecessary(this)) return; // <- this is the magic line 

     ... 

    } 

    ... 

} 

爲了使這項工作我添加了一個開關變量,以我的應用程序類:

public class OutBackClientApplication extends Application { 

    ... 

    // Switch to indicate if StartActivity has been started. 
    // Values: -1 = StartActity has never been started or this is first invocation. 
    //   0 = normal situation, StartActivity has been run at least once. 
    private int _startActivityStatus = -1; 

    public int getStartActivityStatus() { return _startActivityStatus; } 

    public void setStartActivityStatus(int startActivityStatus) { 
     _startActivityStatus = startActivityStatus; 
    } 

    ... 

} 

而且我有一個叫StaticMethods類,它包含以下方法:

public class StaticMethods { 

    /** 
    * Method to test for the problematic situation where Android has previously killed this app, and 
    * then when the user restarts the app Android tries to be helpful by restarting the activity 
    * that was in the foreground when it killed the app, instead of starting the activity specified 
    * in the manifest as the launch activity. See here: 
    * http://stackoverflow.com/questions/6673271/android-wrong-activity-sometimes-starts 
    * 
    * The following line should be added to the onCreate() method of every Activity, except for 
    * StartActivity, of course: 
    * 
    * if (StaticMethods.switchToStartActivityIfNecessary(this)) return; 
    */ 
    public static boolean switchToStartActivityIfNecessary(Activity currentActivity) { 

     OutBackClientApplication outBackClientApplication = 
             (OutBackClientApplication) currentActivity.getApplication(); 

     if (outBackClientApplication.getStartActivityStatus() == -1) { 
     currentActivity.startActivity(new Intent(currentActivity, StartActivity.class)); 
     currentActivity.finish(); 
     return true; 
     } 
     return false; 
    } 

} 

最後,當StartActivity啓動時,需要重置開關:

public class StartActivity extends AppCompatActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     ((OutBackClientApplication) getApplication()).setStartActivityStatus(0); 

     ... 

    } 

    ... 

} 

所有這一切,只是爲了對抗Android的「助人爲樂」 ......