Android入門筆記

Android筆記

前言: 本筆記基於MacOS系統

學習意圖: 爲了做逆向打基礎

筆記內容: android的重要組件和功能(不死扣細節)

學習目標: 拿到一套android代碼可以通過讀代碼方式可以理清自己需要的部分功能的實現邏輯.

附加目標: 當需要寫android時,可以根據自己的需要快速定位開發

軟件(flutter、dart和vscode可以不裝)

jdk + flutter + android studio + dart+ vscode(機子性能好可以選android studio + android SDK + jdk)

安裝

1、jdk 12

mac自帶,建議自己配置一個java8,新版本總會有各種不兼容

2、flutter sdk(如果不想寫原生android的話)

2.1 下載

地址:https://flutter.dev/docs/get-started/install

解壓到指定目錄: 如 ~

2.2 環境配置

官方教程: https://flutter.dev/docs/get-started/install/macos

在~/.zshrc(或者.bashrc、.bash_profile) 中最後一行添加

export PATH="$PATH:~/flutter/bin"

重新source ~/.zshrc

3、vscode(機子性能不足,用vscode寫)

https://vscode.cdn.azure.cn/stable/26076a4de974ead31f97692a0d32f90d735645c0/VSCode-darwin-stable.zip

下載完畢後,安裝flutter和dart

dart安裝、配置

brew install dart
vim ~/.zshrc
# 最後兩行添加,其中DART_HOME爲dart的安裝路徑
export DART_HOME=/usr/local/Cellar/dart/2.8.0-dev.0.0/bin
export PATH="${DART_HOME}:${PATH}"

4、AS(android studio)

4.1 下載

android studio下載

http://down-ww3.newasp.net/pcdown/big/android_studio_ide_mac.dmg

下載完畢後,直接安裝,遇到設置代理會報紅,取消即可.後面就是next -> next…

創建項目,項目命名規則爲駝峯式,next…創建完一般情況下會報錯,暫時不管,到AS配置步驟解決

Android sdk下載

https://dl.google.com/android/repository/tools_r25.2.3-macosx.zip

# 解壓後,進入tools目錄
cd tools
.android sdk

勾選Extras,然後下載.

gradle配置

cd ~
vim .zshrc(或者.bashrc)
# 在最後添加
# 配置gradle環境,GRADLE_HOME路徑爲AS路徑下gradle下的gradle
export GRADLE_HOME=/Applications/Android\ Studio.app/Contents/gradle/gradle-4.4
export PATH=${PATH}:${GRADLE_HOME}/bin
# 退出保存 :wq
# 然後測試
gradle -version

------------------------------------------------------------
Gradle 4.4
------------------------------------------------------------

Build time:   2017-12-06 09:05:06 UTC
Revision:     cf7821a6f79f8e2a598df21780e3ff7ce8db2b82

Groovy:       2.4.12
Ant:          Apache Ant(TM) version 1.9.9 compiled on February 2 2017
JVM:          1.8.0_231 (Oracle Corporation 25.231-b11)
OS:           Mac OS X 10.14.4 x86_64

AS配置

1、打開文件目錄下Gradle Scripts -> build.gradle

全選修改(設置國內鏡像源)

buildscript {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.4.0'
    }
}

allprojects {
    repositories {
        maven { url 'https://maven.aliyun.com/repository/google' }
        maven{ url 'https://maven.aliyun.com/repository/jcenter'}
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

2、打開文件目錄下Gradle Scripts -> gradle-wrapper.propertiies

#Thu Jan 02 10:38:22 CST 2020
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

3、File -> Project structure

勾選 Idk location下的Use embezzlementdded JDK

4、Preferences -> Build,Execution,Deployment -> Gradle -> Android Studi

勾選Enable embedded Maven repository

5、Try again

6、創建虛擬設備(可以直接連接手機)

在這裏插入圖片描述

在這裏插入圖片描述

在這裏插入圖片描述
在這裏插入圖片描述

7、運行第一個程序
在這裏插入圖片描述
在這裏插入圖片描述

筆記指南

一個完整的安卓系統大致上由一個界面使用各種佈局方式承載各種組件,並且在組件上綁定各種事件,通過與用戶與組件的交互,激活與事件綁定的後臺邏輯,然後反饋給用戶,實現一個app的各種功能.

四大應用組件

  • Activity
  • 服務
  • 廣播接收器
  • 內容提供程序

Activity(界面)、服務(調度器,大管家)、廣播接收器(全局消息)、內容提供器(數據庫) (總結)

Activity

Activity 是與用戶交互的入口點。它表示擁有界面的單個屏幕。例如,電子郵件應用可能有一個顯示新電子郵件列表的 Activity、一個用於撰寫電子郵件的 Activity 以及一個用於閱讀電子郵件的 Activity。儘管這些 Activity 通過協作在電子郵件應用中形成一種緊密結合的用戶體驗,但每個 Activity 都獨立於其他 Activity 而存在。因此,其他應用可以啓動其中任何一個 Activity(如果電子郵件應用允許)。例如,相機應用可以啓動電子郵件應用內用於撰寫新電子郵件的 Activity,以便用戶共享圖片。Activity 有助於完成系統和應用程序之間的以下重要交互:
		追蹤用戶當前關心的內容(屏幕上顯示的內容),以確保系統繼續運行託管Activity 的進程。
		瞭解先前使用的進程包含用戶可能返回的內容(已停止的 Activity),從而更優先保留這些進程。
		幫助應用處理終止其進程的情況,以便用戶可以返回已恢復其先前狀態的 Activity。
	提供一種途徑,讓應用實現彼此之間的用戶流,並讓系統協調這些用戶流。(此處最經典的示例是共享。)

服務

服務是一個通用入口點,用於因各種原因使應用在後臺保持運行狀態。它是一種在後臺運行的組件,用於執行長時間運行的操作或爲遠程進程執行作業。服務不提供界面。例如,當用戶使用其他應用時,服務可能會在後臺播放音樂或通過網絡獲取數據,但這不會阻斷用戶與 Activity 的交互。諸如 Activity 等其他組件可以啓動服務,使該服務運行或綁定到該服務,以便與其進行交互。事實上,有兩種截然不同的語義服務可以告知系統如何管理應用:已啓動服務會告知系統使其運行至工作完畢。此類工作可以是在後臺同步一些數據,或者在用戶離開應用後繼續播放音樂。在後臺同步數據或播放音樂也代表了兩種不同類型的已啓動服務,而這些服務可以修改系統處理它們的方式:
		音樂播放是用戶可直接感知的服務,因此,應用會向用戶發送通知,表明其希望成爲前臺,從而告訴系統此消息;在此情況下,系統明白它應盡全力維持該服務進程運行,因爲進程消失會令用戶感到不快。
		通常,用戶不會意識到常規後臺服務正處於運行狀態,因此係統可以更自由地管理其進程。如果系統需要使用 RAM 來處理用戶更迫切關注的內容,則其可能允許終止服務(然後在稍後的某個時刻重啓服務)。
綁定服務之所以能運行,原因是某些其他應用(或系統)已表示希望使用該服務。從根本上講,這是爲另一個進程提供 API 的服務。因此,系統會知曉這些進程之間存在依賴關係,所以如果進程 A 綁定到進程 B 中的服務,系統便知道自己需使進程 B(及其服務)爲進程 A 保持運行狀態。此外,如果進程 A 是用戶關心的內容,系統隨即也知道將進程 B 視爲用戶關心的內容。由於存在靈活性(無論好壞),服務已成爲非常有用的構建塊,並且可實現各種高級系統概念。動態壁紙、通知偵聽器、屏幕保護程序、輸入方法、無障礙功能服務以及衆多其他核心系統功能均可構建爲在其運行時由應用實現、系統綁定的服務。

廣播接收器

藉助廣播接收器組件,系統能夠在常規用戶流之外向應用傳遞事件,從而允許應用響應系統範圍內的廣播通知。由於廣播接收器是另一個明確定義的應用入口,因此係統甚至可以向當前未運行的應用傳遞廣播。例如,應用可通過調度提醒來發布通知,以告知用戶即將發生的事件。而且,通過將該提醒傳遞給應用的廣播接收器,應用在提醒響起之前即無需繼續運行。許多廣播均由系統發起,例如,通知屏幕已關閉、電池電量不足或已拍攝照片的廣播。應用也可發起廣播,例如,通知其他應用某些數據已下載至設備,並且可供其使用。儘管廣播接收器不會顯示界面,但其可以創建狀態欄通知,在發生廣播事件時提醒用戶。但廣播接收器更常見的用途只是作爲通向其他組件的通道,旨在執行極少量的工作。例如,它可能會根據帶 JobScheduler 的事件調度 JobService 來執行某項工作

廣播接收器作爲 BroadcastReceiver 的子類實現,並且每條廣播都作爲 Intent 對象進行傳遞。如需瞭解詳細信息,請參閱 BroadcastReceiver 類。

內容提供程序

內容提供程序管理一組共享的應用數據,您可以將這些數據存儲在文件系統、SQLite 數據庫、網絡中或者您的應用可訪問的任何其他持久化存儲位置。其他應用可通過內容提供程序查詢或修改數據(如果內容提供程序允許)。例如,Android 系統可提供管理用戶聯繫人信息的內容提供程序。因此,任何擁有適當權限的應用均可查詢內容提供程序(如 ContactsContract.Data),以讀取和寫入特定人員的相關信息。我們很容易將內容提供程序看作數據庫上的抽象,因爲其內置的大量 API 和支持時常適用於這一情況。但從系統設計的角度看,二者的核心目的不同。對系統而言,內容提供程序是應用的入口點,用於發佈由 URI 架構識別的已命名數據項。因此,應用可以決定如何將其包含的數據映射到 URI 命名空間,進而將這些 URI 分發給其他實體。反之,這些實體也可使用分發的 URI 來訪問數據。在管理應用的過程中,系統可以執行以下特殊操作:
		分配 URI 無需應用保持運行狀態,因此 URI 可在其所屬的應用退出後繼續保留。當系統必須從相應的 URI 檢索應用數據時,系統只需確保所屬應用仍處於運行狀態。
		這些 URI 還會提供重要的細粒度安全模型。例如,應用可將其所擁有圖像的 URI 放到剪貼板上,但將其內容提供程序鎖定,以便其他應用程序無法隨意訪問它。當第二個應用嘗試訪問剪貼板上的 URI 時,系統可允許該應用通過臨時的 URI 授權來訪問數據,這樣便只能訪問 URI 後面的數據,而非第二個應用中的其他任何內容。
內容提供程序也適用於讀取和寫入您的應用不共享的私有數據。

聲明組件

  • Activity — 元素
  • 服務 — 元素
  • 廣播接收器 — 元素
  • 內容提供程序 — 元素

佈局

  • LinearLayout
  • RelativeLayout
  • TableLayout
  • FrameLayout
  • AbsoluteLayout(待刪除,不建議使用)
  • GridLyout

佈局就是按照設計圖選擇最合適的排版模板(總結)

LinearLayout

線性佈局是Android中較爲常用的佈局方式,使用LinearLayout標籤。線性佈局主要有兩種形式,一種是水平線性佈局,一種是垂直線性佈局。需要注意的是Android的線性佈局不會換行,當組件一個挨着一個地排列到頭之後,剩下的組件將不會被顯示出來。

RelativeLayout

相對佈局,使用RelativeLayout標籤。相對佈局通常有兩種形式,一種是相對於容器而言的,一種是相對於控件而言的。

TableLayout

表格佈局就是讓控件以表格的形式來排列控件,只要將控件放在單元格中,控件就可以整齊地排列,使用TableLayout標籤。

TableLayout繼承了 LinearLayout,因此它的本質依然是線性佈局管理器。每次向TableLayout中添加一個TableRow,該TableRow就是一個表格行,TableRow也是容器,因此它也可以不斷地添加其他組件,每添加一個子組件該表格就增加一列。如果直接向TableLayout中添加組件,那麼這個組件將直接佔用一行。

在表格佈局中,列的寬度由該列中最寬的那個單元格決定,整個表格佈局的寬度則取決於父容器的寬度(默認總是佔滿父容器本身)。

FrameLayout

幀佈局爲每個加入其中的控件創建一個空白區域(稱爲一幀,每個控件佔據一 幀)。釆用幀佈局方式設計界面時,只能在屏幕左上角顯示一個控件,如果添加多個控件,這些控件會按照順序在屏幕的左上角重疊顯示。

AbsoluteLayout(待刪除,不建議使用)

絕對佈局需要通過指定x、y座標來控制每一個控件的位置,放入該佈局的控件需要通過android:layout_x和android:layout_y 兩個屬性指定其準確的座標值,並顯示在屏幕上。

需要注意的是當使用AbsoluteLayout作爲佈局容器時,佈局容器不再管理子組件的位置和大小,都需要開發人員自己控制。使用絕對佈局時,每個子組件都可指定如下兩個XML屬性。

GridLyout

網格佈局實現了控件的交錯顯示,能夠避免因佈局嵌套對設備性能的影響,更利於自由佈局的開發。網格佈局用一組無限細的直線將繪圖區域分成行、列和單元,並指定控件的顯示區域和控件在該區域的顯示方式

View

部分組件

  • TextView
  • EditText
  • Button
  • CheckBox
  • RadioBox
  • Boggle
  • Switch
  • ImageView
  • ImageButton
  • ZoomButton

View實際上就是界面展示的各種組件,組件配合佈局構成了用戶展示界面(總結)

Android 應用的界面 (UI) 以佈局和微件的層次結構形式構建而成。佈局是 ViewGroup 對象,即控制其子視圖在屏幕上的放置方式的容器。微件是 View 對象,即按鈕和文本框等界面組件。

ViewGroup
ViewGroup
View
View
View
View

TextView

  • 功能: 在界面上顯示文本

  • 父類: View

  • 子類: EditText、Button

EditText

  • 功能: 接收用戶輸入
  • 父類: TextView

Button

  • 功能: 綁定點擊事件,實現某些邏輯
  • 父類: TextView

CheckBox

  • 功能: 多選

RadioBox

  • 功能: 單選

Boggle

  • 功能: 選中

Switch

  • 功能: 切換

ImageView

  • 功能: 展示圖片

ImageButton

  • 功能: 帶有圖片的按鈕

ZoomButton

  • 放大縮曉

事件 (重要)

Android事件處理方式分兩種方式:

  • 基於監聽的事件處理
  • 基於回調的事件處理

**觸發事件後,事件傳播流程,用戶界面的各個View(組件)配合事件構成app的各種功能(總結): **

注意事項
觸發事件
返回true
返回true
返回false
返回false
事件監聽器
事件監聽處理
事件回調處理
結束
結束
事件源

1、基於監聽的事件處理

Event Source (事件源):事件發生的場所,通常就是各個組件,例如按鈕、窗口、菜單等。

Event (事件):事件封裝了界面組件上發生的特定事情(通常就是一次用戶操作)。如果程序需要獲得界面組件上所發生事件的相關信息,一般通過Event對象來取得。

Event Listener (事件監聽器):負責監聽事件源所發生的事件,並對各種事件做出相應的響應。

當用戶按下一個按鈕或者單擊某個菜單項時,這些動作就會激發一個相應的事件,該事件就會觸發事件源上註冊的事件監聽器(特殊的Java對象),事件監聽器調用對應的事件處理器 (事件監聽器裏的實例方法)來做出相應的響應。

每個組件均可以針對特定的事件指定一個事件監聽器,每個事件監聽器也可監聽一個或多個事件源。因爲同一個事件源上可能發生多種事件,委派式事件處理方式可以把事件源上所有可能發生的事件分別授權給不同的事件監聽器來處理;同時也可以讓一類事件都使用同一個事件監聽器來處理。

在基於監聽的事件處理模型中,事件監聽器必須實現事件監聽器接口,Android爲不同的界面組件提供了不同的監聽器接口,這些接口通常以內部類的形式存在。以View類爲例,它包含了如下幾個內部接口。

View.OnClickListener:單擊事件的事件監聽器必須實現的接口。

View.OnCreateContextMenu Listener :創建上下文菜單事件的事件監聽器必須實現的接口。

View.onFocusChangeListener:焦點改變事件的事件監聽器必須實現的接口。

View.OnKeyListener:按鍵事件的事件監聽器必須實現的接口。

View.OnLongClickListener:長按事件的事件監聽器必須實現的接口。

View.OnTouchListener:觸摸事件的事件監聽器必須實現的接口。

實現形式:

  • 使用匿名內部類作爲事件監聽器
  • 使用內部類作爲事件監聽器
  • 使用外部類作爲事件監聽器
  • 直接使用Activity作爲事件監聽器
  • 直接綁定到標籤

實例:

layout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="用戶名: "
        android:textSize="16sp" />

    <EditText
        android:id="@+id/name_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入用戶名"/>

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="密碼: "
        android:textSize="16sp"/>

    <EditText
        android:id="@+id/pwd_et"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:hint="請輸入密碼"/>

    <Button
        android:id="@+id/login_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="普通按鈕"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {
    EditText mNameEt = null;
    EditText mPasswordEt = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout);
        // 獲取界面組件
        mNameEt = findViewById(R.id.name_et);
        mPasswordEt = findViewById(R.id.pwd_et);
        Button btnClick =  findViewById(R.id.login_btn);
        btnClick.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view){
                String name = mNameEt.getText().toString();
                String password = mPasswordEt.getText().toString();
                Toast.makeText(MainActivity.this, "按鈕被點擊" + name + password,
                        Toast.LENGTH_SHORT).show();
            }
        });
    }

2、基於回調的事件處理

對於基於回調的事件處理模型來說,事件源與事件監聽器是統一的,或者說事件監聽器完全消失了。當用戶在GUI組件上激發某個事件時,組件自己特定的方法將會負責處理該事件。

爲了實現回調機制的事件處理,Android爲所有GUI組件都提供了一些事件處理的回調方法,以View爲例,該類包含如下方法。

boolean onKeyDown(int keyCode, KeyEvent event):當用戶在該組件上按下某個按鍵時觸發該方法。

boolean onKeyLongPress(int keyCode, KeyEvent event):當用戶在該組件上長按某個按鍵時觸發該方法。

boolean onKeyShortcut(int keyCode, KeyEvent event):當一個鍵盤快捷鍵事件發生時觸發該方法。

boolean onKeyUp(int keyCode, KeyEvent event):當用戶在該組件上鬆開某個按鍵時觸發該方法。

boolean onTouchEvent(MotionEvent event):當用戶在該組件上觸發觸摸屏事件時觸發該方法。

boolean onTrackballEvent(MotionEvent event):當用戶在該組件上觸發軌跡球事件時觸發該方法。

void onFocusChanged(boolean gainFocus, int direction, Rect previously FocusedRect):當組件的焦點發生改變時觸發該方法。和前面的6個方法不同,該方法只能夠在View中重寫。

