關於android初學者必須掌握的Activity的四大知識點


 

  這幾天一直都在搗鼓android的知識點,興趣班的老師,講課太過深奧,天(想到什么就見什么,后后面完全不想聽),最后自己找資料總結了在Android學習中很重要的一個組件Activity,那就開始吧!

第一:掌握Activity的四種狀態及什么時候觸發

  首先我們要知道什么是Activity,簡單來說Activity其實就是一個屏幕的顯示頁面。(簡單的闡述)

我們知道Activity是由Activity棧進管理,當來到一個新的Activity后,此Activity將被加入到Activity棧頂,之前的Activity位於此Activity底部。

Acitivity一般意義上有四種狀態:

  1、Running狀態: 一個新的Activity啟動入棧后,它在屏幕的最前端,處於棧的最頂端,此時它處於可見並可和用戶交互的激活狀態,Android試圖盡最大可能保持它活動狀態,殺死其它Activity來確保當前活動Activity有足夠的資源可使用。當另外一個Activity被激活,這個將會被暫停。

  2、Paused狀態:當Activity處於此狀態時,此時它依然與窗口管理器保持連接,系統繼續維護其內部狀態,它仍然可見,但它已經失去了焦點,故不可與用戶交互。

  3、Stopped狀態: 當Activity 不可見時,Activity處於Stopped狀態。當Activity處於此狀態時,一定要保存當前數據和當前的UI狀態,否則一旦Activity退出或關閉時,當前的數據和UI狀態就丟失了

  4、Killed狀態: Activity被殺掉以后或者被啟動以前,處於Killed狀態。這是Activity已從Activity堆棧中移除,需要重新啟動才可以顯示和使用。

                                                

                                 圖1

  對四種狀態的一個總結:Running狀態和Paused狀態是可見的,Stopped狀態和Killed狀態時不可見的,當然Starting是有系統自身自動創建,而且每一個活動( Activity )都處於某一個狀態,對於開發者來說,是無法控制其應用程序處於某一個狀態的,這些均由系統來完成。 

但是當一個活動的狀態發生改變的時候,開發者可以通過調用 onXX() 的方法獲取到相關的通知信息。

接下來講下各種狀態在何時觸發:

  1、Running狀態: 

    期間觸發的函數及順序為: onCreate() ->on Start() -> onResume()。 

  注意:

            1.1:onCreate()只有在該Activity是第一次被創建時才會被調用,主要是負責Activity的一般性的初始化設置,包括視圖的創建,數據的綁定等等。

            需要注意的是若之前有凍結的state(即系統對該Activity調用過onSaveInstanceState()函數),則可以通過其 Bundle 參數進行state恢復。

     1.2:on Start()是當Activity正在變為可見狀態時才會被調用。一般地在此期間可以注冊一個廣播等等。 

     1.3:onResume()是在該Activity將要和用戶進行交互時被調用,此時Activity位於的活動棧頂部。

   2、Paused狀態:

     運行狀態到暫停狀態所觸發的函數及順序為:onResume() -> onPuased()

       暫停狀態恢復至運行狀態所觸發的函數及順序為:onPuased() -> onResume()。     

   注意: 
    2.1:onPuased()是當一個Activity失去系統焦點后將會被調用,包括見面被部分遮擋,以及設備轉入休眠狀態等等。一般地在此期間對一些未保存的數據進行持久化並停 止其他需要耗費CPU的操作,同時不可進行耗時操作,否則會阻塞系統UI線程。

    2.2:一個處於暫停狀態的Activity只有在系統極度缺乏內存資源的情況下才會被系統強制結束。

   3stopped狀態:

      暫停狀態到停止狀態所觸發的函數及順序為:onPuased() -> on Stop()。 
         停止狀態恢復至運行狀態所觸發的函數及順序為:on Stop() -> onRestart() -> on Start() -> onResume()。 

    注意: 
    3.1:on Stop()是當一個Activity變為不可見時將會被調用,此時可能是由於該Activity要被注銷或新的Activity完全遮擋了該Activity。在此期間一般可以進行取消注冊 廣播等操作,因此用戶不可見。 
    3.2:onRestart()是當一個Activity從停止狀態恢復至運行狀態時將會被優先調用。

    4、Killed狀態:

      停止狀態到死亡狀態分為兩種情況:(1)由用戶操作導致,則執行:on Stop() -> onDestroy()。

                      (2)由系統自動強制執行,則該Activity被強行結束。 

    注意: 
    4.1:onDestroy()是當一個Activity正在被系統finished期間被調用的。

以上就是關於 Activity的四種狀態以及何時觸發的詳細分解,當然 如果有何不對或者疑問可以留言或者發Email 214392652@qq.com 感謝!

 第二:掌握Activity的生命周期及各個階段觸發的事件名稱和觸發次數

  Activity一共有七個生命周期函數,分別為onCreate(),onRestart(),on Start(),onReusme(),onPause(),on Stop(),onDestory()。

  1:onCreate() 

    當Acitivity第一次被創建時觸發,一般在這里要做的事情包括創建視圖(setContentView())、向視圖填充必要的數據等等。

  2:onRestart() 

    如果Activity之前被stop過,那么下一次onStart()方法之前會先觸發這個方法,當處於停止狀態的活動需要再次展現給用戶的時候,觸發該方法。

  3:onStart() 

    只要Activity從不可見變成可見,就會觸發到這個方法,但被AlertDialog遮擋/顯示的情況不算在內。

      4:onResume()

    當Activity來到最上層的時候,也就是開始與用戶直接交互時,觸發這個方法。例如本來Activity被一個AlertDialog遮擋,當這個AlertDialog消失時,onResume()方法就被觸發。

  5:onPause() 

    同onResume()的觸發條件剛好相反,如果Activity本來在最上層,當它要讓出最上層的位置時會觸發這個方法。

     onPause()和onResume()是被觸發最頻繁的兩個方法,所以在這里不應該執行過於消耗資源的方法。

 6: onStop ()

      當一個活動不再需要展示給用戶的時候,觸發該方法。如果內存緊張,系統會直接結束這個活動,而不會觸發 onStop 方法。

    所以保存狀態信息是應該在onPause時做,而不是onStop時做。活動如果沒有在前台運行,都將被停止或者Linux管理進程為了給新的活動預留足夠的存儲空間而隨時結束這些活動。因此對於開發者來說,在設計應用程序的時候,必須時刻牢記這一原則。在一些情況下,onPause方法或許是活動觸發的最后的方法,因此開發者需要在這個時候保存需要保存的信息。

 7: onDestroy ()

     當活動銷毀的時候,觸發該方法。和onStop 方法一樣,如果內存緊張,系統會直接結束這個活動而不會觸發該方法。

  接下來我們用代碼來實現具體的方法觸發: 

    創建一個android項目,在MainActivity中進行編輯    

public class MainActivity extends Activity {
    
    // onCreate系統自動初始化
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("--MainActivity--","--------onCreate- 系統自動初始化---------");
    }
    
    //從stop轉為激活狀態時執行
    @Override
    protected void onRestart() {
        super.onRestart();
        Log.i("--MainActivity--", "------onRestart--stop轉為激活狀態時執行----");
    }
        
    //Activity開始加載事件時執行(新創建時,或者重新啟動的時候執行!)
    @Override
    protected void onStart() {
        super.onStart();
        Log.i("--MainActivity--", "--------onStart---開始加載事件時執行-----");
    }
    
    //Activity恢復到激活狀態時執行(任何一次進入激活狀態都將執行)
    @Override
    protected void onResume() {
        super.onResume();
        Log.i("--MainActivity--", "----------onResume-恢復到激活狀態時執行-------------");
    }
    
    //Activity 被覆蓋的時候執行
    @Override
    protected void onStop() {
        super.onStop();
        Log.i("--MainActivity--", "-------onStop ----被覆蓋的時候執行-----------");
    }
    
    //Activity 退出或者被回收時執行,僅執行一次
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i("--MainActivity--","---------onDestroy---退出或者被回收時執行,僅執行一次--------------");
    }

}

