成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

模仿Android微信小程序,實(shí)現(xiàn)小程序獨(dú)立任務(wù)視圖的效果

移動開發(fā) Android
小程序相信現(xiàn)在所有人都使用過的對吧,很多人甚至天天都在使用。小程序特別的方便,無需下載,無需安裝,在微信當(dāng)中打開就能立刻使用。隨取隨用,隨用隨走,也不占用任何手機(jī)的存儲空間。

?今天跟大家分享一個非常有趣的技術(shù),如何在我們的App中實(shí)現(xiàn)類似于微信小程序的功能。

哈哈開個玩笑,如果我能徒手實(shí)現(xiàn)一套微信小程序系統(tǒng)的話,早就被騰訊挖過去當(dāng)架構(gòu)師了。

小程序相信現(xiàn)在所有人都使用過的對吧,很多人甚至天天都在使用。小程序特別的方便,無需下載,無需安裝,在微信當(dāng)中打開就能立刻使用。隨取隨用,隨用隨走,也不占用任何手機(jī)的存儲空間。

而Android上的微信小程序做得格外的像一個真正的應(yīng)用程序。為什么這么說呢?因為Android上的每個微信小程序甚至還能擁有自己的任務(wù)視圖,就像是一個真正的獨(dú)立應(yīng)用程序一樣。點(diǎn)擊手機(jī)任務(wù)欄鍵可以看到如下界面:

圖片

上圖中美團(tuán)外賣、微博熱搜、星巴克都是小程序。

擁有獨(dú)立的任務(wù)視圖的話,就可以更加方便地在多個小程序或微信本體之間進(jìn)行快速切換,在這點(diǎn)上Android的體驗要比iOS更好。

那么問題來了,這種依附于其他程序的小程序是如何做到擁有一個獨(dú)立的任務(wù)視圖的呢?

本篇文章我們就來一探究竟。

事實(shí)上,這是一個很基礎(chǔ)的功能。有多基礎(chǔ)呢?任何一位Android開發(fā)者在入門時都一定學(xué)過這個知識:Launch Mode。

因此,我就不在這里對Launch Mode進(jìn)行展開講解了。如果你真的從來沒有聽說過Launch Mode,建議參考《第一行代碼 第3版》第3章的內(nèi)容。

我們都知道,Android中Activity的啟動模式一共有4種:standdard、singleTop、singleTask和singleInstance。

從字面意思上來看,singleTask表示的就是要啟用一個單獨(dú)的任務(wù)來存放當(dāng)前Activity。但假如你把一個Activity聲明成了singleTask,你會發(fā)現(xiàn)并不能得到我們想要的效果,所有的Activity仍然是放在同一個任務(wù)當(dāng)中的。

這是因為,singleTask還會關(guān)聯(lián)一個叫taskAffinity的屬性,只有被聲明成singleTask的Activity,且它的taskAffinity值也是獨(dú)立的,那么這個Activity才會被放在一個單獨(dú)的任務(wù)當(dāng)中。

而默認(rèn)情況下,每個Activity的taskAffinity屬性值都是當(dāng)前應(yīng)用程序的包名,也就是說它們的值都是相同的,所以才不能得到我們想要的效果。

那么解決方法也很簡單,給每一個要啟用獨(dú)立任務(wù)視圖的Activity都賦值一個不同的taskAffinity值即可。

接下來我們就開始動手實(shí)踐一下吧。

首先創(chuàng)建一個叫MiniProgramTest的項目。

接下來創(chuàng)建3個空的Activity,分別給它們起名為FirstActivity、SecondActivity和ThirdActivity。

然后編輯項目的activity_main.xml布局文件,在里面加入3個按鈕,分別用于啟動FirstActivity、SecondActivity和ThirdActivity:

<androidx.constraintlayout.widget.ConstraintLayout 
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"
tools:context=".MainActivity">

<Button
android:id="@+id/first_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="啟動第一行代碼"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@+id/second_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />

<Button
android:id="@+id/second_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="啟動第二行代碼"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toTopOf="@+id/third_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/first_btn" />

<Button
android:id="@+id/third_btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="啟動第三行代碼"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/second_btn" />

</androidx.constraintlayout.widget.ConstraintLayout>

布局文件定義好了之后,接下來修改MainActivity的代碼,加入啟動邏輯:

class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)

val firstBtn = findViewById<Button>(R.id.first_btn)
val secondBtn = findViewById<Button>(R.id.second_btn)
val thirdBtn = findViewById<Button>(R.id.third_btn)

firstBtn.setOnClickListener {
val intent = Intent(this, FirstActivity::class.java)
startActivity(intent)
}
secondBtn.setOnClickListener {
val intent = Intent(this, SecondActivity::class.java)
startActivity(intent)
}
thirdBtn.setOnClickListener {
val intent = Intent(this, ThirdActivity::class.java)
startActivity(intent)
}
}
}

代碼非常簡單,點(diǎn)擊哪個按鈕就去啟動相應(yīng)的Activity就可以了。

但如果僅僅是這樣,F(xiàn)irstActivity、SecondActivity和ThirdActivity一定與MainActivity是存放在同一個任務(wù)當(dāng)中的。

因此下面我們就要去編寫最核心的代碼了,修改AndroidManifest.xml文件,如下所示:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.miniprogramtest">

<application
...>

<activity
android:name=".FirstActivity"
android:exported="false"
android:label="第一行代碼"
android:launchMode="singleTask"
android:taskAffinity="com.example.miniprogramtest.first"
/>

<activity
android:name=".SecondActivity"
android:exported="false"
android:label="第二行代碼"
android:launchMode="singleTask"
android:taskAffinity="com.example.miniprogramtest.second" />

<activity
android:name=".ThirdActivity"
android:exported="false"
android:label="第三行代碼"
android:launchMode="singleTask"
android:taskAffinity="com.example.miniprogramtest.third"
/>
...
</application>

</manifest>

可以看到,這里我們將FirstActivity、SecondActivity和ThirdActivity的launchMode都設(shè)置成了singleTask,并且給它們都指定了一個不同的taskAffinity。

現(xiàn)在運(yùn)行一下程序,并分別點(diǎn)擊界面上的3個按鈕,然后按下手機(jī)任務(wù)欄鍵,我們就能看到如下效果了:

圖片

有沒有覺得很神奇?明明都是同一個App中的3個Activity,現(xiàn)在我們竟然可以讓它們在3個獨(dú)立的任務(wù)視圖中顯示,是不是感覺就好像是微信小程序一樣?

不過,雖然FirstActivity、SecondActivity和ThirdActivity都擁有獨(dú)立的任務(wù)視圖了,它們和微信小程序還有一個非常明顯的差距。

因為每個程序都有自己專屬的應(yīng)用Logo,小程序也不例外。就像我們在最開始的圖片中看到的一樣,美團(tuán)小程序有美團(tuán)的Logo,微博小程序有微博的Logo,星巴克小程序有星巴克的Logo。

而目前,F(xiàn)irstActivity、SecondActivity和ThirdActivity顯示的都是MiniProgramTest這個項目的Logo,這使得它們看上去仍然不像是一個獨(dú)立的應(yīng)用程序。

下面我們就開始著手優(yōu)化這部分問題。

首先,這里我準(zhǔn)備了3張圖片first_line.png、second_line.png、third_line.png,分別用于作為FirstActivity、SecondActivity和ThirdActivity的Logo:

圖片

接下來,編輯FirstActivity、SecondActivity和ThirdActivity的代碼,在里面加入如下邏輯:

class FirstActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_first)
setCustomTaskDescription()
}

private fun setCustomTaskDescription() {
val taskDescription = ActivityManager.TaskDescription(
"FirstActivity",
BitmapFactory.decodeResource(resources, R.drawable.first_line)
)
setTaskDescription(taskDescription)
}
}

class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
setCustomTaskDescription()
}

private fun setCustomTaskDescription() {
val taskDescription = ActivityManager.TaskDescription(
"SecondActivity",
BitmapFactory.decodeResource(resources, R.drawable.second_line)
)
setTaskDescription(taskDescription)
}
}

class ThirdActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_third)
setCustomTaskDescription()
}

private fun setCustomTaskDescription() {
val taskDescription = ActivityManager.TaskDescription(
"ThirdActivity",
BitmapFactory.decodeResource(resources, R.drawable.third_line)
)
setTaskDescription(taskDescription)
}
}

這3段代碼的邏輯基本都是相同的。

核心部分就是調(diào)用了setCustomTaskDescription()方法來給當(dāng)前Activity設(shè)置一個自定義的TaskDescription。

所謂TaskDescription就是給當(dāng)前的任務(wù)設(shè)置一個描述,描述中可以包含任務(wù)的名稱和圖標(biāo)。

那么這里我們給FirstActivity、SecondActivity和ThirdActivity分別設(shè)置了不同的TaskDescription,這樣在任務(wù)視圖當(dāng)中,就可以看到各不相同的應(yīng)用Logo了,如下圖所示:

圖片