Android系統事件響應

對Android系統事件的響應處理,實際上時對Configuration類的處理,系統事件響應主要解決app共享系統資源問題(總結)

在開發Android應用時,有時候可能需要讓應用程序隨系統設置而進行調整,比如判斷系統的屏幕方向、判斷系統方向的方向導航設備等。除此之外,有時候可能還需要讓應用程序監聽系統設置的更改,對系統設置的更改做出響應.

Configuration類專門用於描述手機設備上的配置信息,這些配置信息既包括用戶特定的配置項,也包括系統的動態設備配置。程序可調用Activity的如下方法來獲取系統的Configuration對象:

Configurationcfg=getResources().getConfiguration();

一旦獲得了系統的Configuration對象,就可以使用該對象提供的如下常用屬性來獲取系統的配置信息。

常用的配置常量

densityDpi:屏幕密度。

fontScale:當前用戶設置的字體的縮放因子。

hardKeyboardHidden:判斷硬鍵盤是否可見,有兩個可選值:

      HARDKEYBOARDHIDDEN_NO,值爲十六進制的0。

      HARDKEYBOARDHIDDEN_YES,值爲十六進制的1。

keyboard:獲取當前關聯額鍵盤類型:該屬性的返回值:

      KEYBOARD_12KEY:只有12個鍵的小鍵盤。

      KEYBOARD_NOKEYS:無鍵盤。

      KEYBOARD_QWERTY:普通鍵盤。

