Android中Intent組件的入門學習心得

什麼是 Intent ?

Intent是Android開發中一個非常重要且常用的類,Intent是一個消息傳遞對象,可以用來從其他應用組件請求操作,使用Intent可以在一個組件中同一APP中的另一個組件或者是啟動另一個APP的組件(這裡所說的組件包括Activity、Service和Broadcast)。

ctivity、service和broadcast receiver之間是通過Intent進行通信的,而另外一個組件Content Provider本身就是一種通信機制,不需要通過Intent。我們來看下面這個圖就知道瞭:

如果Activity1需要和Activity2進行聯系,二者不需要直接聯系,而是通過Intent作為橋梁。通俗來講,Intnet類似於中介、媒婆的角色。

安卓官方對於Intent的介紹

Intent 的類型?

Intent 有兩種類型,分別是 顯式 Intent 和 隱式 Intent 。

顯式 Intent: 通過提供目標應用的軟件包名稱或完全限定的組件類名來指定可處理 Intent 的應用。通常,您會在自己的應用中使用 顯式 Intent 來啟動組件,這是因為您知道要啟動的 Activity 或服務的類名。例如,您可能會啟動您應用內的新 Activity 以響應用戶操作,或者啟動服務以在後臺下載文件。

隱式 Intent: 不會指定特定的組件,而是聲明要執行的常規操作,從而允許其他應用中的組件來處理。例如,如需在地圖上向用戶顯示位置,則可以使用 隱式 Intent,請求另一具有此功能的應用在地圖上顯示指定的位置。使用 隱式 Intent 時,Android 系統通過將 Intent 的內容與在設備上其他應用的清單文件中聲明的 Intent 過濾器 進行比較,從而找到要啟動的相應組件。如果 Intent 與 Intent 過濾器匹配,則系統將啟動該組件,並向其傳遞 Intent 對象。如果多個 Intent 過濾器兼容,則系統會顯示一個對話框,支持用戶選取要使用的應用。

Intent 的組成

intent由組件名稱(Component name)、操作(Action)、數據(Data)、類別(Category)、額外的數據(Extra)和標志(Flag)六個部分組成。

組件名稱 Component name:

組件名稱是要啟動的組件名稱。如果使用的是 顯式 Intent 則必須指定此參數,否則 Intent 無法識別要傳遞給哪個應用組件。不指定此參數則為 隱式 Intent ,系統將根據其他 Intent 信息決定要接受 Intent 的應用組件。如果想要啟動特定的組件,則必須要指定此參數為該組件的名稱。

操作 Action:

操作指定要執行的通用操作的字符串。可以自定義自己的操作,但是通常應該使用由 Intent 類或其他框架類定義的操作常量(例如 ACTION_VIEWACTION_SEND)。

數據 Data:

數據是引用待操作數據或該數據 MIME 類型的 URI 對象。提供的數據類型通常由 Intent 的操作決定。創建 Intent 時,除瞭指定 URI 以外,指定數據類型(其 MIME 類型)往往也很重要。

類別 Category:

類別是一個包含應處理 Intent 組件類型的附加信息的字符串。可以將任意數量的類別描述放入一個 Intent 中,但大多數 Intent 均不需要類別。以下是一些常見類別:

CATEGORY_BROWSABLE

目標 Activity 允許本身通過網絡瀏覽器啟動,以顯示鏈接引用的數據,如圖像或電子郵件。

CATEGORY_LAUNCHER

此類別描述瞭該 Activity 是任務的初始 Activity,當系統啟動時首先啟動此 Activity。

額外的數據 Extra:

攜帶完成請求操作所需的附加信息的鍵值對。正如某些操作使用特定類型的數據 URI 一樣,有些操作也使用特定的 extra。

標志 Flag:

標志在 Intent 類中定義,充當 Intent 的元數據。標志可以指示 Android 系統如何啟動 Activity(例如,Activity 應屬於哪個任務),以及啟動之後如何處理(例如,Activity 是否屬於最近的 Activity 列表)。

顯式 Intent 的使用

首先新建一個 Activity 以及相應的佈局文件。

MyActivity

import androidx.annotation.Nullable;
import android.app.Activity;
import android.os.Bundle;

public class MyActivity extends Activity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.myactivity);
    }
}

myactivity.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"`在這裡插入代碼片`
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MyActivity">
    <TextView
        android:text="這是一個新的頁面"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>

在清單文件 AndroidManifest.xml 中註冊 MyActivity

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.myapplication1">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.MyApplication1">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MyActivity"/>
    </application>

</manifest>

此處android:name中使用 .MyActivity 是為瞭程序在運行時直接將該 name 添加到 package 後,這樣方便程序去尋找此Activity並啟動,也可以將package復制添加到 android:name 中,例如<activity android:name="com.example.myapplication1.MyActivity"/> 。

在 MainActivity 中設定一個按鈕 id 為 startNew ,當按下該按鈕時啟動 MyActivity 。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.startNew).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startActivity(new Intent(MainActivity.this,MyActivity.class));
            }
        });
    }
}

此處在 new Intent(MainActivity.this,MyActivity.class) 中指明瞭要啟動的 Activity 的名稱,所以為顯式 Intent 。

運行效果:

隱式 Intent 的使用

首先在清單文件 AndroidManifest 中修改 MyAcitivity 的相關定義。

<activity
    android:name=".MyActivity"
    android:exported="true">
    <intent-filter>
        //為此intent定義一個新的action名稱
        <action android:name="NewAction"/>
        //若指定category為DEFAULT,則指明此intent的行為方式是Activity
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

修改 MainActivity ,將原本的顯式 Intent 啟動方式改為隱式 Intent ,即通過自定義的 action 名稱來啟動相對應的 Activity 。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.startNew).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //此處使用NewAction調用MyActivity
                startActivity(new Intent("NewAction"));
            }
        });
    }
}

這樣就成功通過隱式 Intent 啟動 MyActivity 。

通常建議將 定義為 “包.intent.action.組件名” 。可以通過在組件中定義靜態變量來更加方便地訪問該組件。例如,public static final String ACTION = "com.example.myapplication1.intent.action.MyActivity";

調用時直接使用 MyActivity.ACTION 即可。

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.startNew).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //此處使用NewAction調用
                startActivity(new Intent(MyActivity.ACTION));
            }
        });
    }
}

運行效果與顯式 Intent 相同。

通過隱式 Intent ,組件可以對不同APP之間的組件進行訪問。如果想讓本應用的組件可以被其他的應用進行訪問,則需要對 activity 標簽加上一個屬性 android:exported ,當 android:exported 為 true 時,本組件可以被其他應用組件訪問,為 false 時則不可被其他應用訪問,並彈出異常警告。可以在啟動其他應用組件時加上異常捕獲語句,例如,

public void onClick(View view) {
    try {
        startActivity(new Intent(MyActivity.ACTION));
    }catch (Exception e){
        Toast.makeText(MainActivity.this,"無法啟動指定的Activity",Toast.LENGTH_SHORT).show();
    }
}

本文大部分參考瞭Android中對Intent部分的描述,希望本文對大傢更好地使用Intent對象有所幫助。

總結

到此這篇關於Android中Intent組件入門學習的文章就介紹到這瞭,更多相關Android Intent組件學習內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: