當(dāng)前位置:首頁 > IT技術(shù) > 移動(dòng)平臺(tái) > 正文

Android開發(fā)——四大組件之Activity
2021-09-05 09:10:20

<1>關(guān)于Activity和AndroidManifest

我們AS項(xiàng)目里的AndroidManifest.xml文件其實(shí)就是一個(gè)清單文件,用于描述我們的項(xiàng)目?jī)?nèi)容

其中包含了一些Application、activity、包名等信息,還包括一些權(quán)限的聲明(例如在數(shù)據(jù)存儲(chǔ)時(shí)使用SD卡讀寫的權(quán)限聲明)

四大組件也都需要在這里注冊(cè)之后才能使用

?

Application就代表一個(gè)應(yīng)用程序,其中可以包含四大組件

而Activity是用于處理用戶操作,與用戶進(jìn)行交互的(可以理解為一個(gè)容器,一個(gè)窗口,主要用于承載UI內(nèi)容)

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

//這兩行就是設(shè)置權(quán)限,允許外置存儲(chǔ)卡讀寫操作 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  //一個(gè)application就代表了一個(gè)應(yīng)用程序 <application android:allowBackup="true" //允許系統(tǒng)備份 android:icon="@mipmap/ic_launcher" //設(shè)置應(yīng)用的桌面圖標(biāo)(這些圖標(biāo)存儲(chǔ)在res文件夾的mipmap里的lc_launcher下) android:label="@string/app_name" //設(shè)置應(yīng)用程序的名稱(它存儲(chǔ)在res文件夾的values下的strings里) android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" //支持從右到左 android:theme="@style/Theme.AndroidActivityDemo"> //用于控制樣式(它存儲(chǔ)在res文件夾的values下的themes里) <activity android:name=".MainActivity" //四大組件的靜態(tài)注冊(cè)都要這樣 android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

?

如何在一個(gè)Application中再新建一個(gè)activity呢?(即如何再新建一個(gè)UI窗口)

——首先新建一個(gè)類SecondActivity,這個(gè)類繼承Activity

——重寫其中的onCreate()方法

——然后再新建一個(gè)布局activity_second,在SecondActivity類中setContentView()顯示這個(gè)布局

——最后要使這個(gè)新的Activity可以使用,需要在配置列表里注冊(cè)一下

可以看到,在一個(gè)application中注冊(cè)了有兩個(gè)activity,一個(gè)標(biāo)簽設(shè)置為“第一個(gè)ActivityDemo”,另一個(gè)設(shè)置為“第二個(gè)ActivityDemo”,同時(shí)給了兩個(gè)intent-filter,都聲明的是主入口

所以最終的結(jié)果是,在手機(jī)中有兩個(gè)app圖標(biāo),都可以打開這個(gè)程序,分別是這個(gè)程序的兩個(gè)界面

?

<2>利用顯式意圖來實(shí)現(xiàn)界面跳轉(zhuǎn)

(顯式Intent:按名稱(完全限定類名)指定要啟動(dòng)的組件)

用一個(gè)案例來學(xué)習(xí)顯式意圖的界面跳轉(zhuǎn)(目標(biāo)是在主界面輸入賬號(hào)和密碼,點(diǎn)擊登錄按鍵后,跳轉(zhuǎn)到另一個(gè)界面,并在其中顯示我們輸入的賬號(hào)和密碼)

——首先,在MainActivity中和原來一樣,通過id找到我們輸入的賬號(hào)和密碼

——然后判斷賬號(hào)和密碼是否為空,如果不為空,則創(chuàng)建一個(gè)意圖對(duì)象 Intent ,把我們的賬號(hào)和密碼的值存儲(chǔ)到這個(gè)對(duì)象里 putExtra()方法,存儲(chǔ)了鍵值對(duì)

——調(diào)用startActivity()方法進(jìn)行界面的跳轉(zhuǎn)

——新建一個(gè)類SecondActivity,繼承Activity并重寫其中的onCreate()方法

——這個(gè)activity記得要在配置清單中聲明一下才能使用

