編輯:Android資訊
學過android的人都知道,activity是最常用的四大組件之一,但你真的了解透徹activity了嗎?接下來,本人將從activity的正常和異常生命周期、啟動模式、IntentFilter匹配原則、activity的過渡動畫等方面做個總結。
這種情況是最普通的狀況,Activity的生命周期會按照上圖從上到下的方式走。即:onCreate –> onStart –> onResume –> 運行–> 按返回鍵結束程序–> onPause–>onStop–>onDestory
對於A:onCreate –> onStart –> onResume –> A運行 –> A發出打開B的Intent –> onPause–>B可見–>onStop
此時,會打開B,B同樣會經歷一個完整的Activity生命周期。等B結束,A再度可見的時候,A會經歷:onRestart–>onStart–>onResume
注意:B這個Activity是在A的onPause執行後才變成可見狀態的,所以為了不影響B的顯示,最好不要在onPause裡執行一些耗時操作,可以考慮將這些操作放到onStop裡,這時B已經可見了。
資源相關的系統配置發生改變,舉個例子。當前Activity處於豎屏狀態的時候突然轉成橫屏,系統配置發生了改變,Activity就會銷毀並且重建,其onPause, onStop, onDestory均會被調用。因為實在異常情況下終止的,所以系統會調用onSaveInstanceState來保存當前Activity狀態。這個方法是在onStop之前,與onPause沒有固定的時序關系。當Activity重建的時候系統會把onSaveInstanceState所保存的Bundle作為對象傳遞給onRestoreInstanceState和onCreate方法。
Activity優先級
前台Activity——正在和用戶交互的Activity,優先級最高
可見但非前台Activity——Activity中彈出的對話框導致Activity可見但無法交互
後台Activity——已經被暫停的Activity,優先級最低
系統內存不足是,會按照以上順序殺死Activity,並通過onSaveInstanceState和onRestoreInstanceState這兩個方法來存儲和恢復數據。
四種啟動模式分別是standard(標准模式)、singleTop(棧頂復用模式)、singleTask(棧內復用模式)、singleInstance(單實例模式 – 加強的singleTask模式)
運用場景:常運用於通知欄彈出Notification,點擊Notification跳轉到指定的Activity,設置singleTop模式
運用場景:可用來退出整個應用。主界面activity設為singleTas模式,要退出應用時轉到主activity,從而將主activity之上的activity都清除,然後重寫主activity的onNewIntent()方法,在裡面加上finish(),即可退出所有activity。這種模式還適用於做浏覽器、微博之類的應用
運用場景:這種模式常運用於需要與程序分離的界面,如在SetupWizard(安裝向導)中調用緊急呼叫就是適用這種模式
Intent是抽象的數據結構,包含了一系列描述某個操作的數據,使得程序在運行時可以在程序中不同組件間通信或啟動不同的應用程序。
可以通過startActivity(Intent)啟動一個Activity,sendBroadcast(Intent))發送廣播發送給感興趣的BroadcastReceiver組件,startService(android.content.Intent))啟動service,bindService()綁定服務。
Intent Filter顧名思義就是Intent的過濾器,組件通過定義Intent Filter可以決定哪些隱式Intent可以和該組件進行通訊
Intent分為隱式(implicit)Intent和顯式(explicit)Intent。
顯式Intent通常用於在程序內部組件間通信,已經明確的定義目標組件的信息,所以不需要系統決策哪個目標組件處理Intent,如下
Intent intent =new Intent(CRListDemo.this, GoogleMapDemo.class); startActivity(intent);
其中CRListDemo和GoogleMapDemo都是用戶自定義的組件,
隱式Intent不指明目標組件的class,只定義希望的Action及Data等相關信息,由系統決定使用哪個目標組件。如發送短信
Android系統通過對Intent和目標組件在AndroidManifest文件中定義的(也可以在程序中定義Intent Filter)進行匹配決定和哪個目標組件通訊。如果某組件未定義則只能通過顯式的Intent進行通信。Intent的三個屬性用於對目標組件選取的決策,分別是Action、Data(Uri和Data Type)、Category。匹配規則如下
a. 發送短信
Uri uri = Uri.parse("smsto:15800000000"); Intent i=newIntent(Intent.ACTION_SENDTO, uri); i.putExtra("sms_body", "The SMS text"); startActivity(i);
b. 打電話
Uri dial = Uri.parse("tel:15800000000"); Intent i=newIntent(Intent.ACTION_DIAL, dial); startActivity(i);
c. 發送郵件
Uri email = Uri.parse("mailto:[email protected];[email protected]"); Intent i=newIntent(Intent.ACTION_SENDTO, email); startActivity(i);
d. 拍照
Intent i =newIntent(MediaStore.ACTION_IMAGE_CAPTURE); String folderPath= Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "AndroidDemo" +File.separator; String filePath= folderPath + System.currentTimeMillis() + ".jpg";newFile(folderPath).mkdirs(); File camerFile=newFile(filePath); i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(camerFile)); startActivityForResult(i,1);
e. 浏覽網頁
Uri web = Uri.parse("http://www.google.com"); Intent i=newIntent(Intent.ACTION_VIEW, web); startActivity(i);
f. 查看聯系人
Intent i =newIntent(); i.setAction(Intent.ACTION_GET_CONTENT); i.setType("vnd.android.cursor.item/phone"); startActivityForResult(i,1);
overridePendingTransition方法是Activity中提供的Activity跳轉動畫方法,通過該方法可以實現Activity跳轉時的動畫效果,簡單例子如下:
Intent intent =newIntent(MainActivity.this, SecondActivity.class); startActivity(intent); overridePendingTransition(R.anim.slide_in_left, R.anim.slide_in_left);
注意:overridePendingTransition在startActivity或者是finish方法立刻執行才有效
(1)定義Application的style
<!-- 系統Application定義 --> <application Android:allowBackup="true" Android:icon="@mipmap/ic_launcher" Android:label="@string/app_name" Android:supportsRtl="true" Android:theme="@style/AppTheme">
(2)定義具體的AppTheme樣式
其中這裡的windowAnimationStyle就是我們定義Activity切換動畫的style。而@anim/slide_in_top就是我們定義的動畫文件,也就是說通過為Appliation設置style,然後為windowAnimationStyle設置動畫文件就可以全局的為Activity的跳轉配置動畫效果。
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="Android:windowAnimationStyle">@style/activityAnim</item>
</style><!-- 使用style方式定義activity切換動畫 --> <style name="activityAnim"> <item name="Android:activityOpenEnterAnimation">@anim/slide_in_top</item> <item name="Android:activityOpenExitAnimation">@anim/slide_in_top</item> </style>
而在windowAnimationStyle中存在四種動畫:
通過overridePendingTransition方法基本上可以滿足我們日常中對Activity跳轉動畫的需求了,但MD風格出來之後,overridePendingTransition這種老舊、生硬的方式怎麼能適合我們的MD風格的App呢?google在新的sdk中給我們提供了另外一種Activity的過度動畫——ActivityOptions。並且提供了兼容包——ActivityOptionsCompat。ActivityOptionsCompat是一個靜態類,提供了相應的Activity跳轉動畫效果,通過其可以實現不少炫酷的動畫效果。
(1)在跳轉的Activity中設置contentFeature
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 設置contentFeature,可使用切換動畫 getWindow().requestFeature(Window.FEATURE_CONTENT_TRANSITIONS); Transition explode = TransitionInflater.from(this).inflateTransition(Android.R.transition.explode); getWindow().setEnterTransition(explode); setContentView(R.layout.activity_three); }
(2)在startActivity執行跳轉邏輯的時候調用startActivity的重寫方法,執行ActivityOptions.makeSceneTransitionAnimation方法
/** * 點擊按鈕,實現Activity的跳轉操作 * 通過Android5.0及以上代碼的方式實現activity的跳轉動畫 */ button3.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, ThreeActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle()); } });
activity跳轉動畫效果
這種方式其實就是通過style的方式展示和使用ActivityOptions過度動畫,下面是實現通過定義style方式定義過度動畫的步驟:
(1)編寫過度動畫文件
<explode xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:duration="300" />
首先我們需要在Application項目res目錄下新建一個transition目錄,然後創建資源文件,然後使用這些系統自帶的過渡動畫效果,這裡設置了過度時長為300ms。
(2)定義style文件
<!-- Base application theme. --> <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> <!-- Customize your theme here. --> <item name="colorPrimary">@color/colorPrimary</item> <item name="colorPrimaryDark">@color/colorPrimaryDark</item> <item name="colorAccent">@color/colorAccent</item> <item name="Android:windowEnterTransition">@transition/activity_explode</item> <item name="Android:windowExitTransition">@transition/activity_explode</item> </style>
在Application的style文件中添加:
<item name="Android:windowEnterTransition">@transition/activity_explode</item> <item name="Android:windowExitTransition">@transition/activity_explode</item>
並指定過渡動畫效果為我們剛剛定義的過渡動畫文件。
(3)執行跳轉邏輯
點擊按鈕,實現Activity的跳轉操作 * 通過Android5.0及以上style的方式實現activity的跳轉動畫
button4.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { /** * 調用ActivityOptions.makeSceneTransitionAnimation實現過度動畫 */ Intent intent = new Intent(MainActivity.this, FourActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this).toBundle()); } });
這樣執行之後也可以展示出Activity跳轉過度動畫了,其和通過代碼方式實現的效果是類似的,而且這種動畫效果是全局的。
這裡的共享組件動畫效果是指將前面一個Activity的某個子View與後面一個Activity的某個子View之間有過渡效果,即在這種過度效果下實現Activity的跳轉操作。那麼如何實現兩個組件View之間實現過渡效果呢?
(1)定義共享組件
在Activity a中的button按鈕點擊transitionName屬性:
<Button Android:id="@+id/button5" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_below="@+id/button4" Android:layout_marginTop="10dp" Android:layout_marginRight="10dp" Android:layout_marginLeft="10dp" Android:text="組件過度動畫" Android:background="@color/colorPrimary" Android:transitionName="shareNames" />
在Activity b的布局文件中為組件定義transitionName屬性,這樣這兩個組件相當於有了過度對應關系,這裡需要注意的是這兩個組件的transitionName屬性的值必須是相同的。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:id="@+id/activity_second" Android:layout_width="match_parent" Android:layout_height="match_parent" Android:gravity="center_horizontal" Android:orientation="vertical" Android:transitionName="shareNames" > <TextView Android:layout_width="match_parent" Android:layout_height="match_parent" Android:background="@color/colorAccent" Android:layout_marginTop="10dp" Android:layout_marginBottom="10dp" /> </LinearLayout>
(2)調用startActivity執行跳轉動畫
點擊按鈕,實現Activity的跳轉操作 * 通過Android5.0及以上共享組件的方式實現activity的跳轉動畫
button5.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, FiveActivity.class); startActivity(intent, ActivityOptions.makeSceneTransitionAnimation(MainActivity.this, button5, "shareNames").toBundle()); } });
需要說明的是這裡調用的ActivityOptions.makeSceneTransitionAnimation方法,傳遞了三個參數,其中第一個參數為context對象,第二個參數為啟動Activity的共享組件,第三個參數為啟動Activity的共享組件transitionName屬性值。
這樣經過調用之後我們就實現了從Activity a跳轉到Activity b的時候a中的組件到b中組件的過度效果。
過渡動畫總結
- overridePendingTransition方法從Android2.0開始,基本上能夠覆蓋我們activity跳轉動畫的需求;
- ActivityOptions API是在Android5.0開始的,可以實現一些炫酷的動畫效果,更加符合MD風格;ActivityOptions還可以實現兩個Activity組件之間的過度動畫;
過渡動畫可參考github項目地址:實現activity跳轉動畫的五種方式
一、ActionBar概述 ActionBar是androiD3.0以後新增的組件,主要用於標示應用程序以及用戶所處的位置並提供相關操作以及全局的導航功能。下面我
由於我們很容易習慣公式化的預置代碼,有時我們會忽略很優雅的細節。LayoutInflater以及它在Fragment的onCreateView()中填充View的
一、萌芽 作為一只編程經驗並不怎麼豐富的程序猿來講,我一直覺得架構師是一個比較神秘的職業,架構設計就更加的高大上了。經過今年的幾個項目,之前曾發文敘述我的從MVC
本項目主要對目前 GitHub 上排名前 100 的 Android 開源庫進行簡單的介紹, 至於排名完全是根據GitHub搜索Java語言選擇 (Best Ma