Activity詳細總結

一、Activity的生命周期

Activity的生命周期.png

二、Activity之間傳遞數據

1. 通過Intent傳遞數據

通過Intent.putExtra方法可以將簡單數據類型或可序列化對象保存在Intent對象中,然后在另一個Activity中使用getInt、getString等方法獲得這些數據。示例代碼如下:

Intent intent =new Intent(CurrentActivity.this,OtherActivity.class);
  // 創建一個帶“收件人地址”的 email 
 Bundle bundle =new Bundle();// 創建 email 內容
 bundle.putBoolean("boolean_key", true);// 編寫內容
 bundle.putString("string_key", "string_value"); 
 intent.putExtra("key", bundle);// 封裝 email 
 startActivity(intent);// 啟動新的 Activity

下面是獲取數據:

 Intent intent =getIntent();// 收取 email 
 Bundle bundle =intent.getBundleExtra("key");// 打開 email 
 bundle.getBoolean("boolean_key");// 讀取內容
 bundle.getString("string_key");

不過使用Bundle傳遞數據稍顯麻煩,如果你只需要傳遞一種類型的值可以這樣:

Intent intent =new Intent(EX06.this,OtherActivity.class); 
 intent.putExtra("boolean_key", true); 
 intent.putExtra("string_key", "string_value"); 
 startActivity(intent);

獲取數據:

Intent intent=getIntent(); 
 intent.getBooleanExtra("boolean_key",false); 
 intent.getStringExtra("string_key");

2. 通過靜態變量傳遞數據

適用于不可序列化的且簡單的對象,不過不推薦使用靜態代碼塊

public class MainActivity extends Activity {  
    private Button btn;  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main);  
        btn = (Button)findViewById(R.id.btOpenOtherActivity);  
        btn.setOnClickListener(new OnClickListener() {  
            @Override  
            public void onClick(View v) {  
                //定義一個意圖  
                Intent intent = new Intent(MainActivity.this,OtherActivity.class);  
                //改變OtherActivity的三個靜態變量的值  
                OtherActivity.name = "wulianghuan";  
                OtherActivity.age = "22";  
                OtherActivity.address = "上海閔行";  
                startActivity(intent);  
            }  
        });  
    }  
}  
public class OtherActivity extends Activity {  
    public static String name;  
    public static String age;  
    public static String address;  
    private TextView text_name;  
    private TextView text_age;  
    private TextView text_address;  
  
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.other);  
        text_name = (TextView) findViewById(R.id.name);  
        text_age = (TextView) findViewById(R.id.age);  
        text_address = (TextView) findViewById(R.id.address);     
        //設置文本框的數據  
        text_name.setText("姓名:"+name);  
        text_age.setText("年齡:"+age);  
        text_address.setText("地址:"+address);  
    }  
}  

3.通過全局對象傳遞數據

如果想使某些數據長時間駐留內存,以便程序隨時調用,建議采用全局對象。Application全局類不需要定義靜態變量只要定義普通成員變量即可,但全局類中必須有一個無參構造方法,編寫完Application類后,還需要在<application>標簽中制定全局類名,否則系統不會自動創建全局對象

public class MainApplication extends Application {
   private String username;

   public String getUsername() {
       return username;
   }

   public void setUsername(String username) {
       this.username = username;
   }
}
public class MainActivity extends Activity {

   private MainApplication application;

   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       application = (MainApplication) getApplication();
       application.setUsername("sunzn");
   }

   public void open(View view) {
       Intent intent = new Intent(this, OtherActivity.class);
       startActivity(intent);
   }
}
public class OtherActivity extends Activity {
   private TextView tv_data;
   private MainApplication application;
   private String username;

   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_other);
       application = (MainApplication) getApplication();
       username = application.getUsername();
       tv_data = (TextView) findViewById(R.id.tv_data);
       tv_data.setText("從上一個 Activity 中獲取到的數據為:" + username);
   }
}

三、從Activity返回數據

要從Activity返回數據,需要使用startActivityForResult方法來顯示Activity。
從Activity1跳轉到Activity2:

Intent intent = new Intent();
 intent = intent.setClass(ActivityIntent.this, AnotherActivity.class);
 Bundle bundle = new Bundle();
 bundle.putString("string", et_string.getText().toString());
 intent.putExtras(bundle);
 startActivityForResult(intent,0); //只有這里不同

從Activity2返回數據到Aactivity1:

Intent intent = new Intent();
intent = intent.setClass(AnotherActivity.this, ActivityIntent.class);
Bundle bundle = new Bundle();
bundle.putInt("result", "Activity2的處理結果");
intent.putExtras(bundle); 
AnotherActivity.this.setResult(RESULT_OK, intent); //RESULT_OK是返回狀態碼
AnotherActivity.this.finish();

在Activity1中重寫onActivityResault方法,接受數據:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
                   super.onActivityResult(requestCode, resultCode, data);
                    switch(resultCode) { //根據狀態碼,處理返回結果
                    case RESULT_OK: 
                          Bundle bundle =data.getExtras(); //獲取intent里面的bundle對象
                              String result = bundle.getInt("result"); 
                    break; 
                    default:
                    break;
                    } 

             }

四、Activity的四種創建模式

我們在開發項目的過程中,會涉及到該應用中多個Activity組件之間的跳轉,或者夾帶其它應用的可復用的Activity。例如我們可能希望跳轉到原來某個Activity實例,而不是產生大量重復的 Activity。這樣就需要我們為 Activity 配置特定的加載模式,而不是使用默認的加載模式。設置啟動模式的位置在 Manifest.xml 文件中 Activity的android:launchMode 屬性

  1. standard 模式
    這是默認模式,無需設置,每次激活Activity時都會創建Activity實例,并放入任務棧中。相當于入棧,按back鍵返回到前一個Activity相當于退棧。

  2. singleTop 模式
    如果在任務的棧頂正好存在該Activity的實例,就重用該實例( 會調用實例的 onNewIntent()),否則就會創建新的實例并放入棧頂,即使棧中已經存在該Activity的實例,只要不在棧頂,都會創建新的實例。可用來解決棧頂多個重復相同的Activity的問題

  3. singleTask 模式
    如果在棧中已經有該Activity的實例,就重用該實例(會調用實例的 onNewIntent() )。重用時,會讓該實例回到棧頂,因此在它上面的實例將會被移出棧。如果棧中不存在該實例,將會創建新的實例放入棧中。singleTask 模式可以用來退出整個應用。將主Activity設為SingTask模式,然后在要退出的Activity中轉到主Activity,然后重寫主Activity的onNewIntent函數,并在函數中加上一句finish。

  4. singleInstance 模式
    在一個新棧中創建該Activity的實例,并讓多個應用共享該棧中的該Activity實例。一旦該模式的Activity實例已經存在于某個棧中,任何應用再激活該Activity時都會重用該棧中的實例( 會調用實例的 onNewIntent() )。其效果相當于多個應用共享一個應用,不管誰激活該 Activity 都會進入同一個應用中。

五、Activity現場保存狀態

一般來說,調用onPause()和onStop()方法后的activity實例仍然存在于內存中,activity的所有信息和狀態數據不會消失, 當activity重新回到前臺之后, 所有的改變都會得到保留。但是當系統內存不足時, 調用onPause()和onStop()方法后的activity可能會被系統摧毀, 此時內存中就不會存有該activity的實例對象了. 如果之后這個activity重新回到前臺, 之前所作的改變就會消失.可以在activity被殺掉之前調用保存每個實例的狀態,開發者可以覆寫onSaveInstanceState()方法. onSaveInstanceState()方法接受一個Bundle類型的參數, 開發者可以將狀態數據存儲到這個Bundle對象中,以保證該狀態在onCreate(Bundle)或者onRestoreInstanceState(Bundle)(傳入的Bundle參數是由onSaveInstanceState封裝好的)中恢復。這個方法在一個activity被殺死前調用,當該activity在將來某個時刻回來時可以恢復其先前狀態。如果調用onSaveInstanceState()方法,調用將發生在onPause()或onStop()方法之前,而且它也不是生命周期的方法。
若向數據庫中插入記錄等,保存持久化數據的操作應該放在onPause()中. onSaveInstanceState()方法只適合保存瞬態數據, 比如UI控件的狀態, 成員變量的值等.

public class MainActivity extends Activity {  
    private String temp;    
    @Override  
    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        // 從savedInstanceState中恢復數據, 如果沒有數據需要恢復savedInstanceState為null  
        if (savedInstanceState != null) {  
            temp = savedInstanceState.getString("temp");  
            System.out.println("onCreate: temp = " + temp);  
        }  
    }  
  
    public void onRestoreInstanceState(Bundle saveInstanceState) {  
        super.onRestoreInstanceState( saveInstanceState);  
        String temp  = saveInstanceState.getString("temp");  
        System.out.println("onResume: temp = " + temp);  
       
    }  
      
    // 將數據保存到outState對象中, 該對象會在重建activity時傳遞給onCreate方法和onRestoreInstanceState方法
    @Override  
    protected void onSaveInstanceState(Bundle outState) {  
        super.onSaveInstanceState(outState);  
        outState.putString("temp", temp);  
    }  

六、一些關于Activity的技巧

  1. 設置Activity的方向
 android:screenOrientation="portrait">// 豎屏 , 值為 landscape 時為橫屏
  1. 設置Activity全屏
    在onCreate方法中添加如下代碼:
 // 設置全屏模式
 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
    WindowManager.LayoutParams.FLAG_FULLSCREEN); 
 // 去除標題欄
 requestWindowFeature(Window.FEATURE_NO_TITLE);
  1. 改變窗口大小、位置、透明度
    在onCreate方法中添加如下代碼:
 Window w=getWindow();
 w.setBackgroundDrawableResource(resourceID);//設置窗口背景
WindowManager.LayoutParams layoutParams  = w.getAttributes();
layoutParams.height = 200; 
layoutParams.width= 200;
layoutParams.gravity = Gravity.TOP;
layoutParams.x=50;//距離Gravity屬性的距離
layoutParams.y=50;
layoutParams.alpha = 0.5;//0:完全透明,1:不透明
w.setAttributes(layoutParams);
  1. 關閉所有窗口
Intent intent = new Intent(); 
intent.setClass(Android123.this, CWJ.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  //注意本行的FLAG設置 
startActivity(intent) 

另一種方法:在調用退出方法中寫上MyApplication.getInstance().exit();

public class MyApplication extends Application {

        private List<Activity> activityList = new LinkedList<Activity>();
        private static MyApplication instance;

        private MyApplication() {
        }

        // 單例模式中獲取唯一的MyApplication實例
        public static MyApplication getInstance() {
                if (null == instance) {
                        instance = new MyApplication();
                }
                return instance;

        }

        // 添加Activity到容器中
        public void addActivity(Activity activity) {
                activityList.add(activity);
        }

        // 遍歷所有Activity并finish
        /*
         * 在每一個Activity中的onCreate方法里添加該Activity到MyApplication對象實例容器中
         * 
         * MyApplication.getInstance().addActivity(this);
         * 
         * 在需要結束所有Activity的時候調用exit方法
         * 
         * MyApplication.getInstance().exit();
         */
        public void exit() {

                for (Activity activity : activityList) {
                        activity.finish();
                }

                System.exit(0);

        }
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,363評論 6 532
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,497評論 3 416
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,305評論 0 374
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,962評論 1 311
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,727評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,193評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,257評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,411評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,945評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,777評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,978評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,519評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,216評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,642評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,878評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,657評論 3 391
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,960評論 2 373

推薦閱讀更多精彩內容

  • Activity 一、四種形態 運行狀態: 當 Activity 處于棧的頂層,可見,并可與用戶進行交互 onRe...
    任教主來也閱讀 1,684評論 1 10
  • ¥開啟¥ 【iAPP實現進入界面執行逐一顯】 〖2017-08-25 15:22:14〗 《//首先開一個線程,因...
    小菜c閱讀 6,483評論 0 17
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,643評論 25 708
  • 需求:QQ紅包測試 1、查看原型圖,設計稿 2、了解開發實現,參與CodeView和前后端交互(走哪些接口數據) ...
    星_修閱讀 905評論 0 0
  • 今天上班是有關于突破的,我不排除自己是一個很認真的人,尤其是當我很想記住某個點的時候,我特別認真去記,可效果很不好...
    Hi_張閱讀 181評論 0 0