keyboardHidden:該屬性返回一個boolean值用於標識當前鍵盤是否可用。該屬性不僅會判斷系統的硬件鍵盤,也會判斷系統的軟鍵盤(位於屏幕)。

locale:獲取用戶當前的語言環境。

mcc:獲取移動信號的國家碼。

mnc:獲取移動信號的網絡碼。

ps:國家代碼和網絡代碼共同確定當前手機網絡運營商。

navigation:判斷系統上方向導航設備的類型。該屬性的返回值:

      NAVIGATION_NONAV:無導航。

      NAVIGATION_DPAD:DPAD導航。

      NAVIGATION_TRACKBALL:軌跡球導航。

      NAVIGATION_WHEEL:滾輪導航。

orientation:獲取系統屏幕的方向。該屬性的返回值:

      ORIENTATION_LANDSCAPE:橫向屏幕。

      ORIENTATION_PORTRAIT:豎向屏幕。

screenHeightDp,screenWidthDp:屏幕可用高和寬,用dp表示。

touchscreen:獲取系統觸摸屏的觸摸方式。該屬性的返回值:

      TOUCHSCREEN_NOTOUCH:無觸摸屏。

      TOUCHSCREEN_STYLUS:觸摸筆式觸摸屏。

      TOUCHSCREEN_FINGER:接收手指的觸摸屏。

如果程序需要監聽系統設置的更改,則可以考慮重寫Activity的onConfigurationChanged (Configuration newConfig)方法,該方法是一個基於回調的事件處理方法:當系統設置發生更改時,該方法會被自動觸發。

當然,爲了讓Activity能監聽系統配置更改的事件,需要在配置Activity時指定 androidiconfigChanges 屬性,該屬性可以支持 mcc、mnc、locale、touchscreen、keyboard、keyboardHidden、navigation、orientation、screenLayout、uiMode、screenSize、smallestScreenSize、fontScale等屬性值。

Activity

Activity是Android組件中最基本也是最常用的一種組件,在一個Android應用中,一個Activity通常就是一個單獨的屏幕。每一個Activity都被實現爲一個獨立的類,並且繼承於Activity這個基類。

Activity生命週期
在這裏插入圖片描述

實例:

鏈接:https://pan.baidu.com/s/1FB12ZvqlAB0TE4PAw-fxPg 密碼:pq07

Task

Android中對於Activity的管理採用Task的概念,在應用程序中每個被創建的Activity都保存在回退堆棧內,每次後退就將棧頂的Activity取出.

Service

Service是Android提供一個允許長時間留駐後臺的一個組件,最常見的 用法就是做輪詢操作,同時,Service提供跨進程通信組件!

Service生命週期

在這裏插入圖片描述

StartService啓動Service

首次啓動會創建一個Service實例,依次調用onCreate()和onStartCommand()方法,此時Service 進入運行狀態,如果再次調用StartService啓動Service,將不會再創建新的Service對象, 系統會直接複用前面創建的Service對象,調用它的onStartCommand()方法!
但這樣的Service與它的調用者無必然的聯繫,就是說當調用者結束了自己的生命週期, 但是隻要不調用stopService,那麼Service還是會繼續運行的!
無論啓動了多少次Service,只需調用一次StopService即可停掉Service

BindService啓動Service

當首次使用bindService綁定一個Service時,系統會實例化一個Service實例,並調用其onCreate()和onBind()方法,然後調用者就可以通過IBinder和Service進行交互了,此後如果再次使用bindService綁定Service,系統不會創建新的Sevice實例,也不會再調用onBind()方法,只會直接把IBinder對象傳遞給其他後來增加的客戶端!
如果我們解除與服務的綁定,只需調用unbindService(),此時onUnbind和onDestory方法將會被調用!這是一個客戶端的情況,假如是多個客戶端綁定同一個Service的話,情況如下 當一個客戶完成和service之間的互動後,它調用 unbindService() 方法來解除綁定。當所有的客戶端都和service解除綁定後,系統會銷燬service。(除非service也被startService()方法開啓)
另外,和上面那張情況不同,bindService模式下的Service是與調用者相互關聯的,可以理解爲 “一條繩子上的螞蚱”,要死一起死,在bindService後,一旦調用者銷燬,那麼Service也立即終止!
通過BindService調用Service時調用的Context的bindService的解析 bindService(Intent Service,ServiceConnection conn,int flags)
service:通過該intent指定要啓動的Service
conn:ServiceConnection對象,用戶監聽訪問者與Service間的連接情況, 連接成功回調該對象中的onServiceConnected(ComponentName,IBinder)方法; 如果Service所在的宿主由於異常終止或者其他原因終止,導致Service與訪問者間斷開 連接時調用onServiceDisconnected(CompanentName)方法,主動通過unBindService() 方法斷開並不會調用上述方法!
flags:指定綁定時是否自動創建Service(如果Service還未創建), 參數可以是0(不自動創建),BIND_AUTO_CREATE(自動創建)

StartService啓動Service後bindService綁定

如果Service已經由某個客戶端通過StartService()啓動,接下來由其他客戶端 再調用bindService()綁定到該Service後調用unbindService()解除綁定最後在 調用bindService()綁定到Service的話,此時所觸發的生命週期方法如下:
onCreate( )->onStartCommand( )->onBind( )->onUnbind( )->onRebind( )
**PS:**前提是:onUnbind()方法返回true!!! 這裏或許部分讀者有疑惑了,調用了unbindService後Service不是應該調用 onDistory()方法麼!其實這是因爲這個Service是由我們的StartService來啓動的 ,所以你調用onUnbind()方法取消綁定,Service也是不會終止的!
得出的結論: 假如我們使用bindService來綁定一個啓動的Service,注意是已經啓動的Service!!! 系統只是將Service的內部IBinder對象傳遞給Activity,並不會將Service的生命週期 與Activity綁定,因此調用unBindService( )方法取消綁定時,Service也不會被銷燬!

IntentService

IntentService是繼承與Service並處理異步請求的一個類,在IntentService中有 一個工作線程來處理耗時操作,請求的Intent記錄會加入隊列

當需要有耗時的操作,就放在後臺進行,此時需要使用IntentService(總結)

客戶端通過startService(Intent)來啓動IntentService; 我們並不需要手動地區控制IntentService,當任務執行完後,IntentService會自動停止; 可以啓動IntentService多次,每個耗時操作會以工作隊列的方式在IntentService的 onHandleIntent回調方法中執行,並且每次只會執行一個工作線程,執行完一,再到二這樣!

Binder

Binder用來實現Android跨進程通信的一種機制,也是Android程序中的一個類.

Binder流程:
在這裏插入圖片描述

BroadcastReceiver

廣播,相當於一個全局的事件監聽器和消息發送器.

ContentProvider

在這裏插入圖片描述

自定義ContentProvider
在這裏插入圖片描述

通過ContentObserver監聽ContentProvider的數據變化

在這裏插入圖片描述

Intent

1.顯式Intent與隱式Intent的區別

  • 顯式Intent:通過組件名指定啓動的目標組件,比如startActivity(new Intent(A.this,B.class)); 每次啓動的組件只有一個~
  • 隱式顯式Intent:不指定組件名,而指定Intent的Action,Data,或Category,當我們啓動組件時, 會去匹配AndroidManifest.xml相關組件的Intent-filter,逐一匹配出滿足屬性的組件,當不止一個滿足時, 會彈出一個讓我們選擇啓動哪個的對話框~

2.Intent的七個屬性

  1. ComponentName
    在這裏插入圖片描述

2)Action
在這裏插入圖片描述

3)Category
在這裏插入圖片描述

  1. Data,Type
    在這裏插入圖片描述

5)Extras
在這裏插入圖片描述

6)Flags
在這裏插入圖片描述

3 隱式Intent
在這裏插入圖片描述

數據讀寫

文件操作模式
在這裏插入圖片描述

SharedPreferences保存用戶偏好參數
在這裏插入圖片描述

筆記來源: w3cschool、簡書、CSDN

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章