国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

安卓-Activity生命周期

2019-11-08 00:38:16
字體:
供稿:網(wǎng)友

一、簡述

android是使用任務(wù)來管理活動的,一個任務(wù)就是一組存放在棧中的活動的集合。

1.活動有四個狀態(tài):1)運(yùn)行狀態(tài):活動位于返回棧的棧頂2)暫停狀態(tài):活動不處于棧頂位置,但是可見3)停止?fàn)顟B(tài):活動不處于棧頂位置,且完全不可見4)銷毀狀態(tài):當(dāng)一個活動從返回棧中移除

2.活動生存周期Activity中定義了7各回調(diào)方法onCreate():活動第一次創(chuàng)建時調(diào)用,完成初始化操作:加載布局、綁定事件onStart():活動由不可見變?yōu)榭梢姇r調(diào)用onResume():活動準(zhǔn)備好和用戶交互時調(diào)用。處于返回棧的棧頂,并且處于運(yùn)行狀態(tài)onPause():系統(tǒng)準(zhǔn)備去啟動或者恢復(fù)另一個活動時調(diào)用。比如:上面彈出各對話框onStop():活動在完全不可見的時候調(diào)用onDestroy():活動被銷毀之前調(diào)用onRestart():活動由停止?fàn)顟B(tài)變?yōu)檫\(yùn)行狀態(tài)

生命周期又可分為3種生存期完整生存期:onCreate()到onDestroy()之間可見生存期:onStart()到onStop()之間前臺生存期:onResume()和onPause()之間

總結(jié)下狀態(tài)的變化:

一個Activity從創(chuàng)建到顯示經(jīng)歷:onCreate()  onStart() onResume()一個Activity上彈出一個全屏的Activity,經(jīng)歷:onPause  onStop,上面的銷毀,onRestart onStart  onResume一個Activity上彈出一個對話框,下面的Activity經(jīng)歷:onPause  ,此時點(diǎn)擊返回鍵,下面的Activity執(zhí)行onResume,再點(diǎn)擊返回鍵,Activity執(zhí)行onPause  onStop  onDestroy

下面也引用網(wǎng)上的一張圖:

上面這張圖是各個文章中引用最多的,詳細(xì)說明了各個狀態(tài)。

二、測試各種情況

1)測試一個Activity正常啟動時

測試結(jié)果:

02-23 18:55:55.524 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onCreate: 02-23 18:55:55.744 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onStart: 02-23 18:55:55.744 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onResume:

可以看到Activity在啟動的過程中經(jīng)歷了:onCreate->onStart->onResume

2)從后臺切換到前臺

測試結(jié)果:

02-23 19:21:51.954 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onRestart: 02-23 19:21:51.954 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onStart:

02-23 19:21:51.964 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onResume:

02-23 19:21:52.004 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged:

可以看到Activity經(jīng)歷了:onRestart->onStart->onResume->onWindowFocusChanged

3)全屏的Activity跳轉(zhuǎn)且不透明

測試結(jié)果:

02-23 19:38:31.854 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onPause: 02-23 19:38:31.874 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged: 02-23 19:38:31.904 20215-20215/com.mobile.cdtx.blog D/SecondDemoActivity: onCreate: 02-23 19:38:31.994 20215-20215/com.mobile.cdtx.blog D/SecondDemoActivity: onStart: 02-23 19:38:31.994 20215-20215/com.mobile.cdtx.blog D/SecondDemoActivity: onResume: 02-23 19:38:32.084 20215-20215/com.mobile.cdtx.blog D/SecondDemoActivity: onWindowFocusChanged: 02-23 19:38:32.474 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onStop:

其中ActivityLifeActivity是下面的界面,SecondDemoActivity是跳轉(zhuǎn)后的界面

ActivityLifeActivity經(jīng)歷了:onPause->onWindowFocusChanged->onStop

SecondDemoActivity經(jīng)歷了:onCreate->onStart->onResume->onWindowFocusChanged

4)全屏的Activity返回到下面的Activity

測試結(jié)果:

02-23 19:31:59.854 8605-8605/com.mobile.cdtx.blog D/SecondDemoActivity: onPause:02-23 19:31:59.864 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onRestart: 02-23 19:31:59.864 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onStart: 02-23 19:31:59.864 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onResume: 02-23 19:31:59.894 8605-8605/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged: 02-23 19:31:59.964 8605-8605/com.mobile.cdtx.blog D/SecondDemoActivity: onWindowFocusChanged: 02-23 19:32:00.284 8605-8605/com.mobile.cdtx.blog D/SecondDemoActivity: onStop: 02-23 19:32:00.284 8605-8605/com.mobile.cdtx.blog D/SecondDemoActivity: onDestroy:

