2016-10-13 23 views
0

我正在構建一個電子書閱讀器,因此我有一個webview加載本地存儲在從電子書本身檢索的設備上的頁面。在這個頁面上,它有一個JavaScript函數controls.nextPage(),它加載並運行得很好;它過去並不實際導航到新的網頁,而是使用JavaScript重新繪製虛擬頁面。我有這個功能綁定到網頁上的一個按鈕本身,以便我可以手動點擊它來測試,再次,當我觸摸我的web視圖上的按鈕時工作得很好。如何從android活動調用現有的javascript功能

現在我試圖從我的應用程序內觸發這個確切的功能。理想情況下,我想通過手勢輕掃來實現這一點,但對於這個特定問題來說太複雜了,因爲我還有其他需要首先解決的手勢問題。現在,我已經設置了一個按鈕,在我的抽屜式導航來觸發它,測試它:

NavigationView navigationViewRight = (NavigationView) findViewById(R.id.nav_view_webview_right); 
navigationViewRight.setNavigationItemSelectedListener(
    new NavigationView.OnNavigationItemSelectedListener() { 
     @SuppressWarnings("StatementWithEmptyBody") 
     @Override 
     public boolean onNavigationItemSelected(MenuItem item) { 
      // Handle navigation view item clicks here. 
      int id = item.getItemId(); 

      if (id == R.id.nav_camera) { 
       // *** - Focus here - *** // 
       runOnUiThread(new Runnable() { 
        @Override 
        public void run() { 
         mWebview.evaluateJavascript("controls.pageNext()", null); 
        } 
       }); 
      } else if (id == R.id.nav_share) { 
      } 

      drawer.closeDrawer(GravityCompat.END); 
      return true; 
     } 
    } 
); 

注意,我也打過電話window.controls.pageNext()無濟於事。

所以我的頁面被加載,並且我打了我的頁內按鈕來測試函數;作品。我去打我的導航抽屜裏的按鈕在應用程序?錯誤(使用window.controls.pageNext()時:

[INFO:CONSOLE(1)] "Uncaught TypeError: Cannot read property 'pageNext' of undefined", source: (1) 

所以這似乎是evaluateJavascript()是在一個新的環境/線程中運行我怎麼能告訴它不要

要解決這個問題,我有?試圖在我可以簡單地初始化我的頁面的JavaScript到它希望創建一個空的JavaScript接口,從而能夠從Android調用它。

mWebview.addJavascriptInterface(new TestInterface(), "TestInterface"); 

public class TestInterface { 
    @JavascriptInterface 
    public void test() { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       mWebview.evaluateJavascript("console.log('test')", null); 
      } 
     }); 
    } 
} 

從我的web應用程序中,JavaScript可以調用接口就好了。呼籲TestInterface.test();產量:

[INFO:CONSOLE(1)] "test", source: (1) 

但是,當我試圖將一個新的功能分配給從我的web應用該接口:

TestInterface.testTwo = function() { 
    console.log('testTwo'); 
}; 
TestInterface.testTwo(); 

的Android不會有:

[INFO:CONSOLE(674)] "testTwo", source: http://127.0.0.1:8080/js/main.js (674) 

有什麼奇怪的是這不是真的給我很多信息繼續下去。我知道我的頁面的其餘部分在testTwo()嘗試test()沒有,因此我假設未能加載腳本的其餘部分加載問題。

最後,出於好奇,我改變了我的抽屜式導航按鈕嘗試和運行這樣的新功能:

mWebview.evaluateJavascript("TestInterface.testTwo()", null); 

登錄:

[INFO:CONSOLE(1)] "Uncaught TypeError: TestInterface.testTwo is not a function", source: (1) 

是的,但它是別的東西?我不知道。思考?謝謝。

回答

0

所以我最終想出了我的問題是什麼。通過運行mWebview.evaluateJavascript("window.location", null);我意識到我其實並沒有在我以爲是的頁面上。我的電子書頁面被加載到一個iframe或其他類型的框架/包裝器中,使得運行evaluateJavascript()時web應用程序功能實際上不可用。

所以一旦想通了這一點,我可以證實一些事情,我原來上面的質疑:

所以這似乎是evaluateJavascript()在新的環境 /線程中運行。我怎麼能告訴它不?

它沒有。只要確定你知道什麼頁面實際加載。

要解決這個問題,我試圖在我可以簡單地初始化我的網頁的JavaScript到它,從而能夠從Android叫它希望創建一個空的JavaScript接口。

這確實有效。我不知道我以前的錯誤是什麼,但是如果我在Android中創建一個JavaScript接口,它的功能可用於Web應用程序,並且我實際上可以將新對象從Web應用程序寫入接口對象。 mWebview.evaluateJavascript("TestInterface.someNewFunctionFromWebapp()", null);

我卻無法覆蓋的JavaScript界面​​對象的任何現有對象/屬性:那麼,初始化新對象到TestInterface從Web應用程序中,可以在Android應用中通過運行。所以TestInterface.test()是不可變的。