html5無法調用Android本地方法的一種情況(因混淆)

來源:互聯網
上載者:User

最近在開發一個模組的時候,有一個Activity嵌套了html5頁面,但是發現了一個問題,就是Debug包是可以正常調用Android本地方法的,而Release包則無法調用同一個本地方法。
代碼如下:

public class FlaggingActivity extends AppBaseActivity {    @Initialize    NavigateBar navigateBar;    @Initialize    WebView webView;    String url = NetComment.getIns().getH5()+"/html/fedback/index.html?";    String strId;    String strTel;    String strType;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        Intent intent=getIntent();        strId = intent.getStringExtra("id");        strTel = intent.getStringExtra("tel");        strType = intent.getStringExtra("type");        url = url +"id="+strId+"&type="+strType+"&tel="+strTel+"&device=2";        setContentView(R.layout.activity_flagging);        findAllViewByRId(R.id.class);        WebSettings webSetting = webView.getSettings();        //設定js可用        webSetting.setJavaScriptEnabled(true);        // 添加js調用介面        webView.addJavascriptInterface(this,"android");        webView.getSettings().setJavaScriptEnabled(true);        webView.setWebViewClient(new WebViewClient() {            public boolean shouldOverrideUrlLoading(WebView view, String url) {                view.loadUrl(url);                return true;            }        });        webView.loadUrl(url);    }    @JavascriptInterface    public void close(String token) {        //關閉當前activity        this.finish();    }}

從上面的代碼可以看出,我這裡就是在Activity裡嵌套了一個webview,webview的內容指向一個html頁面。然後在html頁面通過Js再去反向調用Android本地的close方法。
然而,在這裡出現了上文的問題:就是Debug包是可以正常調用Android本地方法的,而Release包則無法調用同一個本地方法。
經過排查,我發現了:在我的Android項目裡,Debug包是未混淆的,而Release包是經過混淆的,問題也的確就出現在混淆上。混淆的作用是:為了防止自己的勞動成果被別人竊取,混淆代碼能有效防止被反編譯。那麼同樣地,因為混淆功能的開啟,導致本地的close()方法,在經過混淆之後可能並不再是close()這個函數名稱了,那就導致我們的js無法找到這個方法,也就無法調用close()方法了。
相應的解決方式也就是讓close()方法不參與混淆,我這裡的範圍稍微大了一些,是直接把當前的類設定成為了不可混淆,如下(添加在proguard-rules.pro檔案中):

#html互動本地方法不能被混淆-keepclassmembernames class com.android.app.activity.house.FlaggingActivity {*;}

加上上面的代碼塊中後,我們的release包也可以找到close()方法了。

其實這個問題很好解決,在這裡記錄下來的原因就是一般情況下,Debug包是不混淆的,而Release包通常作為上線包是需要混淆的。但是我們在測試的時候通常使用的是Debug包,在Debug包測試無誤的時候通常對於Release包的測試就會掉以輕心。當我們使用js調用本地方法或者反射的時候,這是玩玩不可以的。所以也就要求我們在上線的時候最好對於Release包也進行一個相對完整的測試,以減少類似的失誤。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.