Android Activity

一 Activity簡介app

Activity是Context的子類ide

Activity是四大組件之一 用來顯示控件和用戶交互 佈局

Activity是一個佈局容器測試

Activity若是5s內沒有響應 就會致使一個異常 ANR(application not response)spa

 

二 新建一個Activitycode

1. 直接或者間接繼承Activityxml

2. AndroidManifest.xml application節點裏面配置activity name屬性必須配置 其他可選對象

 

三 意圖激活新的Activityblog

顯式意圖繼承

用於激活本應用的另外一個Activity

startActivity(new Intent(context, OtherActivity.class));

隱式意圖

多用於激活其它應用的Activity 能夠匹配多個應用

原則: 徹底匹配對方暴露的intent-filter(action category data)

// 系統撥號盤
startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:18627777777")));

  

四 意圖數據的傳遞

基本數據類型

// 傳遞
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("name", "小白");
intent.putExtra("age", 15);
startActivity(intent);
// 取值
Intent intent = getIntent();
String name = intent.getStringExtra("name");
int age = intent.getIntExtra("age", 0);

對象數據類型

必須讓類去實現Parcelable接口或者Serializable接口

推薦使用Parcelable接口 由於消耗資源少 Serializable是Java的序列化接口 在Android裏面比較消耗資源

// 傳遞
Intent intent = new Intent(context, OtherActivity.class);
intent.putExtra("user", new User("小白", 15));
startActivity(intent);
// 取值
Intent intent = getIntent();
User user = intent.getParcelableExtra("user");

 

五 打開一個Activity關閉後返回數據

 

六 Activity生命週期

 

七 Activity被系統回收後臨時數據的存儲

當系統去主動殺死應用程序的時候 是須要對臨時數據進行存儲的

public class MainActivity extends AppCompatActivity {

    /** 第一種恢復方式 **/
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 只有被系統殺死過 savedInstanceState纔有數據
        if (null != savedInstanceState) {
            int page = savedInstanceState.getInt("page");
            Log.i("HUANG", "onCreate page=" + page);
        }
    }

    /** 保存 **/
    @Override
    protected void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        // 當系統去主動殺死應用程序的時候 onPause()以後調用
        outState.putInt("page", 100);
    }
    
    /** 第二種恢復方式 **/
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // 只有被系統殺死過纔會在onStart()以後調用
        int page = savedInstanceState.getInt("page");
        Log.i("HUANG", "onRestoreInstanceState page=" + page);
    }

}

 

八 橫豎屏切換的生命週期與相關方法

豎屏 -> 橫屏

Activity先殺死 再建立

橫豎 -> 豎屏

Activity先殺死 再建立

配置橫豎屏切換Activity不殺死 只作界面的改變

橫豎屏切換的監聽

public class MainActivity extends AppCompatActivity {

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        // 必須配置橫豎屏切換Activity不殺死 切換時纔會調用
        switch (newConfig.orientation) {
            case Configuration.ORIENTATION_LANDSCAPE:
                Log.i("HUANG", "橫屏");
                break;

            case Configuration.ORIENTATION_PORTRAIT:
                Log.i("HUANG", "豎屏");
                break;
        }
    }

}

 我開發中屏幕方向的處理

 

九 任務棧

任務棧: 用來記錄用戶的操做行爲

棧: 先進後出

進棧(壓棧): startActivity()

出棧(彈棧): finish()和用戶按下後退鍵

當啓動一個應用程序 系統就會分配一個任務棧給應用

 

十 啓動模式

singleInstance 單實例

這樣的Activity會單獨存放在一個任務棧裏面 而且這樣的實例只會有一份引用

若是主任務棧裏面已存在一樣的Activity 那麼不會新建Activity 而會複用已存在的Activity 複用Activity就會調用Activity裏面onNewIntent()方法

舉個例子

AActivity -> BActivity -> BActivity  其中BActivity的啓動模式是singleInstance

第二個BActivity會複用第一個BActivity

此時棧的狀況 AActivity BActivity

再舉個例子

AActivity -> BActivity -> BActivity -> CActivity  其中BActivity的啓動模式是singleInstance

第二個BActivity會複用第一個BActivity

此時棧的狀況 BActivity AActivity CActivity  很奇怪是嗎 我也很奇怪 在三部真機上測試都是這個樣子