當我們啟動部署程序的時候,通過LogCat 日志來查看信息

    以上就是關於掌握Activity的生命周期及各個階段觸發的事件名稱和觸發次數

 第三:掌握Activity中如何在各個窗體之間傳值

    如上我們知道了Activity是一個窗體的頁面顯示,既然是頁面顯示,那么我們就需要進行顯示數據與讀取數據,那么問題來了,Activity中如何在各個窗體之間進行傳值。

這里引入一個關鍵字: Intent:在Android中,Intent對象負責各個Activity窗口之間的切換,同時他更擔負起數據傳輸重任。  

   接下來我們用代碼來具體實現分析(采用工具Eclipse):

  第一:首先我們創建一個名為ActivityValue 的Android項目 並在src 目錄下分別創建名為:SecondActivity JAVA普通類 ,Second_OneActivity JAVA普通類 分別繼承Activity

   

在目錄layout 中創建分別跟SecondActivity ,Second_OneActivity  相對應的布局xml文件

名為:activity_second_one.xml

 名為:activity_second.xml

接下來我們在SecondActivity.java 文件中進行編輯:

package com.example.activityvalue;

import java.util.ArrayList;

import com.example.activitylife.R;
import com.example.activityvalue.Second_OneActivity;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class SecondActivity extends Activity{

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //聲明Activity
        setContentView(R.layout.activity_second);
    }
    
    //傳遞一個普通值到一個窗體
    public void MytestOne(View view){
        System.out.println("=================傳遞一個普通值到一個窗體=====================");
        Intent intent = new Intent(this,Second_OneActivity.class);
        //窗體傳值
        intent.putExtra("stuName","習大大");
        intent.putExtra("stuage",20);
        intent.putExtra("isMerry",false);
        //設置數組
        intent.putExtra("stuHobby",new String[]{"籃球","羽毛球","足球"});
        //設置集合數值
        ArrayList<String> list = new ArrayList<String>();
        list.add("北京");
        list.add("廣東");
        list.add("美國");
        //設置數值到Intent 中
        intent.putStringArrayListExtra("stuCitys",list);
        //開啟Activity
        startActivity(intent);
    }
    
}

我們先在SecondActivity 文件中部署好我們需要取出的數據 不同的類型數據m,由上文可知我們是通過intent 來進行傳值

在Second_OneActivity 進行編輯:

 1 package com.example.activiyvalue;
 2 
 3 import java.lang.reflect.Array;
 4 import java.util.ArrayList;
 5 import java.util.Arrays;
 6 
 7 import android.app.Activity;
 8 import android.content.Intent;
 9 import android.os.Bundle;
10 import android.widget.TextView;
11 
12 public class Second_OneActivity extends Activity{
13     
14     private TextView showText;
15 
16     @Override
17     protected void onCreate(Bundle savedInstanceState) {
18         super.onCreate(savedInstanceState);
19         
20         //聲明一個布局文件
21         setContentView(R.layout.activity_second_one);
22         
23         //從Intent 中取出傳遞過來的數據
24         Intent intent = getIntent();
25         
26         //取出普通數據
27         String name = intent.getStringExtra("stuName");
28         int age = intent.getIntExtra("stuAge", 0);
29         boolean isMerry = intent.getBooleanExtra("isMerry",false);
30         
31         //取出數組數據
32         String[] hobbys = intent.getStringArrayExtra("stuHobby");
33         String hobby = Arrays.toString(hobbys);
34         
35         //取出ArrayList 集合數據
36         ArrayList<String> citys =intent.getStringArrayListExtra("stuCitys");
37         String city = Arrays.toString(citys.toArray());
38         
39         //聲明Activity
40         showText = (TextView) findViewById(R.id.showText);
41         
42         //在Activity 中動態添加文本內容
43         String str = "姓名:"+name+",年齡:"+age+"\n"+
44                      "婚否:"+isMerry+"\n"+
45                      "愛好:"+hobby+"\n"+
46                      "城市:"+city;
47         showText.setText(str);
48 49     
50     
51 }

如果在第21 行 聲明一個布局文件 報錯時,則說明R 文件中 沒有自動生成句柄  我們可以這樣做

在項目右擊重新加載項目便可:

  

接下來我們要在項目目錄下的AndroidMainifest.xml 中進行聲明Activity 類文件

在聲明的前提我們先進行設置好string參數

接下來在AndroidMainifest.xml 開始聲明

接下來要回到MainActivity.java 定義一個方法 用來轉跳Activity

1     //============================打開一個窗體傳值的案例==============================
2     public void setValuesMyDemo(View view){
3         Intent intent = new Intent(this,SecondActivity.class);  //創建一個Activity對象
4         //開始激活Activity狀態為start
5         startActivity(intent);
6     }

在activity_main.xml 布局文件中定義一個Button 按鈕

1 <Button
2 android:id="@+id/button1"
3 android:layout_width="match_parent"
4 android:layout_height="wrap_content"
5 android:text="Activity窗體傳值案例"
6 android:onClick="setValuesMyDemo" />

按鈕綁定一個方法對應的是MainActivity.java 中的 setValuesMyDemo 方法 

setValuesMyDemo 方法中調用 下一個Activity  也就是SecondActivity.java 對應的布局文件

那么我們就要在SecondActivity.java 對應的布局文件activity_second.xml 中添加一個button

<Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="通過Intent傳遞普通數據" 
        android:onClick="MytestOne"/>

activity_second.xml 中點擊事件綁定的方法是SecondActivity.java 文件中對應的MytestOne方法:

在MytestOne方法中 調用了下一個Activity 也就是Second_OneActivity.java   我們在這個文件中進行讀取數據 在SecondActivity.java文件中進行設置數值

接下來見證奇跡的時刻:我們運行我們的程序,打開我們的模擬器或者真機部署文件

點擊窗體中的button 進入SecondActivity的布局文件了  (此時就進行了頁面的跳轉)

 

在SecondActivity頁面我們是進行了設置數值 因此 當再次點擊的時候我們在Second_OneActivity 的布局文件就要進行讀取數據

點擊 顯示跳轉如下: 

  

總結: 由上圖案例可知,Activity與Activity 之間的跳轉 跟 Activity與Activity 之間的傳值  是通過上一個Activity對下一個Activity的調用,其中intent 對象 起到的方法很重要,起着跳轉跟傳值的任務!

 第三: 掌握Activity窗體狀態保存問題

在這里如何保存當前的窗體狀態我們通過代碼來實現: 

  在我們上面的案例基礎上,到MainActivity.java 文件中 重寫Activity 的兩個方法:

onRestoreInstanceState(Bundle savedInstanceState)
    //========================窗體狀態保存與恢復====================================
        @Override
        protected void onRestoreInstanceState(Bundle savedInstanceState) {
            super.onRestoreInstanceState(savedInstanceState);
            //恢復狀態
            if(savedInstanceState!=null){
                String msg = savedInstanceState.getString("message");
                //設置這個數據到需要的地方
                Toast.makeText(this, "以前的消息:"+msg, 50000).show();
            }
        }

onSaveInstanceState(Bundle outState)

//========================保存的狀態====================================
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            // TODO Auto-generated method stub
            super.onSaveInstanceState(outState);
            //保存數據
            outState.putString("message", "Hello!");
            Toast.makeText(this, "狀態已經保存!", 3000).show();
        }

完畢之后,我們開始運行程序最終結果如下:

  

 

 

 總結:  以上是通過其他教師的一個資料與案例自己總結出來的四大知識點,對於android 入門級選手比如我,就可以拿來嘗試,很有成就感的,當然 以上的操作過程有何問題或者歡迎大神前來光顧,希望不斷的進步吧。加油。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM