• 跨平台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发送回调通知。

  • 相关阅读:
    蒟蒻Orion还要学的东西!
    一些技巧 && 常数优化 && 出现の错误 [绝赞更新中!]
    [US Open 2004][luogu2342] 叠积木 [带权并查集]
    省选算法学习·一些数列相关的数学知识 [数学]
    [BJOI2019] 奥术神杖 [取log+AC自动机+dp]
    [BJOI2019] 删数 [dp转贪心结论+线段树]
    [2018国家集训队][UOJ449] 喂鸽子 [dp+组合数学]
    [2018集训队作业][UOJ424] count [笛卡尔树+括号序列+折线法+组合数学]
    [2018集训队作业][UOJ450] 复读机 [DP+泰勒展开+单位根反演]
    [SDOI2014][BZOJ3533] 向量集 [线段树+凸包]
  • 原文地址:https://www.cnblogs.com/ever4ever/p/2594163.html
Copyright © 2020-2023  润新知