最後舉個例子

AActivity -> BActivity -> AActivity -> BActivity -> CActivity  其中BActivity的啓動模式是singleInstance

第二個BActivity會複用第一個BActivity

此時棧的狀況 BActivity AActivity AActivity CActivity  這個也很奇怪

singleTask 單任務棧

若是任務棧裏面已存在一樣的Activity 那麼就會銷燬該Activity上面全部的Activity 再複用該Activity 複用Activity就會調用Activity裏面onNewIntent()方法

singleTop 獨佔頂端

若是棧頂已存在一樣的Activity 那麼不會新建Activity 而會複用棧頂的Activity 複用Activity就會調用Activity裏面onNewIntent()方法

若是不在棧頂 會新建Activity

standard 標準(默認)

啓動一個Activity 該Activity的實例引用就會放置在任務棧 每次啓動都會建立一個新的實例

 

十一 intent.setFlags()方法中的參數值含義

Intent.FLAG_ACTIVITY_NO_HISTORY

經過Intent跳轉到Activity 若是這個Intent添加FLAG_ACTIVITY_NO_HISTORY標誌

這樣的Activity會單獨存放在一個任務棧裏面 而且這樣的實例只會有一份引用

若是主任務棧裏面已存在一樣的Activity 那麼就會銷燬掉舊Activity 再新建Activity

舉個例子

AActivity -> BActivity -> BActivity  其中跳轉BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY標誌

第一個BActivity會被銷燬 第二個BActivity是新建的

此時棧的狀況 AActivity BActivity

再舉個例子

AActivity -> BActivity -> BActivity -> CActivity  其中跳轉BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY標誌

第一個BActivity會被銷燬 第二個BActivity是新建的

此時棧的狀況 AActivity CActivity

最後舉個例子

AActivity -> BActivity -> AActivity -> BActivity -> CActivity  其中跳轉BActivity的Intent添加了FLAG_ACTIVITY_NO_HISTORY標誌

第一個BActivity會被銷燬 第二個BActivity是新建的

此時棧的狀況 AActivity AActivity CActivity

Intent.FLAG_ACTIVITY_CLEAR_TOP

經過Intent跳轉到Activity 若是這個Intent添加FLAG_ACTIVITY_CLEAR_TOP標誌

若是任務棧裏面已存在一樣的Activity 那麼就會銷燬掉舊Activity和它上面全部的Activity 再新建Activity

Intent.FLAG_ACTIVITY_SINGLE_TOP

經過Intent跳轉到Activity 若是這個Intent添加FLAG_ACTIVITY_SINGLE_TOP標誌

若是棧頂已存在一樣的Activity 那麼不會新建Activity 而會複用棧頂的Activity 複用Activity就會調用Activity裏面onNewIntent()方法

若是不在棧頂 會新建Activity

Intent.FLAG_ACTIVITY_NEW_TASK

經過Intent跳轉到Activity 若是這個Intent添加FLAG_ACTIVITY_NEW_TASK標誌

通常狀況: 啓動一個Activity 該Activity的實例引用就會放置在任務棧 每次啓動都會建立一個新的實例

特殊狀況: 若是試圖從Activity的外部非正常途徑啓動一個Activity 好比從一個BroadcastReceiver中啓動一個Activity 則Intent必需要添加FLAG_ACTIVITY_NEW_TASK標記 不然報錯

 

十二 onNewIntent()方法調用順序

若是不在棧頂

onNewIntent() -> onStart() -> onResume()

若是已在棧頂

onNewIntent() -> onResume()

 

十三 注意

通常來講 不建議目標Activity的intent.setFlags()的同時該Activity也設置啓動模式

尤爲是Intent.FLAG_ACTIVITY_NO_HISTORY Intent.FLAG_ACTIVITY_CLEAR_TOP Intent.FLAG_ACTIVITY_SINGLE_TOP 和 singleInstance singleTask singleTop 一塊兒混用

會致使任務棧很奇怪 Activity裏面的方法調用也會很奇怪

 

十四 一個變態的方法

public class MainActivity extends AppCompatActivity {

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            // 把當前Activity放置在後臺
            moveTaskToBack(true);
        }
        return true; //告訴系統交由我來處理
    }

}
相關文章
相關標籤/搜索