天天看點

談一談對Activity的了解

一、Activity的生命周期

Activity的基本生命周期如下代碼 所示:

public class MyActivity extends Activity {   

    protected void onCreate(Bundle savedInstanceState);   

    protected void onStart();   

    protected void onResume();   

    protected void onPause();   

    protected void onStop();   

    protected void onDestroy();   

  }    
           

詳細介紹一下這幾個方法中系統在做什麼以及我們應該做什麼:

- onCreate:在這裡建立界面 ,做一些資料 的初始化工作。

- onStart:到這一步變成使用者可見不可互動的。

- onResume:變成和使用者可互動的,在activity棧系統通過棧的方式管理這些個Activity的最上面,運作完彈出棧,則回到上一個Activity。

- onPause:到這一步是可見但不可互動的,系統會停止動畫等消耗CPU 的事情。從上文的描述已經知道,應該在這裡儲存你的一些資料,因為這個時候你的程式的優先級降低,有可能被系統收回。在這裡儲存的資料,應該在onResume裡讀出來。注意:這個方法裡做的事情時間要短,因為下一個activity不會等到這個方法完成才啟動。

- onStop:變得不可見 ,被下一個activity覆寫了。

- onDestroy:這是activity被幹掉前最後一個被調用方法了,可能是外面類調用finish方法或者是系統為了節省空間将它暫時性的幹掉,可以用isFinishing()來判斷它,如果你有一個Progress Dialog線上程中轉動,請在onDestroy裡把他cancel掉,不然等線程結束的時候,調用Dialog的cancel方法會抛異常的。

onPause,onStop, onDestroy,三種狀态 下 activity都有可能被系統幹掉。為了保證程式的正确性,你要在onPause()裡寫上持久層操作的代碼,将使用者編輯的内容都儲存到存儲媒體上(一般都是資料庫 )。實際工作中因為生命周期的變化而帶來的問題也很多,比如你的應用程式起了新的線程在跑,這時候中斷了,你還要去維護那個線程,是暫停還是殺掉還是資料復原,是吧?因為Activity可能被殺掉,是以線程中使用的變量和一些界面元素就千萬要注意了,一般我都是采用Android的消息機制 [Handler,Message]來處理多線程和界面互動的問題。這個我後面會講一些,最近因為這些東西頭已經很大了,等我理清思緒再跟大家分享。

多個Activity的生命周期互動的思想,請參考:http://blog.csdn.net/u012301841/article/details/49586539

二、讓Activity變成一個視窗:Activity屬性設定

講點輕松的吧,可能有人希望做出來的應用程式是一個漂浮在手機主界面的東西,那麼很簡單你隻需要設定 一下Activity的主題就可以了在AndroidManifest.xml 中定義 Activity的地方一句話:

android:theme="@android:style/Theme.Dialog" 
// 這就使你的應用程式變成對話框的形式彈出來了,或者
android:theme="@android:style/Theme.Translucent" 
// 就變成半透明的
           

【友情提示】類似的這種activity的屬性可以在android.R.styleable 類的AndroidManifestActivity 方法中看到,AndroidManifest.xml中所有元素的屬性的介紹都可以參考這個類android.R.styleable。上面說的是屬性名稱,具體有什麼值是在android.R.style中 可以看到,比如這個”@android:style/Theme.Dialog” 就對應于android.R.style.Theme_Dialog。

三、你背景的Activity被系統回收怎麼辦:onSaveInstanceState

當你的程式中某一個Activity A 在運作時中,主動或被動地運作另一個新的Activity B,這個時候A會執行onSaveInstanceState方法。

public
void onSaveInstanceState(Bundle outState) {   
    super.onSaveInstanceState(outState);   
    outState.putLong("id", );   
}  
           

B 完成以後又會來找A,這個時候就有兩種情況,一種是A被回收,一種是沒有被回收,被回收的A就要重新調用onCreate()方法,不同于直接啟動的是這回onCreate()裡是帶上參數savedInstanceState,沒被收回的就還是onResume就好了。

savedInstanceState是一個Bundle對象,你基本上可以把他了解為系統幫你維護的一個Map對象。在onCreate裡你可能會用到它,如果正常啟動onCreate就不會有它,是以用的時候要判斷一下是否為空。

if (savedInstanceState != null) {   
     long id = savedInstanceState.getLong("id");   
}   
           

onSaveInstanceState(Bundle outState)方法在onPause()之後調用的。

就像官方的Notepad教程 裡的情況,你正在編輯某一個note,突然被中斷,那麼就把這個note的id記住,再起來的時候就可以根據這個id去把那個note取出來,程式就完整一些。這也是看你的應用需不需要儲存什麼,比如你的界面就是讀取一個清單,那就不需要特殊記住什麼,哦, 沒準你需要記住滾動條的位置…

四、調用與被調用:我們的通信使者Intent

要說Intent了,Intent就是這個這個意圖 ,應用程式間Intent進行交流,打個電話啦,來個電話啦都會發Intent,這個是Android架構的松耦合的精髓部分,大大提高了元件的複用性,比如你要在你的應用程式中點選按鈕,給某人打電話,很簡單啊,看下代碼先:

Intent intent = new Intent();   
intent.setAction(Intent.ACTION_CALL);   
intent.setData(Uri.parse("tel:" + number));   
startActivity(intent);  
           

扔出這樣一個意圖,系統看到了你的意圖就喚醒了電話撥号程式,打出來電話。什麼讀聯系人,發短信啊,郵件啊,統統隻需要扔出intent就好了,這個部分設計 地确實很好啊。

那Intent通過什麼來告訴系統需要誰來接受他呢?通常使用Intent有兩種方法,第一種是直接說明需要哪一個類來接收代碼如下:

Intent intent = new Intent(this, MyActivity.class);   
intent.getExtras().putString("id", "1");   
startActivity(intent); 
           

第一種方式很明顯,直接指定了MyActivity為接受者,并且傳了一些資料給MyActivity,在MyActivity裡可以用getIntent()來的到這個intent和資料。

第二種就需要先看一下AndroidMenifest中的intent-filter的配置了:

<intent-filter> 
    <action android:name="android.intent.action.VIEW" /> 
    <action android:value="android.intent.action.EDIT" /> 
    <action android:value="android.intent.action.PICK" /> 
    <category android:name="android.intent.category.DEFAULT" /> 
    <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> 
</intent-filter> 
           

action其實就是一個意圖的字元串名稱。

上面這段intent-filter的配置檔案說明了這個Activity可以接受不同的Action,當然相應的程式邏輯也不一樣咯,提一下那個 mimeType,他是在ContentProvider裡定義的,你要是自己實作一個ContentProvider就知道了,必須指定 mimeType才能讓資料被别人使用。不知道原理說明白沒,總結一句,就是你調用别的界面不是直接new那個界面,而是通過扔出一個intent,讓系統幫你去調用那個界面,這樣就多麼松藕合啊,而且符合了生命周期被系統管理的原則。想知道category都有啥,Android為你預先定制好的action都有啥等等,請親自通路官方連結Intent 。

ps:想知道怎麼調用系統應用程式的同學,可以仔細看一下你的logcat,每次運作一個程式的時候是不是有一些資訊比如:

Starting activity: Intent { action=android.intent.action.MAINcategories={android.intent.category.LAUNCHER} flags=0x10200000comp={com.android.camera/com.android.camera.GalleryPicker} }

再對照一下Intent的一些set方法,就知道怎麼調用咯,希望你喜歡:)

繼續閱讀