——最后在SecondActivity類中的onCreate方法里,getIntent()得到第一個(gè)界面中我們創(chuàng)建的意圖對(duì)象,然后獲取其中的內(nèi)容并顯示

——最終效果如下

?

<3>利用隱式意圖來實(shí)現(xiàn)界面跳轉(zhuǎn)

(隱式Intent:不會(huì)指定特定的組件,而是聲明要執(zhí)行的常規(guī)操作,從而允許其他應(yīng)用中的組件來處理它)

隱式意圖實(shí)現(xiàn)界面跳轉(zhuǎn)的方式和顯式差不多,主要差別就是創(chuàng)建Intent的方法

?

<4>區(qū)別

顯式意圖:也就是可以直接看到我們要跳轉(zhuǎn)到的目標(biāo)組件,例如之前要從MainActivity跳轉(zhuǎn)到SecondActivity,用的是new Intent(this, SecondActivity.class);在這里面我們直接就可以看到目標(biāo)組件的名稱(一般是用于應(yīng)用內(nèi)組件的跳轉(zhuǎn))

隱式意圖:用于跳轉(zhuǎn)到第三方應(yīng)用(一般是用于各個(gè)應(yīng)用之間的跳轉(zhuǎn))

?

——?jiǎng)?chuàng)建顯式意圖的幾種寫法:

//第一種:

Intent intent = new Intent();

intent.setClassName("包名","類名");

startActivity(intent);

?

//第二種:

Intent intent = new Intent();

ComponentName componentName = new ComponentName("包名","類名");

startActivity(intent);

?

//第三種:

Intent intent = new Intent(this, 要跳轉(zhuǎn)的界面類名.class );

startActivity(intent);

其實(shí)還有很多種寫法,沒有全部列出來

創(chuàng)建顯式意圖主要就是要找到組件的名稱 ComponentName = 包名/類的路徑名稱

由于顯式意圖主要是用在應(yīng)用內(nèi)部各個(gè)組件之間的跳轉(zhuǎn),所以第三種方式就很方便

?

——?jiǎng)?chuàng)建隱式意圖

隱式意圖的創(chuàng)建步驟為:

創(chuàng)建Intent對(duì)象

給這個(gè)intent對(duì)象設(shè)置Action,設(shè)置它的category值,設(shè)置包名(可以在Android系統(tǒng)源碼里查找過濾器 intent-filter 查看各個(gè)系統(tǒng)應(yīng)用的action值和category值)

使用startActivity()方法跳轉(zhuǎn)到另一個(gè)界面

Intent intent = new Intent();

intent.setAction(" 目標(biāo)應(yīng)用的組件的action值? ");

intent.setCategory(" 目標(biāo)應(yīng)用的組件的category值 ");

intent.setPackage(" 目標(biāo)應(yīng)用的組件的包名 ");

startActivity(intent);

采用這種方式,在創(chuàng)建和使用的時(shí)候我們是看不見這個(gè)組件的名稱的,只通過它的action值,category值和包名就可以使用了

?

<5>組件之間的數(shù)據(jù)傳遞

Activity之間的數(shù)據(jù)傳遞和組件之間的數(shù)據(jù)傳遞是一樣的

數(shù)據(jù)傳遞又分為兩種:1 基本數(shù)據(jù)類型的數(shù)據(jù)傳遞??? 2? 引用數(shù)據(jù)類型的數(shù)據(jù)傳遞(對(duì)象的傳遞)

?

——基本數(shù)據(jù)類型數(shù)據(jù)的傳遞

直接創(chuàng)建一個(gè)意圖intent,調(diào)用intent中的putExtra()方法就可以把基本數(shù)據(jù)類型的數(shù)據(jù)以鍵值對(duì)的形式存儲(chǔ)在這個(gè)intent中

然后切換界面,在接收界面中首先getIntent()拿到這個(gè)intent對(duì)象,然后再用intent.getExtra()方法用鍵獲取到相應(yīng)的值即可

?

——引用數(shù)據(jù)類型數(shù)據(jù)的傳遞

其實(shí)引用數(shù)據(jù)類型的傳遞和基本數(shù)據(jù)類型的數(shù)據(jù)傳遞方式差不多,都是利用了putExtra()和getIntent()兩個(gè)方法,不同的是引用數(shù)據(jù)類型的數(shù)據(jù)在傳遞前必須要把數(shù)據(jù)序列化

要把數(shù)據(jù)序列化,就是要在傳遞的對(duì)象的類中實(shí)現(xiàn)Parcelable接口或者實(shí)現(xiàn)Serializable接口

Parcelable接口是Google自定義的接口,使用起來比較高效,直接將數(shù)據(jù)存儲(chǔ)到內(nèi)存中,然后傳遞

Serializable接口則是Java自帶的,是寫到持久化存儲(chǔ)單元里然后再傳遞的,比較慢

例如我們要傳遞一個(gè)user對(duì)象,首先要對(duì)User類實(shí)現(xiàn)可序列化的接口

然后再傳遞

(需要注意的是,String類和Bitmap類本身就以及實(shí)現(xiàn)了序列化接口的,所以在傳遞string類型數(shù)據(jù)或bitmap類型的數(shù)據(jù)的時(shí)候,不需要再對(duì)其實(shí)現(xiàn)序列化接口,直接和基本數(shù)據(jù)類型傳遞一樣的使用就可以了)

?

?

?

?

來寫一個(gè)撥打電話的按鍵,練習(xí)一下用協(xié)議來傳數(shù)據(jù):

?

?注意要在配置清單中打開打電話的權(quán)限

?

?類似的打電話,發(fā)短信,或者操作其他應(yīng)用的都可以通過這種方法,在Android源碼中找到相應(yīng)的參數(shù),通過創(chuàng)建隱式意圖的方法進(jìn)行跳轉(zhuǎn)和根據(jù)其中規(guī)定的協(xié)議進(jìn)行數(shù)據(jù)傳輸

?

——也可以自己按這種方法定義界面操作,在配置清單中配置一下即可,其中 action 內(nèi)容就是包名.應(yīng)用名稱 , category 意思就是這個(gè)應(yīng)用的類別(例如DEFAULT就表示這是一個(gè)應(yīng)用),data 后面可以自己設(shè)置約束

然后通過隱式意圖,填寫相關(guān)的配置信息,就可以跳轉(zhuǎn)到該應(yīng)用界面并傳輸數(shù)據(jù)

?

?<6>Activity之間的數(shù)據(jù)回傳

例如我們發(fā)微信朋友圈的時(shí)候,需要從朋友圈編輯界面先跳轉(zhuǎn)到相冊(cè)界面,選擇想要發(fā)布的相片,然后選完之后會(huì)自動(dòng)返回到朋友圈的編輯界面,并且選中的相片會(huì)傳到這里

這種類似的情況就用到了Activity之間的數(shù)據(jù)回傳

數(shù)據(jù)回傳和跳轉(zhuǎn)界面差不多,主要的區(qū)別在于數(shù)據(jù)回傳要用到startActivityForResult(intent)這個(gè)方法而不是startActivity(intent)方法

?

寫一個(gè)充值的例子來練習(xí),具體要求是:

在主界面點(diǎn)擊充值按鍵,跳轉(zhuǎn)到充值界面,在充值界面充值等操作后,自動(dòng)返回到主界面并顯示操作結(jié)果

主界面中的操作

?

?支付界面的操作

?

?

?

?

?主要的思路就是,主界面調(diào)用startActivityForResult(intent,requestCode<1> )方法

在充值界面中,當(dāng)完成充值操作會(huì)調(diào)用setResult(resulCode<2> , intent)方法,當(dāng)完成取消充值會(huì)調(diào)用setResult(resultCode<3> ,intent)方法

在主界面中重寫onActivityResult()方法,在這個(gè)方法中通過判斷requestCode來確定返回?cái)?shù)據(jù)應(yīng)該去到哪個(gè)部位

通過判斷resultCode來判斷跳轉(zhuǎn)的那個(gè)界面到底做了什么操作,用data.getExtra()方法獲取到相應(yīng)操作的數(shù)據(jù)結(jié)果

?

本文摘自 :https://www.cnblogs.com/

開通會(huì)員,享受整站包年服務(wù)立即開通 >