其實(shí)到這里為止,我們就把微信小程序的外殼搭建得差不多了。剩下的部分,當(dāng)然也是最難的部分,就是在這個殼子里面添加小程序的內(nèi)容了。這部分的技術(shù)以前端為主,并不是我擅長的領(lǐng)域,我也講不了,因此就不再繼續(xù)向下延伸了。

不過或許還有些朋友會存在這樣的疑惑:目前我們的技術(shù)實(shí)現(xiàn)方案是給每個小程序定義一個單獨(dú)的Activity(FirstActivity、SecondActivity和ThirdActivity),而微信小程序卻可以有無限多個,我們顯然不可能在AndroidManifest.xml文件中注冊無限個Activity,那么微信又是如何實(shí)現(xiàn)的呢?

其實(shí)這只是一個美麗的誤會,因為微信小程序并不是可以有無限多個,只是你平時沒有注意這個小細(xì)節(jié)而已。

我們通過做個實(shí)驗來驗證一下吧,觀察下圖中的效果:

圖片

可以看到,這里我事先依次按照順序打開了嗶哩嗶哩、QQ音樂、微博熱搜、京東購物、星巴克,這5個小程序。

這個時候回到微信當(dāng)中,再打開一個順豐速運(yùn)小程序。

再次回到任務(wù)視圖列表界面,你會發(fā)現(xiàn)現(xiàn)在多了一個順豐速運(yùn)的小程序,而最早打開的嗶哩嗶哩小程序卻從任務(wù)視圖列表中消失不見了。

由此可以看出,微信其實(shí)在AndroidManifest.xml文件中也只是放置了5個占位的Activity。當(dāng)你嘗試打開第6個小程序時,最先打開的那個小程序就會被回收,將它的容器提供給第6個小程序使用。

好了,本篇文章到這里就結(jié)束了。內(nèi)容其實(shí)非常的簡單,但是已經(jīng)把在Android上如何實(shí)現(xiàn)小程序外層的架子講明白了。至于如何實(shí)現(xiàn)小程序最核心的內(nèi)容部分,那就要看各位架構(gòu)師的水準(zhǔn)了。?

責(zé)任編輯:武曉燕 來源: 郭霖
相關(guān)推薦

2017-05-08 15:03:07

微信小程序開發(fā)實(shí)戰(zhàn)

2016-11-04 10:48:37

信小程序

2017-02-06 13:32:12

微信小程序思想

2016-11-22 11:23:52

微信小程序騰訊微信

2016-09-27 15:40:58

微信程序前端

2016-11-04 10:49:48

微信小程序

2016-09-27 16:38:24

JavaScript微信Web

2021-06-10 10:51:27

程序基礎(chǔ)架構(gòu)

2016-10-20 21:02:12

微信小程序javascript

2017-01-09 10:01:49

微信小程序

2017-06-09 10:40:00

微信小程序架構(gòu)分析

2017-06-09 12:58:20

微信小程序架構(gòu)分析

2016-09-28 18:10:59

微信程序MINA

2016-11-04 10:31:49

微信程序指南

2017-06-09 10:06:54

微信小程序架構(gòu)分析

2021-10-28 19:32:16

微信原理程序

2016-11-04 10:30:17

微信小程序

2021-03-03 14:23:06

微信小程序互聯(lián)網(wǎng)

2018-08-03 11:10:30

前端小程序vue.js

2018-07-26 15:16:50

小程序iPhone X甜酸
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 成人午夜影院 | 免费99精品国产自在在线 | 成人av电影在线观看 | 国产精品久久久久久久岛一牛影视 | 激情欧美一区二区三区 | 蜜桃免费av | 日韩视频在线一区 | 毛片一级片 | 亚洲欧美久久 | 蜜桃传媒一区二区 | 久久曰视频 | 国产内谢| 亚洲国产精品久久久久婷婷老年 | 羞羞视频网站免费观看 | 日本一区二区不卡视频 | 久久精品国产免费一区二区三区 | 国产无套一区二区三区久久 | 精品欧美一区免费观看α√ | 久久精品亚洲精品国产欧美 | 视频1区2区 | 中文日韩在线视频 | 亚洲最大福利网 | 蜜桃av鲁一鲁一鲁一鲁 | 久久亚洲一区 | 艹逼网| 怡红院免费的全部视频 | 九一在线观看 | 97色在线视频| 网色| 人干人人| 欧美日韩国产三级 | 午夜精品久久久久久久99黑人 | 一本色道久久综合亚洲精品高清 | 青草久久免费视频 | 欧美1区2区| 毛片站 | 日本黄色片免费在线观看 | 国产真实乱对白精彩久久小说 | 亚洲国产欧美精品 | 久久久久国产一级毛片高清网站 | 国产成人精品久久二区二区 |