在前面文章中對ARouter中頁面跳轉(zhuǎn)和源碼進(jìn)行了分析,今天我們來學(xué)習(xí)下通過URL跳轉(zhuǎn)本地頁面的使用和跳轉(zhuǎn)源碼分析。在看這篇文章之前建議小伙伴們先看下ARouter解析一:基本使用及頁面注冊源碼解析,先對ARouter有個整體的了解。
通過URL跳轉(zhuǎn)也免不了前面的準(zhǔn)備工作,比如ARouter實例的獲取,初始化,構(gòu)造路由信息的PostCard,PostCard的完善等都是一樣的,我們這里就不再重復(fù)炒飯了,有需要的同學(xué)自行參考ARouter解析二:頁面跳轉(zhuǎn)源碼分析.
栗子還是用的官方Demo,看下跳轉(zhuǎn)效果。
點擊“通過URL跳轉(zhuǎn)”,會通過WebView加載html文件:
點擊第一個鏈接會跳轉(zhuǎn)到Test1Activity界面:
接下來我們先來看下URL跳轉(zhuǎn)到本地頁面怎么使用。
1.URL跳轉(zhuǎn)簡單使用
首先需要加載一個H5頁面,使用方式還是一致的,通過單例模式獲取ARouter實例,傳入path“/test/webview”
構(gòu)建PostCard,用來存儲跳轉(zhuǎn)的所有信息。傳入一個H5頁面地址的參數(shù),調(diào)用navigation就可以跳轉(zhuǎn)到path路徑對應(yīng)的界面。
ARouter.getInstance().build("/test/webview")
.withString("url", "file:///android_asset/schame-test.html")
.navigation();
我們看下這個界面的代碼,邏輯很簡單。通過WebView加載url對應(yīng)的H5頁面,也就是前面?zhèn)魅氲膆tmlfile:///android_asset/schame-test.html
@Route(path = "/test/webview")
public class TestWebview extends Activity {
WebView webview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_webview);
webview = (WebView) findViewById(R.id.webview);
webview.loadUrl(getIntent().getStringExtra("url"));
}
}
簡單看下html界面的代碼,簡單我們就看下第一個跳轉(zhuǎn)鏈接的效果。點擊會會觸發(fā)href屬性的鏈接arouter://m.aliyun.com/test/activity1
.
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title></title>
</head>
<body>
<h2>跳轉(zhuǎn)測試</h2>
<h2>自定義Scheme[通常來說都是這樣的]</h2>
<p><a href="arouter://m.aliyun.com/test/activity1">arouter://m.aliyun.com/test/activity1</a></p>
<p><a href="arouter://m.aliyun.com/test/activity1?url=https%3a%2f%2fm.abc.com%3fa%3db%26c%3dd">測試URL Encode情況</a></p>
<p><a href="arouter://m.aliyun.com/test/activity1?name=alex&age=18&boy=true&high=180&obj=%7b%22name%22%3a%22jack%22%2c%22id%22%3a666%7d">arouter://m.aliyun.com/test/activity1?name=alex&age=18&boy=true&high=180&obj={"name":"jack","id":"666"}</a></p>
<p><a href="arouter://m.aliyun.com/test/activity2">arouter://m.aliyun.com/test/activity2</a></p>
<p><a href="arouter://m.aliyun.com/test/activity2?key1=value1">arouter://m.aliyun.com/test/activity2?key1=value1</a></p>
<p><a href="arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180">arouter://m.aliyun.com/test/activity3?name=alex&age=18&boy=true&high=180</a></p>
<h2>App Links[防止被App屏蔽]</h2>
<p><a >http://m.aliyun.com/test/activity1</a></p>
<p><a >http://m.aliyun.com/test/activity2</a></p>
</body>
</html>
有沒有感覺很神奇?為什么點擊一個鏈接會跳轉(zhuǎn)到我們 本地的頁面?繼續(xù)往后看就有分曉了。
URL的跳轉(zhuǎn)很簡單就是一句話,和頁面跳轉(zhuǎn)的邏輯是一樣的,這里多了一個加載H5頁面的步驟,只不過是為了模擬URL跳轉(zhuǎn)本地界面的功能。
2.URL跳轉(zhuǎn)源碼分析
在上面我們留了個疑問,為什么在WebView中點擊一個鏈接能跳轉(zhuǎn)到我們APP本地的頁面?一般會有個常用的做法,就是給WebView添加一個WebViewClient,然后實現(xiàn)shouldOverrideUrlLoading
方法,在方法中構(gòu)造intent進(jìn)行跳轉(zhuǎn)。邏輯示意代碼就是這樣:
webview.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url != null && url.contains("arouter")){
Intent intent = new Intent(TestWebview.this, Test1Activity.class);
startActivity(intent);
return true;
}
return super.shouldOverrideUrlLoading(view, url);
}
});
通過* shouldOverrideUrlLoading*攔截url跳轉(zhuǎn),然后根據(jù)自己的需要進(jìn)行跳轉(zhuǎn)。那么ARouter是這樣的嗎?淡然不是了,要不就沒有這篇分享的必要了,逃:)
首先我們先來分析下,上面這種寫法的缺點。
1.在webView中直接寫跳轉(zhuǎn)邏輯,有點硬編碼的味道,另外如果一個APP中有很多頁面需要這種跳轉(zhuǎn)邏輯,不可能每個界面添加一個WebView控件,只能在父類界面中添加共同添加一個WebView控件,然后統(tǒng)一進(jìn)行攔截,那么這時候邏輯就會顯得有點臃腫了。
2.另外一個缺點就是,比如另外一個應(yīng)用需要跳轉(zhuǎn)到我們APP的Test1Activity怎么做?這時候就不是在自己APP的WebView環(huán)境中了,這種方法就起不了作用了。所以在大型APP中不是一種很好的設(shè)計。
那么ARouter怎么做的呢?小伙伴們還記得隱式跳轉(zhuǎn)嗎?ARouter就是通過注冊一個沒有UI的界面來統(tǒng)一處理scheme是arouter的跳轉(zhuǎn)請求。我們看下代碼:
<activity android:name=".SchemeFilterActivity">
<!-- Schame -->
<intent-filter>
<data
android:host="m.aliyun.com"
android:scheme="arouter"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
</intent-filter>
</activity>
在清單文件中注冊了SchemeFilterActivity
這個activity,scheme
就是arouter
, host
就是m.aliyun.com
,其中有個category
是 android.intent.category.BROWSABLE
,這樣就可以在WebView中跳轉(zhuǎn)SchemeFilterActivity
這個界面了。有個注意點,能跳轉(zhuǎn)SchemeFilterActivity
的必要條件就是需要匹配intent-filter
中的data, action, category
的標(biāo)簽,其中category匹配任意一個即可。接著看下SchemeFilterActivity
這個界面:
public class SchemeFilterActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 直接通過ARouter處理外部Uri
Uri uri = getIntent().getData();
ARouter.getInstance().build(uri).navigation(this, new NavCallback() {
@Override
public void onArrival(Postcard postcard) {
finish();
}
});
}
}
會不會有的小伙伴不相信會跳到這?還不信我的人品嗎?好吧,我在這里面打了個斷點,我沒騙人吧。同時可以看到拿到了H5界面點擊的鏈接arouter://m.aliyun.com/test/activity1
.
有了這個鏈接,后面其實就是頁面跳轉(zhuǎn)的邏輯了,同ARouter解析二:頁面跳轉(zhuǎn)源碼分析源碼跳轉(zhuǎn)是一致的,這里就不再粘貼一次了。
那么這樣使用有什么好處呢?
1.首先就是頁面跳轉(zhuǎn)的靈活性,比如需要和H5中進(jìn)行通信,H5需要跳轉(zhuǎn)到APP本地的頁面,Native和H5只需要統(tǒng)一一個path文檔即可,H5通過path構(gòu)造一個url就可以實現(xiàn)跳轉(zhuǎn)到對應(yīng)頁面的功能,很類似瀏覽器,實現(xiàn)很好的解耦。
2.相比較于隱式的intent,每一個從外面跳轉(zhuǎn)進(jìn)來的頁面都需要注冊上intent-filter,每個頁面都需要設(shè)置export=true,也就是需要讓每一個頁面都可以導(dǎo)出,在外部可以訪問到。這樣做會帶來非常嚴(yán)重的安全風(fēng)險,就像是一個房子有十個門還是只有一個門,看門的成本是不同的。而現(xiàn)在使用的這種場景只需要對外暴露出一個activity,然后在這個activity中注冊一個intent-filter,這樣之后所有的外部路由請求都會經(jīng)過這唯一的門,然后在這個activity中獲取到URL并將其交給ARouter,剩下的就由路由框架做分發(fā)了。
3.另外一個好處就是隱式intent跳轉(zhuǎn)無法將參數(shù)自動注入,ARouter可以在url中攜帶參數(shù)然后自動注入,這個我們這次分享沒有涉及到,下一個分享會涉及。
3.總結(jié)
今天URL跳轉(zhuǎn)本地頁面源碼的內(nèi)容就是這些,有了前面兩篇分享的基礎(chǔ)到這里就比較輕松愉快了。使用方式都是都是一行代碼搞定,和Activity跳轉(zhuǎn)不同的就是需要考慮外部導(dǎo)航到本地頁面的需求,因此需要在清單文件中聲明一個activity,這個activity不需要頁面,用來統(tǒng)一獲取url請求,然后再交給路由框架進(jìn)行跳轉(zhuǎn)。
今天的URL跳轉(zhuǎn)本地頁面源碼分析的車就開到這了,大家可以下車嘍。有些跳轉(zhuǎn)細(xì)節(jié)不清楚的可以參考前面的分享:
ARouter解析一:基本使用及頁面注冊源碼解析
ARouter解析二:頁面跳轉(zhuǎn)源碼分析
你們的贊是我堅持下去最大的動力,謝謝!
歡迎關(guān)注公眾號:JueCode