日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android四大组件(activity task stack)

發布時間:2023/12/20 Android 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android四大组件(activity task stack) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Activity

生命周期

  • onCreate:創建活動。此時會把頁面布局加載進內存,進入了初始狀態。
  • onStart:開啟活動。此時會把活動頁面顯示在屏幕上,進入了就緒狀態。
  • onResume:恢復活動。此時活動頁面進入活躍狀態,能夠與用戶正常交互,例如允許響應用戶的點擊動作、允許用戶輸入文字等。
  • onPause:暫停活動。此時活動頁面進入暫停狀態(也就是退回就緒狀態),無法與用戶正常交互。
  • onStop:停止活動。此時活動頁面將不在屏幕上顯示。 onDestroy:銷毀活動。此時回收活動占用的系統資源,把頁面從內存中清除掉。
  • onRestart:重啟活動。處于停止狀態的活動,若想重新開啟的話,無須經歷onCreate的重復創建過程,而是走onRestart的重啟過程。

特殊的聲明周期:

  • onNewIntent

在singleTask和singleTop啟動模式下,啟動一個已存在的Activity,該Activity的生命周期會如何回調
activity1(singleTask)

[activity1]---task1---foreground

再啟動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: onResume

Activity的啟動模式

首先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 ActSendActiviy extends AppCompatActivity implements View.OnClickListener {private TextView tvContent;private Button btSend;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_send_activiy);initView();btSend.setOnClickListener(this);}private void initView() {tvContent = (TextView) findViewById(R.id.tv_Content);btSend = (Button) findViewById(R.id.bt_send);}@Overridepublic void onClick(View v) {String content = tvContent.getText().toString();Intent intent = new Intent(this, ActReviceActivity.class);Bundle bundle = new Bundle();bundle.putString("time", DateUtil.getNowTime());bundle.putString("content",content);intent.putExtras(bundle);startActivity(intent);} }

消息接收類

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進行消息的傳遞

  • 消息發送類
public class ActSendActiviy extends AppCompatActivity implements View.OnClickListener {private TextView tvContent;private Button btSend;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_act_send_activiy);initView();btSend.setOnClickListener(this);}private void initView() {tvContent = (TextView) findViewById(R.id.tv_Content);btSend = (Button) findViewById(R.id.bt_send);}@Overridepublic void onClick(View v) {String content = tvContent.getText().toString();Intent intent = new Intent(this, ActReviceActivity.class); // Bundle bundle = new Bundle(); // bundle.putString("time", DateUtil.getNowTime()); // bundle.putString("content",content); // intent.putExtras(bundle);intent.putExtra("time",DateUtil.getNowTime());intent.putExtra("content",content);startActivity(intent);} }
  • 消息接收類
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"));String showInf = String.format("傳遞消息時間 %s \n 傳遞內容 %s \n ",intent.getStringExtra("time"), intent.getStringExtra("content"));initView();tvReceive.setText(showInf);}private void initView() {tvReceive = (TextView) findViewById(R.id.tv_receive);} }

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

    // 注冊

    // todo 優先級 默認的優先級是多少 OrderAReceiver orderAReceiver = new OrderAReceiver(); IntentFilter intentFilterA = new IntentFilter(orderBroadCastReceiver); intentFilterA.setPriority(10); registerReceiver(orderAReceiver,intentFilterA);// todo 優先級 默認的優先級是多少 OrderBReceiver orderBReceiver = new OrderBReceiver(); IntentFilter intentFilterB = new IntentFilter(orderBroadCastReceiver); intentFilterB.setPriority(8); registerReceiver(orderAReceiver,intentFilterB);// 取消注冊 unregisterReceiver(orderAReceiver); unregisterReceiver(orderBReceiver);

    // 接收
    registerReceiver 輸入參數分別為BroadcastReceiver receiver, IntentFilter filter

    public class OrderAReceiver extends BroadcastReceiver {private String TAG = "HHH.OrderAReceiver";@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(MainActivity.orderBroadCastReceiver)){Log.i(TAG, "OrderAReceiver onReceive...");}} }```public class OrderBReceiver extends BroadcastReceiver {private String TAG = "HHH.OrderBReceiver";@Overridepublic void onReceive(Context context, Intent intent) {if (intent != null && intent.getAction().equals(MainActivity.orderBroadCastReceiver)){Log.i(TAG, "OrderBReceiver onReceive...");}} } // 結果```java 2022-06-17 17:02:05.777 21164-21164/cn.jj.myapplication I/HHH.OrderAReceiver: OrderAReceiver onReceive... 2022-06-17 17:02:05.779 21164-21164/cn.jj.myapplication I/HHH.OrderBReceiver: OrderBReceiver onReceive...

    靜態廣播

    發送

    // 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)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。