其中,SecondDemoActivity是上面的界面,ActivityLifeActivity是下面的界面

SecondDemoActivity經(jīng)歷了:onPause->onWindowFocusChanged->onStop->onDestroy

ActivityLifeActivity經(jīng)歷了:onRestart->onStart->onResume->onWindowFocusChanged

5)從前臺切換到后臺

測試結(jié)果:

02-23 19:43:37.854 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onPause: 02-23 19:43:37.874 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged: 02-23 19:43:38.354 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onStop:

ActivityLifeActivity從前臺切換到后臺經(jīng)歷了:onPause->onWindowFocusChanged->onStop

6)Activity上彈出Toast

測試結(jié)果:

未打印任何日志,這說明窗口焦點(diǎn)和Activity未受任何影響

7)Activity上彈出對話框

測試結(jié)果:

02-23 19:49:10.394 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged:

可以看到Activity只經(jīng)歷了:onWindowFocusChanged

8)Activity上彈出的對話框消失

測試結(jié)果:

02-23 19:50:34.684 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged:

可以看到Activity只經(jīng)歷了:onWindowFocusChanged

9)彈出半透明對話框

測試結(jié)果:

02-23 19:52:23.124 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onPause: 02-23 19:52:23.144 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged: 

可以看到ActivityLifeActivity經(jīng)歷了:onPause->onWindowFocusChanged

10)彈出的半透明對話框消失

02-23 19:54:18.944 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onResume: 02-23 19:54:18.964 20215-20215/com.mobile.cdtx.blog D/ActivityLifeActivity: onWindowFocusChanged:

ActivityLifeActivity經(jīng)歷了:onResume->onWindowFocusChanged

11)改變屏幕方向

然后在“Settings->Display”中,將“Auto-rotate Screen”一項選中,表明可以自動根據(jù)方向旋轉(zhuǎn)屏幕,中文設(shè)置中顯示的是:顯示->自動旋轉(zhuǎn)屏幕

測試結(jié)果:

02-23 20:03:12.884 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onPause: 02-23 20:03:12.884 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onStop: 02-23 20:03:12.884 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onDestroy: 02-23 20:03:12.924 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onCreate: 02-23 20:03:13.044 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onStart: 02-23 20:03:13.044 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onRestoreInstanceState: 02-23 20:03:13.044 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onResume: 02-23 20:03:13.124 9747-9747/com.mobile.cdtx.blog D/SecondDemoActivity: onWindowFocusChanged:

可以看到Activity經(jīng)歷了:onPause->onStop->onDestroy->onCreate->onStart->onRestoreInstanceState->onResume->onWindowFocusChanged

其中onRestoreInstanceState用于恢復(fù)保存的數(shù)據(jù)

上面的數(shù)據(jù)說明經(jīng)歷銷毀到重建的過程,怎么樣才可以避免這種情況呢?

1.AndroidManifest.xml中聲明:<uses-permission android:name="android.permission.CHANGE_CONFIGURATION"/>

2.在Activity的注冊中設(shè)置:android:configChanges="orientation|screenSize“屬性

3.在Activity中重寫下面的方法:

@Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)        {            Log.d(TAG, "onConfigurationChanged:橫屏");// 獲取橫屏        } else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)        {// 獲取豎屏            Log.d(TAG, "onConfigurationChanged:豎屏");// 獲取橫屏        }    }測試結(jié)果:

02-23 20:27:29.034 9379-9379/com.mobile.cdtx.blog D/SecondDemoActivity: onConfigurationChanged:橫屏

可以看到Activity并沒有經(jīng)歷銷毀到重建的過程。

有些文章上說android:configChanges="orientation“這個屬性這樣設(shè)置,但是在新高版本的API中不行仍然會經(jīng)歷從銷毀到重建的過程。自從Android 3.2(API 13),screen size也開始跟著設(shè)備的橫豎切換而改變。所以,在AndroidManifest.xml里設(shè)置的MiniSdkVersion和 TargetSdkVersion屬性大于等于13的情況下,如果你想阻止程序在運(yùn)行時重新加載Activity,除了設(shè)置"orientation",還必須設(shè)置"ScreenSize"。

如果不想讓屏幕發(fā)生旋轉(zhuǎn)怎么辦呢?

指定屬性:

android:screenOrientation="portrait"或android:screenOrientation="landscape"

如果<activity>配置了android:screenOrientation屬性,則會使android:configChanges="orientation"失效

測試代碼中也增加了onSaveInstanceState方法的測試,但是發(fā)現(xiàn)Activity即將被銷毀的時候并沒有執(zhí)行這個方法,這是為什么呢?

當(dāng)Activity只執(zhí)行onPause方法時(Activity a打開一個透明Activity b)這時候如果App設(shè)置的targetVersion大于android3.0則不會執(zhí)行onSaveInstanceState方法。

以上測試結(jié)果已經(jīng)可以說明常見的調(diào)用情況了,大家看著測試數(shù)據(jù)多體會多測試。

三、測試代碼AndroidManifest.xml中用到的關(guān)鍵代碼

<uses-permission android:name="android.permission.CALL_PHONE"/><uses-permission android:name="android.permission.CHANGE_CONFIGURATIONS"/>....<activity android:name=".main.activity.ActivityLifeActivity"></activity><!--如果指定了android:screenOrientation="landscape"這個屬性,則屏幕不會發(fā)生旋轉(zhuǎn)--><activity android:name=".main.activity.SecondDemoActivity" android:configChanges="orientation|screenSize" ></activity>主測試界面布局文件activity_life.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:id="@+id/activity_life"    android:layout_width="match_parent"    android:layout_height="match_parent">    <Button        android:id="@+id/id_btn_jump"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="模擬界面跳轉(zhuǎn)"/>    <Button        android:id="@+id/id_btn_toast"        android:textAllCaps="false"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="彈出Toast提示"/>    <Button        android:id="@+id/id_btn_dialog"        android:textAllCaps="false"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="彈出對話框提示"/>    <Button        android:id="@+id/id_btn_home"        android:textAllCaps="false"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="模擬跳到主屏幕界面"/>    <Button        android:id="@+id/id_btn_call"        android:textAllCaps="false"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="模擬打電話"/></LinearLayout>主界面代碼:

import android.Manifest;import android.content.Intent;import android.content.pm.PackageManager;import android.content.res.Configuration;import android.net.Uri;import android.os.Bundle;import android.os.PersistableBundle;import android.support.annotation.NonNull;import android.support.v4.app.ActivityCompat;import android.support.v7.app.AlertDialog;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.Toast;import com.mobile.cdtx.blog.R;//測試Activity的生命周期public class ActivityLifeActivity extends AppCompatActivity implements View.OnClickListener {    PRivate static final String TAG = "ActivityLifeActivity";    private Button btnJump, btnToast, btnDialog, btnHome, btnCall;    Intent intent;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG, "onCreate: ");        setContentView(R.layout.activity_life);        initView();    }    @Override    protected void onStart() {        super.onStart();        Log.d(TAG, "onStart: ");    }    @Override    protected void onResume() {        super.onResume();        Log.d(TAG, "onResume: ");    }    @Override    protected void onPause() {        super.onPause();        Log.d(TAG, "onPause: ");    }    @Override    protected void onStop() {        super.onStop();        Log.d(TAG, "onStop: ");    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroy: ");    }    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG, "onRestart: ");    }    @Override    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {        super.onSaveInstanceState(outState, outPersistentState);        Log.d(TAG, "onSaveInstanceState: ");    }    @Override    protected void onRestoreInstanceState(Bundle savedInstanceState) {        super.onRestoreInstanceState(savedInstanceState);        Log.d(TAG, "onRestoreInstanceState: ");    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        Log.d(TAG, "onWindowFocusChanged: ");    }    //當(dāng)指定了android:configChanges="orientation"后,方向改變時onConfigurationChanged被調(diào)用    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        Log.d(TAG, "onConfigurationChanged:");    }    //控件初始化    private void initView() {        btnJump = (Button) findViewById(R.id.id_btn_jump);        btnJump.setOnClickListener(this);        btnToast = (Button) findViewById(R.id.id_btn_toast);        btnToast.setOnClickListener(this);        btnDialog = (Button) findViewById(R.id.id_btn_dialog);        btnDialog.setOnClickListener(this);        btnHome = (Button) findViewById(R.id.id_btn_home);        btnHome.setOnClickListener(this);        btnCall = (Button) findViewById(R.id.id_btn_call);        btnCall.setOnClickListener(this);    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.id_btn_jump:                startActivity(new Intent(ActivityLifeActivity.this, SecondDemoActivity.class));                break;            case R.id.id_btn_toast:                Toast.makeText(this, "測試Toast", Toast.LENGTH_SHORT).show();                break;            case R.id.id_btn_dialog:                new AlertDialog.Builder(this)                        .setTitle("標(biāo)題")                        .setMessage("簡單消息框")                        .setPositiveButton("確定", null)                        .show();                break;            case R.id.id_btn_home:                Intent MyIntent = new Intent(Intent.ACTION_MAIN);                MyIntent.addCategory(Intent.CATEGORY_HOME);                startActivity(MyIntent);                break;            case R.id.id_btn_call:                intent = new Intent(Intent.ACTION_CALL);                Uri data = Uri.parse("tel:1234567890");                intent.setData(data);                if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {                    ActivityCompat.requestPermissions(ActivityLifeActivity.this, new String[] {Manifest.permission.CALL_PHONE},1);                    return;                }else{                    startActivity(intent);                }                break;            default:                break;        }    }    @Override    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {        if (requestCode == 1) {            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {                intent = new Intent(Intent.ACTION_CALL);                Uri data = Uri.parse("tel:1234567890");                intent.setData(data);                startActivity(intent);            } else {                Toast.makeText(this, "權(quán)限被拒絕", Toast.LENGTH_SHORT).show();            }            return;        }        super.onRequestPermissionsResult(requestCode, permissions, grantResults);    }}運(yùn)行效果圖:

模擬界面跳轉(zhuǎn)的界面的布局文件:

activity_second_demo.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout    xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/activity_second_demo"    android:layout_width="match_parent"    android:layout_height="match_parent"></RelativeLayout>布局很簡單什么控件都沒,主要是在代碼中打印關(guān)鍵方法。

模擬界面跳轉(zhuǎn)的界面的代碼:

import android.content.res.Configuration;import android.os.Bundle;import android.os.PersistableBundle;import android.support.v7.app.AppCompatActivity;import android.util.Log;import com.mobile.cdtx.blog.R;public class SecondDemoActivity extends AppCompatActivity {    private static final String TAG = "SecondDemoActivity";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Log.d(TAG, "onCreate: ");        setContentView(R.layout.activity_second_demo);    }    @Override    protected void onStart() {        super.onStart();        Log.d(TAG, "onStart: ");    }    @Override    protected void onResume() {        super.onResume();        Log.d(TAG, "onResume: ");    }    @Override    protected void onPause() {        super.onPause();        Log.d(TAG, "onPause: ");    }    @Override    protected void onStop() {        super.onStop();        Log.d(TAG, "onStop: ");    }    @Override    protected void onDestroy() {        super.onDestroy();        Log.d(TAG, "onDestroy: ");    }    @Override    protected void onRestart() {        super.onRestart();        Log.d(TAG, "onRestart: ");    }    @Override    public void onSaveInstanceState(Bundle outState, PersistableBundle outPersistentState) {        super.onSaveInstanceState(outState, outPersistentState);        Log.d(TAG, "onSaveInstanceState: ");    }    @Override    protected void onRestoreInstanceState(Bundle savedInstanceState) {        super.onRestoreInstanceState(savedInstanceState);        Log.d(TAG, "onRestoreInstanceState: ");    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);        Log.d(TAG, "onWindowFocusChanged: ");    }    //當(dāng)指定了android:configChanges="orientation"后,方向改變時onConfigurationChanged被調(diào)用    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);        if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)        {            Log.d(TAG, "onConfigurationChanged:橫屏");// 獲取橫屏        } else if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)        {// 獲取豎屏            Log.d(TAG, "onConfigurationChanged:豎屏");// 獲取橫屏        }    }}


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 吴桥县| 巴彦淖尔市| 饶阳县| 长岛县| 威信县| 通河县| 繁昌县| 秦安县| 昌平区| 苗栗县| 德保县| 沁源县| 甘谷县| 云梦县| 新化县| 东平县| 柯坪县| 广水市| 巍山| 渝北区| 宝鸡市| 厦门市| 荔浦县| 长丰县| 喜德县| 尼勒克县| 开鲁县| 新兴县| 庄浪县| 汝南县| 秀山| 张家川| 育儿| 凌云县| 巴青县| 安宁市| 府谷县| 临澧县| 凤庆县| 丰原市| 堆龙德庆县|