Android四大组件(activity task stack)
Activity
生命周期
- onCreate:創建活動。此時會把頁面布局加載進內存,進入了初始狀態。
- onStart:開啟活動。此時會把活動頁面顯示在屏幕上,進入了就緒狀態。
- onResume:恢復活動。此時活動頁面進入活躍狀態,能夠與用戶正常交互,例如允許響應用戶的點擊動作、允許用戶輸入文字等。
- onPause:暫停活動。此時活動頁面進入暫停狀態(也就是退回就緒狀態),無法與用戶正常交互。
- onStop:停止活動。此時活動頁面將不在屏幕上顯示。 onDestroy:銷毀活動。此時回收活動占用的系統資源,把頁面從內存中清除掉。
- onRestart:重啟活動。處于停止狀態的活動,若想重新開啟的話,無須經歷onCreate的重復創建過程,而是走onRestart的重啟過程。
特殊的聲明周期:
- onNewIntent
在singleTask和singleTop啟動模式下,啟動一個已存在的Activity,該Activity的生命周期會如何回調
activity1(singleTask)
再啟動activity1
[activity1]---task1---foreground生命周期如下:
2022-09-06 12:11:13.262 16389-16389/cn I/TK.LoginActivity: onPause 2022-09-06 12:11:13.264 16389-16389/cn I/TK.LoginActivity: onNewIntent 2022-09-06 12:11:13.299 16389-16389/cn I/TK.LoginActivity: onResumeActivity的啟動模式
首先activity啟動之后是放在任務棧中的,task stack,既然是棧,遵循先進后出原則。有玩家比喻oncreate是入棧,onDestroy是出棧。
同一個APP中,不同的activity可以設置為不同的啟動模式。在manifest中的activity屬性中進行設置:
<activity android:name=".LoginActivity"android:screenOrientation="landscape"android:configChanges="orientation|screenSize|keyboardHidden"android:launchMode="singleTask"android:exported="true">- 默認啟動模式 standard
標準的啟動模式,每次oncreate都會入棧一個activity,比如當前為activity2,棧內為
[activity2]此時再啟動activity2,棧內為
[activity2,activity2]- 棧頂復用模式 singleTop
比如當前為activity2,棧內為
[activity2]此時再啟動activity2,則棧內為
[activity2]此時再啟動activity1,則棧內為
[activity2,activity1]- 棧內復用模式 singleTask
彈出之上的所有activity。適用于主界面以及占用資源較多的界面。
比如當前為activity2(singleTask),棧內為
[activity2]此時再啟動activity2,則棧內為
[activity2]此時再啟動activity1 (standard),則棧內為
[activity2,activity1]此時再啟動activity3 (standard),則棧內為
[activity2,activity1, activity3 ]此時再啟動activity2 (standard),則棧內為
[activity2]- 全局唯一模式 singleInstance
該模式會創建一個task來單獨存放對應的activity。新的task有且只有這一個activity實例。
activity1(standard )、activity2(standard )、activity3(singleInstance)
啟動activity1
[activity1]---task1---foreground啟動activity3
[activity1]---task1---background [activity3]---task2---foreground啟動activity2
[activity1,activity2]---task1---foreground [activity3]---task2---background啟動activity3
[activity1,activity2]---task1---background [activity3]---task2---foreground啟動activity2
[activity1,activity2,activity2]---task1---foreground [activity3]---task2---background程序動態啟動activity
擴展
判斷是否為根activity。
isTaskRoot()isTaskRoot() 有意思的bug
頁面跳轉
Intent intent = new Intent(this, TestActivityTo.class); startActivity(intent);activity之間傳遞信息
1.使用bundle打包消息后進行消息的傳遞
- 消息發送類
消息接收類
public class ActReviceActivity extends AppCompatActivity {private TextView tvReceive;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_revice);Intent intent = getIntent();Bundle bundle = intent.getExtras();String showInf = String.format("傳遞消息時間 %s \n 傳遞內容 %s \n ",bundle.getString("time"), bundle.getString("content"));initView();tvReceive.setText(showInf);}private void initView() {tvReceive = (TextView) findViewById(R.id.tv_receive);} }- 如果getString的key不存在,則會返回null。
2.使用intent進行消息的傳遞
- 消息發送類
- 消息接收類
3.小結
intent在put數據時底層也是使用了bundle
使用bundle傳輸數據更多用于A界面傳輸到B界面再傳輸到C界面這樣鏈條比較長的場景。這樣的話,B界面取到數據后,不用再重新打包,可以直接將bundle發送過去。
廣播
BroadcastReceiver.onReceive默認是在主線程(UI線程)執行的,所以不能在廣播接收器做耗時操作。
廣播發送者可以指定接收廣播的應用,只要將sendBroadcast(intent)的intent加上具體的包名就行了,intent.setPackage(“yourpackagename”)。
廣播發送者和接收者都可以聲明權限,這樣只有在AndroidManifest聲明對應權限,才能接收到相應的廣播消息。
簡介
廣播接收者(BroadcastReceiver)是安卓的四大組件之一。
類似于日常生活中的廣播,安卓系統中的廣播也有發送者和接收者;
發送者通常是系統的應用程序,比如電池電量低,開關機,有電話或者短信到來,網絡是否連接等都會向外發出廣播。
接收者通常是用戶創建的應用程序,注冊對應的廣播后,用來監聽系統發出的廣播,監聽到后可針對廣播事件做相應反饋。
廣播發送者也可以是用戶創建的應用程序,成為自定義廣播。
接收廣播
發送廣播
1 發送有序廣播
使用sendBroadcast()方法發送無序廣播。無序廣播發送時會在攜帶的intent對象中設置action屬性值,所有注冊廣播時設置了相同action值的廣播接收者都能夠接收到該廣播,沒有絕對順序。
2 發送無序廣播
使用sendOrderedBroadcast()方法可以發送有序廣播。廣播發送者和接收者也會先匹配action屬性值,再通過廣播接收者設置的priority屬性值決定廣播的接收順序,priority值越大越先接收到廣播,如果值相同,先注冊的先接收到廣播。
3 指定廣播接收者(一種特殊的有序廣播)
4)Android四大組件將創建的類在配置文件中進行注冊。
廣播步驟
創建一個Receiver類。通過系統自定義的創建。
重寫onReceive()方法。
在AndroidManifest中添加過濾器。
添加此廣播對應的權限。
當前是否為靜態廣播接收不到,但是動態廣播可以接收到。
對于靜態注冊的方法,在Android8.0之后就增加了限制。
從 Android 8.0(API 級別 26)開始,系統對清單聲明的接收器施加了額外的限制。
如果您的應用面向 Android 8.0 或更高版本,則您不能使用清單為大多數隱式廣播(不專門針對您的應用的廣播)聲明接收器。當用戶積極使用您的應用程序時,您仍然可以使用上下文注冊的接收器。
如果仍然想要使用靜態注冊的方式,在發送廣播時需要做聲明:componentName中分別為包和包中類的引用。
intent.setComponent(new ComponentName(“com.example.myreceiver”,“com.example.myreceiver.receiver”));
比如MainActivity中添加:
無序廣播
## 無序廣播@Overridepublic void onClick(View v) {Intent intent = new Intent();// action為字符串形式的intent.setAction(MyBroadCastReceiver.myReceiver);sendBroadcast(intent);}@Overrideprotected void onStart() {super.onStart();myBroadCastReceiver = new MyBroadCastReceiver();// 創建一個意圖過濾器 只處理myReceiverBroadcastReceiver的廣播IntentFilter intentFilter = new IntentFilter(MyBroadCastReceiver.myReceiver);// 注冊接收器,注冊之后才能正常接收廣播registerReceiver(myBroadCastReceiver, intentFilter);}@Overrideprotected void onStop() {super.onStop();// 注銷接收器,注銷之后不再接收廣播unregisterReceiver(myBroadCastReceiver);}public class MyBroadCastReceiver extends BroadcastReceiver {private static String TAG = "MyBroadCastReceiver";public static String myReceiver = "myReceiverBroadcastReceiver";@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(myReceiver)){Log.i(TAG, "onReceive: my receive");}} }有序廣播
優先級最大可以聲明為int型的最大值,也就是2147483647(為了最高優先級,拼了)。默認優先級應該為0;
// 源碼private int mPriority;public IntentFilter(String action) {mPriority = 0;mActions = new ArrayList<String>();addAction(action);}public final void setPriority(int priority) {mPriority = priority;}發送廣播
// 發送廣播 Intent intent2 = new Intent(); // action intent2.setAction(orderBroadCastReceiver); sendOrderedBroadcast(intent2,null);IntentFilter中輸入參數為action
// 注冊
// 接收
registerReceiver 輸入參數分別為BroadcastReceiver receiver, IntentFilter filter
靜態廣播
發送
// public static String shakeBroadcast = "MyShakeBroadcast"; intent3.setAction(shakeBroadcast); ComponentName componentName = new ComponentName(this,"cn.jj.myapplication.receiver.BroadStaticReceiver"); intent3.setComponent(componentName); sendBroadcast(intent3);接收
public class BroadStaticReceiver extends BroadcastReceiver {private String TAG = "HHH.BroadStaticReceiver";@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(MainActivity.shakeBroadcast)){Log.i(TAG, "onReceive: BroadStaticReceiver");Vibrator vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);vibrator.vibrate(500);}} }清單文件
<receiverandroid:name=".receiver.BroadStaticReceiver"android:enabled="true"android:exported="true"><intent-filter><action android:name="MyShakeBroadcast"/></intent-filter></receiver>服務
1)簡介
服務也是Android的四大組件之一。被稱為是沒有界面的activity;它擁有自己的生命周期,可以不隨著activity的銷毀而銷毀。
2)創建方式
需要創建繼承自Service類的自定義類,并在配置文件中使用標簽完成注冊,該類回復寫一個同名構造方法和一個onBind()的回調方法。
3)使用方法
a) 開啟和停止服務
使用startService()方法開啟服務,使用stopService()方法停止服務。
適用于例如開啟和關閉游戲背景音樂的場景。
b) 綁定和解綁服務
使用bindService()方法綁定服務,使用unbindService()方法解綁服務。
適用于服務中私有方法,Activity通過綁定服務后,調用服務中的方法。例如:音樂播放器。
4)服務與Activity中間的通信
a) 服務的本地調用方法
調用服務的Activity與服務在同一個應用程序中,綁定服務后調用服務中的方法。
b) 服務的遠程方法調用
調用服務的Activity與服務在同一個應用程序中,綁定服務后調用服務中的方法。
context:
它描述的是一個應用程序的環境,即上下文
它類是一個抽象的類,android提供了一個具體的通用實現類contextIml類。
它就像是一個大管家,是一個訪問全局信息的接口。通過它我們可以獲取應用程度 的資源的類,包括一些應用級的操作,如啟動一個activity,發送廣播,接受Intent信息。
Context的繼承關系圖如下圖所示:
總結
以上是生活随笔為你收集整理的Android四大组件(activity task stack)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: jQuery.Event的一些用法
- 下一篇: 看雪KSSD-windows驱动