跨平台PhoneGap技術架構五:PhoneGap類間調用關系及Js和Java交互原理


前面幾篇文章主要講解了PhoneGap幾個重要的類,如果看到這里,相信大家對PhoneGap也有了一定的了解。

PhoneGap類間調用關系

在講解PhoneGap的交互原理之前,我們把原來的內容串講一下,以加深理解。請看下面的類間調用關系圖:

在我們創建Android應用程序的時候,一般會先創建一個Activity。PhoneGap應用程序創建時Activity應繼承DroidGap類。當Activity啟動時,系統會調用onCreate方法。在DroidGap類中,復寫了Activity的onCreate方法。

在DroidGap的onCreate方法中,對Window做了一些設置,並設置了WebView的布局。最后設置了音量硬件控制功能。代碼如下:

onCreate
 1    /**
 2      * Called when the activity is first created.
 3      *
 4      * @param savedInstanceState
 5      */
 6     @SuppressWarnings("deprecation")
 7     @Override
 8     public void onCreate(Bundle savedInstanceState) {
 9         //preferences = new PreferenceSet();
10 
11         LOG.d(TAG, "DroidGap.onCreate()");
12         super.onCreate(savedInstanceState);
13 
14         if(!this.getBooleanProperty("showTitle", false))
15         {
16             getWindow().requestFeature(Window.FEATURE_NO_TITLE);
17         }
18 
19         if(this.getBooleanProperty("setFullscreen", false))
20         {
21             getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
22                     WindowManager.LayoutParams.FLAG_FULLSCREEN);
23         }
24         else
25         {
26             getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
27                     WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
28         }
29         // This builds the view.  We could probably get away with NOT having a LinearLayout, but I like having a bucket!
30         Display display = getWindowManager().getDefaultDisplay();
31         int width = display.getWidth();
32         int height = display.getHeight();
33 
34         root = new LinearLayoutSoftKeyboardDetect(this, width, height);
35         root.setOrientation(LinearLayout.VERTICAL);
36         root.setBackgroundColor(this.backgroundColor);
37         root.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
38                 ViewGroup.LayoutParams.MATCH_PARENT, 0.0F));
39 
40         // Setup the hardware volume controls to handle volume control
41         setVolumeControlStream(AudioManager.STREAM_MUSIC);
42     }

 

然后PhoneGap應用程序調用了loadUrl方法,

super.loadUrl("file:///android_asset/www/index.html");

 

之前說過,loadUrl可以看作是整個應用程序的入口函數。

loadUrl函數會調用Init方法,創建一個CordovaWebView,並設置了CordovaWebViewClient和CordovaChromeClient。

在實例化CordovaWebView時,對PluginManager做了初始化工作,而在CordovaWebViewClient的onPageStarted方法里初始化並啟動CallbackServer。

CordovaWebViewClient的onJsPrompt方法截獲Web端的JavaScript消息,調用PluginManager的exce方法執行插件。

插件執行成功后調用CallbackServer的sendJavaScript方法給Js端返回回調Js代碼。

這就是PhoneGap類間的調用關系,整個PhoneGap工作流程大概也就清晰了。

Js和Java交互原理
  • js↔java同步過程

同步處理:

從js的prompt到WebChromeClient的onJSPrompt是一個跨線程的同步調用過程,如上圖:

在cordova.js文件中,可以找到如下代碼:

var r = prompt(JSON.stringify(args), "gap:"+JSON.stringify([service, action, callbackId, true]));

這句prompt便實現了本地代碼調用。本地代碼通過WebChromeClient攔截onJsPrompt回調,利用gap:開頭標志得知是調用本地插件請求,然后向PluginManager轉發該請求。PluginManager將會根據參數來查找並執行具體插件方法。

js層通過prompt向本地發送poll請求,本地將從CallBackServer中拿出下一個回調返回給js層。

  • js↔java異步過程

異步處理:

為了區別異步和同步。若prompt返回的是空字符串,那么將認為是異步調用。此時PhoneGap會在JS層保留回調函數,待本地層向CallBackServer發送回調后進行執行。
本地層怎么區別哪個回調?PhoneGap對此的處理十分簡單,在cordova.js中定義了一個callbackId的自增種子,並將每個callBack插入callBacks中去。無論同步異步,每個plugin調用都將得到一個流水號碼作為回調標識。這個回調標識在prompt階段便傳遞到了本地層。當本地層的Plugin異步結束后,便可以根據該callbackId找到回調。並向CallBackServer發送回調通知。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM