Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> Android應用開發教程之十八:活動任務堆棧詳解

Android應用開發教程之十八:活動任務堆棧詳解

編輯:關於android開發

  今天帶著個人疑問與實際項目開發中遇到的問題,跟大家一起學習下安卓活動與任務堆棧方面的知識,直入正題:相信大家都碰到過並沒有過多的操作內存但應用自動強制退出或OOM的吧?這個問題也是我本人在面試過程中被人問到的,順帶學習並記錄在博客中,跟大家交流,共同提高改進…說到堆棧,我的第一反應是跟我沒關系,操作不到這個吧?其實錯了,請大家繼續看下文:

  如果你的應用中涉及到的東西比較耗內存的話,比如:相機、第三方地圖、騰訊、新浪、錄音、視頻播放、大量圖片時,如果這些東西同時存在於應用中時,會有很多奇怪的問題出現,自動退出還不報錯等等一系列的問題,還有,如果我們的應用中使用startActivity()過多而且並沒有及時finish()掉的話,也會出現這樣那樣的問題,比如:退出應用時沒有退出干淨,或者莫名其妙的報OOM,啟動的服務自動掛起什麼的!

  其實,Google已經提供了一套完整的機制讓開發人員控制活動棧與任務棧,結合如下代碼:(我會以最簡單的代碼來說明實際開發中遇到的問題處理,不足之外,請大家直接指出批評,有錯必改!)

  首先:我們來啟動三個Activity來模擬生成活動與任務堆棧,三個Activity分別是:AndroidStackTaskActivity1、AndroidStackTaskActivity2、AndroidStackTaskActivity3,具體代碼如果下:

Java代碼
  1. package com.xiaoma.www;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9.    
  10. /** 
  11. * @Title: AndroidStackTaskActivity.java 
  12. * @Package com.xiaoma.www 
  13. * @Description: 活動、任務堆棧學習 
  14. * @author XiaoMa 
  15. */  
  16. public class AndroidStackTaskActivity1 extends Activity implements OnClickListener{  
  17.    
  18.     private Button next = null ;   
  19.    
  20.     /** Called when the activity is first created. */  
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main);  
  25.    
  26.         init();  
  27.     }  
  28.    
  29.     private void init(){  
  30.         next = (Button)findViewById(R.id.button1);  
  31.         next.setOnClickListener(this);  
  32.     }  
  33.    
  34.     @Override  
  35.     public void onClick(View v) {  
  36.         // TODO Auto-generated method stub  
  37.         Intent i = new Intent(this,AndroidStackTaskActivity2.class);  
  38.         startActivity(i);  
  39.     }  
  40. }
Java代碼
  1. package com.xiaoma.www;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9.    
  10. /** 
  11. * @Title: AndroidStackTaskActivity2.java 
  12. * @Package com.xiaoma.www 
  13. * @Description: 活動、任務堆棧學習 
  14. * @author XiaoMa 
  15. */  
  16. public class AndroidStackTaskActivity2 extends Activity  implements OnClickListener {  
  17.    
  18.     private Button next = null ;   
  19.    
  20.     /** Called when the activity is first created. */  
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main2);  
  25.    
  26.         init();  
  27.     }  
  28.    
  29.     private void init(){  
  30.         next = (Button)findViewById(R.id.button1);  
  31.         next.setOnClickListener(this);  
  32.     }  
  33.    
  34.     @Override  
  35.     public void onClick(View v) {  
  36.         // TODO Auto-generated method stub  
  37.         Intent i = new Intent(this,AndroidStackTaskActivity3.class);  
  38.         startActivity(i);  
  39.     }  
  40.    
  41. }  
Java代碼
  1. package com.xiaoma.www;  
  2.    
  3. import android.app.Activity;  
  4. import android.content.Intent;  
  5. import android.os.Bundle;  
  6. import android.view.View;  
  7. import android.view.View.OnClickListener;  
  8. import android.widget.Button;  
  9.    
  10. /** 
  11. * @Title: AndroidStackTaskActivity2.java 
  12. * @Package com.xiaoma.www 
  13. * @Description: 活動、任務堆棧學習 
  14. * @author XiaoMa 
  15. */  
  16. public class AndroidStackTaskActivity3 extends Activity  implements OnClickListener {  
  17.    
  18.     private Button next = null ;   
  19.    
  20.     /** Called when the activity is first created. */  
  21.     @Override  
  22.     public void onCreate(Bundle savedInstanceState) {  
  23.         super.onCreate(savedInstanceState);  
  24.         setContentView(R.layout.main2);  
  25.    
  26.         init();  
  27.     }  
  28.    
  29.     private void init(){  
  30.         next = (Button)findViewById(R.id.button1);  
  31.         next.setOnClickListener(this);  
  32.     }  
  33.    
  34.     @Override  
  35.     public void onClick(View v) {  
  36.         // TODO Auto-generated method stub  
  37.         Intent i = new Intent(this,AndroidStackTaskActivity3.class);  
  38.         startActivity(i);  
  39.     }  
  40.    
  41. }  

  代碼很簡單, 大家不用看運行效果也可以想出什麼情況 ,不過這個地方主要看堆棧,不看這些代碼,貼在這裡供大家搞清楚三個Activity的啟動順序,此時,生成的活動堆棧如下圖所示:

Android應用開發教程之十八:活動任務堆棧詳解

  這個地方說明下,有時候大家可以想著從1到2時可以綁定數據完成回顯,但是如果要簡單的回顯用綁定或startActivityForResult()這兩種方式啟動,但是如果涉及到三個以上的活動惑更多活動之間的跳轉時,有時候不得不必須重新啟動新的活動,也就出現了前面的1>>2>>3>>4>>>>>>>甚至更多的活動跳轉,這樣一個個關閉有時候還是關不干淨,應用退出的時候也還是不干淨的,更搞笑的是有時候還有用戶在多個活動之間跳轉並不進行任何數據操作時還要求返回上一個Activity時你就不能直接finish掉上一個Activity,不然人家說你跳轉不對,針對這個問題我們來看下Google提供的堆棧任務控制機制吧,很簡單,用Flag來控制,這個時候就有個問題,提供的方法有setFlag()、addFlag(),這兩個肯定有什麼區別的,不然不會出現兩個控制Flag的方法的,繼續….先看下如下兩種效果:

  第一種:未設置Flag時

Android應用開發教程之十八:活動任務堆棧詳解

  第二種 :已設置Flag時

Android應用開發教程之十八:活動任務堆棧詳解

  如上所示,大家應該看出來了,同樣點擊了六次按鈕之後按的返回鍵,第一種效果必須點擊六次Back鍵後方可退出,而第二種效果只點擊一次即可退出,這就是Flag的魅力,激動….再來看Flag都有哪幾種吧,此處我列在這個地方,上面兩個效果中設置的是:i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);另外還有很多可以控制活動堆棧與任務棧的Flag,小馬在這個地方隨便列出兩個,剩余的Flag值以截圖的形式顯示,節約時間:

  1. i.setFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);

  2. i.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY)其它:

Android應用開發教程之十八:活動任務堆棧詳解

  大家可以很清楚的看到以後所含的標志中有針對於TASK的,對吧?指的就是任務堆棧,至於什麼是任務堆棧,大家不用太過糾結於與活動堆棧之間的概念什麼的,只記住一點:如果你在應用中啟動Activity的時候沒加任務堆棧的控制Flag時,開發環境肯定報錯,而且提示的很准確 ,就是:你缺少添加任務堆棧Flag標志位,具體少了哪個標志,開發環境也會很准確的指出,必須要你添加才可正常編譯通過!下面列下小馬犯的錯誤,就是在一個Activity找到一個amr錄音文件,直接以下面的方式啟動去播放錄音,猛報錯:

Java代碼
  1. Intent i = new Intent(Intent.ACTION_VIEW);  
Java代碼
  1. i.putExtra("filePath",path);  
Java代碼
  1. startActivity(i);    

  如果加了 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);操作下任務堆棧就可以了,具體的原因,也可以用一句話來總結:如果在一個Activity中同一時間,要操作不用的功能,比如:跳轉時還要操作視頻錄音文件的播放什麼的,都得設置新的任務棧來啟動打開,如果不啟動新任務棧的話,有時候會無原無故的顯示空白還不報錯!上面的錯只是一個小點,小到可以忽略不講,寫在這是提醒大家,該加的時候必須加Flag,至於什麼時候加,大家可以參照下官方的文檔及下面小馬貼出的官方文檔中解釋堆棧的圖解,加以理解學習,如下所示:

  Figure2:不多解釋,就是在A B 丙個任務堆棧,如果用戶正在於B任務堆棧進行交互時,A在等待喚醒,反之則反

Android應用開發教程之十八:活動任務堆棧詳解

  Figure3: 下面這個就好玩了,學習了下官方的文檔,講的是:無論啟動了一個新的任務堆棧或者在同一堆棧中來啟動一個活動,按返回鍵也還是會返回到用戶之前操作的Activity,如果以單例堆棧(類似單位模式)載入的話,就會在後台生成一個針對於此活動的單獨的一個任務堆棧,當這個任務堆棧被喚醒到前台時,此時的返回堆棧中就包含了從前幾個任務傳遞過來的棧頂的所有Activity,棧頂與棧底的顯示關系如果下圖:

Android應用開發教程之十八:活動任務堆棧詳解

  這個地方順帶著講下,在控制活動堆棧時方式只有一種,就是直接在.java文件中setFlag,如果是控制任務堆棧的話可以以addFlag或直接在全局配置文件中添加配置的方式來控制,大家可以直接在AndroidManifest.xml文件中activity節點中添加哪下屬性:taskAffinity、launchMode、allowTaskReparenting、clearTaskOnLaunch、alwaysRetainTaskState、finishOnTaskLaunch,兩種控制任務堆棧的方式換湯不換藥,大家看個人習慣選擇使用就可以了…切記,用的時候一定搞清楚你要加的標志位是什麼意思,不要看到個task就addFlag,設置Flag是為了讓應用更干淨,控制更嚴密,如果加錯了標志位,應用是不會報任何錯的,只是出現怪異的跳轉與關閉!!!這是我個人亂加Flag時的教訓,大家也謹用!今天就先寫到這啦,文章中難免會有不盡人意之處,若有疑問有錯誤,請大家直接指出批評!

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved