天天看點

Activity#finish() 對其生命周期的影響無 Fragment 的情況含有一個 Fragment應用案例注意

  • 無 Fragment 的情況
    • 未調用 finish 方法
    • 調用 finish 方法
  • 含有一個 Fragment
    • 未調用 finish 方法
    • 調用 Activity#finish() 方法
  • 應用案例
  • 注意

如果在 Activity#onCreate() 方法中調用 finish() 方法,其生命周期會發生什麼變化?

實驗環境:

  • compilesdksion=25.0.3;
  • com.android.support:appcompat-v7:25.3.1

無 Fragment 的情況

未調用 finish 方法

正常情況下 Activity 的生命周期:

Activity.onCreate -> Activity.onStart -> Activity.onPostCreate -> Activity.onResume -> Activity.onPostResume;

将 Activity 置于背景後再傳回到前台:

Activity.onPause -> Activity.onStop -> Activity.onRestart -> Activity.onStart -> Activity.onResume -> Activity.onPostResume。

調用 finish 方法

在 Activity#onCreate() 中調用 finish() 方法,生命周期如下:

Activity.onCreate -> Activity.onDestroy。

如果未重寫 finish() 方法,從 finish() 方法傳回後繼續執行 onCreate() 中剩餘的代碼。

含有一個 Fragment

添加 Fragment 的方法:

if (savedInstanceState != null) {
            FragmentManager fm = getSupportFragmentManager();
            myFragment = (MyFragment) fm.findFragmentByTag(MyFragment.TAG);
        }

        if (myFragment == null) {
            MyFragment = new MyFragment();
            FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
            ft.add(android.R.id.content, myFragment, MyFragment.TAG);
            ft.commit();
        }
  }
           

未調用 finish 方法

Activity.onCreate -> Fragment.onAttach -> Fragment.onCreate -> Fragment.onCreateView -> Fragment.onViewCreated -> Fragment.onActivityCreated -> Fragment.onStart -> Activity.onStart -> Activity.onPostCreate -> Activity.onResume -> Fragment.onResume -> Activity.onPostResume;

息屏後又點亮:

Fragment.onPause -> Activity.onPause -> Fragment.onStop -> Activity.onStop -> Activity.onRestart -> Fragment.onStart -> Activity.onStart -> Activity.onResume -> Fragment.onResume -> Activity.onPostResume;

關閉頁面:

Fragment.onPause -> Activity.onPause -> Fragment.onStop -> Activity.onStop -> Fragment.onDestroyView -> Fragment.onDestroy -> Fragment.onDetach -> Activity.onDestroy。

調用 Activity#finish() 方法

在 Activity#onCreate() 方法中調用 finish() 方法。

Activity.onCreate -> Fragment.onAttach -> Fragment.onCreate -> Fragment.onDestroy -> Fragment.onDetach -> Activity.onDestroy。

應用案例

如果 Activity#onCreate() 方法中有調用 finish() 方法情況,則要保持某些成員變量的健壯性,預防出現空指針等異常。比如:

public class MainActivity extends AppCompatActivity {
    private List<String> mData;

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

                mData = getIntent().getStringArrayListExtra("data");

        if (mData == null) {
            finish();
        }

        // more code
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();

        mData.clear();
    }
}
           

上述代碼片段的邏輯是:如果上個頁面傳過來的資料為空,則關閉頁面。

問題在于,如果執行 finish() 方法,則會緊接着執行 Activity#onDestroy() ,則會出現空指針異常。如果該 Activity 中含有 Fragment,更要注意 Fragment#onDestroy() 方法中是否有可能發生空指針異常。

注意

使用 24 和 25 的 support 包,在Activity#onCreate() 中調用 Activity#finish() 後的表現不同,具體見下圖:

Activity#finish() 對其生命周期的影響無 Fragment 的情況含有一個 Fragment應用案例注意