Webview裏JS跳轉到Activity頁面

有兩種方法.

第一種是通過webview提供的js和java溝通的接口進行

public void addJavascriptInterface(Object object, String name) 

然後,在javascript裏可以通過name來引用到object對象裏有@JavascriptInterface註解的方法

Java代碼

  WebView wv;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        wv = (WebView)findViewById(R.id.webView);
        wv.getSettings().setJavaScriptEnabled(true);
        wv.addJavascriptInterface(this, "nativeMethod");
        wv.loadUrl("file:///android_asset/index.html");
    }

    @JavascriptInterface
    public void toActivity(String activityName) {
        //此處應該定義常量對應,同時提供給web頁面編寫者
        if(TextUtils.equals(activityName, "a")){
            startActivity(new Intent(this,AActivity.class));
        }else{
            startActivity(new Intent(this,BActivity.class));
        }
    }

javascript代碼

<!DOCTYPE HTML>
<html>

<script type="text/javascript">
  function gotoActivity (activity) {
    nativeMethod.toActivity(activity);
  }
</script>
<body>

<button onClick="gotoActivity('a')">gotoActivity A</button>
<button onClick="gotoActivity('b')">gotoActivity B</button>

</body>
</html>

以上是第一種方法,在index.html頁面可以跳轉到AActivity和BActivity。

第二種方式裏是利用系統提供的Activity隱式啓動。

<!DOCTYPE HTML>
<html>

<body>
<a href="myapp://tonative/param?id=123">gotoActivity B</a>
<a href="http://www.baidu.com">open http link</a>
<a href="file:///android_asset/b.html">open local file</a>

</body>
</html>

當我們在webview里加載上面的代碼,並點擊gotoActivity B後,系統會去尋找能處理uri爲”myapp://tonative/param?id=123”的Activity,默認情況下當然是沒有的,所以我們可以把要打開的Activity按照約定的uri協議進行聲明

<activity android:name=".BActivity"
            android:parentActivityName=".AActivity">
            <intent-filter>
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:host="tonative"
                    android:scheme="myapp" />
            </intent-filter>
        </activity>

我們可以通過聲明不同的host實現打開不同的Activity,在打開的Activity裏可以通過如下代碼獲取html頁面傳過來的參數

 Intent intent = getIntent();
        String action = intent.getAction();
        if(Intent.ACTION_VIEW.equals(action)){
            Uri uri = intent.getData();
            if(uri != null){
                String id = uri.getQueryParameter("id");
                Toast.makeText(this,id,Toast.LENGTH_LONG).show();
            }
        }

但這樣其實有個問題,我們一般會在自己的WebviewActivity裏給

 wv.setWebViewClient(new WebViewClient(){})

從而實現在本頁內的跳轉都是由本Webview打開,而不是跳轉到系統瀏覽器處理。這樣設置後,‘href=”myapp://tonative/param?id=123”’這樣的請求也被攔截到了本Webview裏,從而失效,因此,我們需要做一個判斷

 wv.setWebViewClient(new WebViewClient(){
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {

                String scheme = Uri.parse(url).getScheme();//還需要判斷host
                if (TextUtils.equals("myapp", scheme)) {
                    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
                    startActivity(intent);
                    return true;
                }
                return false;
            }
        });

return true,表明這次請求交給系統來處理。
京東金融App裏有很多的活動頁面是h5,點擊可以跳轉到原生的基金購買頁面,用Fiddler攔截想看一下他們採用的方式,但是攔截到js這些是可以的,但html解出來的都是亂碼,可能他們採用了加密?

發佈了36 篇原創文章 · 獲贊 65 · 訪問量 27萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章