PhoneGap源码解析
<wbr></wbr>
<wbr></wbr>
Phonegap的核心是插件。在phonegap的概念中,一切调用native功能,都被封装成插件(plugin),由PlugInManager来管理。而在PhoneGap的使用方法中,PlugInManager是由重写过的Activity,即DroidGap来调用的。
<wbr></wbr>
本文主要涉及到的类是PlugInManager,PlugIn,DroidGap, CallbackServer,主要探讨phonegap源码的实现和可供我们结合使用的方式。
1.
DroidGap继承于PhonegapActivity,而PhonegapActivity继承于activity。
<wbr></wbr>
PhonegapActivity是一个抽象类,其中方法不多,列举如下:
<wbr></wbr>
abstract public void sendJavascript(String statement);
abstract public void startActivityForResult(IPlugin command, Intent intent, int requestCode);
abstract public void loadUrl(String url);
abstract public void setActivityResultCallbac<wbr>k(IPlugin plugin);</wbr>
abstract public void setActivityResultCallbac<wbr>k(IPlugin plugin);</wbr>
<wbr></wbr>
其中sendJavascript和loadUrl是phonegap的关键方法。还有两个关键的继承类,GapViewClient和GapClient。
<wbr></wbr>
sendJavascript会被具体的PlugIn回调,例如storage这个插件,在startPlaying方法中,会调用自己的sendJavascript,然后这个sendJavascript会继续调用DroidGap的sendJavascript,然后继续调用CallbackServer的sendJavascript方法,添加到CallbackServer的javascript
linkedlist中去。
<wbr></wbr>
loadUrl事实上是调用了对应的webview的loadUrl,做了一些额外的处理。loadUrl中调用了loadUrlIntoView方法,其中在加载url之前,初始化了CallbackServer,
pluginManager,还为webview设置了超时时间。
<wbr></wbr>
DroidGap中,GapViewClient是对WebviewClient的继承。
<wbr></wbr>
主要是针对拨打电话,调用地图,发送邮件等本Intent的方式进行拦截和调用。这部分代码我们可以直接copy过来使用。
<wbr></wbr>
DroidGap中,GapClient是对WebChromeClient的继承。
在onJsAlert和onJsConfirm方法中,使用Dialog来代替js的默认实现。
在onJsPrompt中,对满足以下条件
<wbr></wbr>
<wbr>(url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0 || isUrlWhiteListed(url))</wbr>
1).file://开头的本地文件
2).在请求的url域名内
3).在配置的url白名单内,白名单是一个配置文件,通过addWhiteListEntry添加。放在xml目录下的phonegap.xml文件。默认配置了http://127.0.0.1。
<wbr></wbr>
并且满足例如"gap:"等情况。进行了自行重写。
<wbr></wbr>
重写条件如下:
1)满足"gap:"开头的,调用plugInManager进行处理。此时每个gap:后面的内容会对应一个具体的调用本地操作的功能。例如摄像头,本地存储等。
2)满足"gap_poll:"开头的,调用callbackServer.getJavascript();
3)满足"gap_callbackServer:"开头的,调用callbackServer.restartServer()等操作。
4)满足"gap_init:"开头的,将webview设置为不可见
<wbr></wbr>
其他情况,依然是以一个dialog形式弹出。
<wbr></wbr>
重点说一下重写条件1)
调用PlugInManager的时候,每次都会重新开启一个线程,在开启线程前还做了一次同步检查,保证同一时刻同一个插件只被调用一次。在线程中,调用对一个PlugIn,执行PlugIn的exec方法,执行具体功能。执行完成之后,返回一个PluginResult。其中以status标示了本地功能调用结果。如果调用成功或者无结果(也可以说是另一方面的调用成功,比如notifacation这种功能),则调用DroidGap的sendJavaScript方法,通知给CallbackServer。
<wbr></wbr>
另外还重写了onPageFinish等一系列方法,我们都可以参考。
<wbr></wbr>
按我的理解,在这个部分的写法的好处,从模式上讲是将本地功能模块化,明晰化,封装的比较好,各自调用自己的功能,从执行效率上讲避免了主线程执行功能,但是在异步线程中操作数据库等功能,会不会引起问题,这个可能也是未来我们结合phonegap的方式来处理自己的程序需要注意的地方。
<wbr></wbr>
2.
另外一个比较重要的工具类是CallbackServer,这也是phonegap框架后来改名为CallBack的原因。它是一个客户端本地实现的XHRServer。在调用完js中的代码,执行完本地的功能后,需要给js发送一个反馈,也就是调用sendJavaScript方法。
<wbr></wbr>
初始化CallbackServer的时候,会建立一个泛型为String的LinkedList,用于保存javascript代码。CallbackServer在外部被调用最多的sendJavascript方法,实现中就是将发送过来的Js语句,添加到这个LinkedList中。
如果要加载的url不是以file://开头,就会建立一个新的线程,CallbackServer本身是实现了Runnable接口的,这个线程就以this作为参数。同时start这个线程。
所以,在整个CallbackServer中,最核心的方法凸显出来了,就是Run。
<wbr></wbr>
Run方法中,建立了一个ServerSocket,将自己作为一个服务器来接收请求。
当LinkedList中有没有处理完的返回结果的时候,就会把链表中的最先进来的提出来,返回给客户端。没有请求来,则10秒钟返回一个空的回复,以维持XHRServer。
<wbr></wbr>
在PhoneGap.js中,PhoneGap.JSCallbackPolling会被setTimeout(1)作为轮询,来访问这个CallBackServer,监听js需要处理的内容。
我个人对这个地方有些疑问,因为这么短时间的轮询,虽然是本地执行,但是会不会有效率问题,需要真正进入开发实战和测试后才能体现。
<wbr></wbr>
<wbr></wbr>
3.
至此,综合1和2,phonegap对于本地方法的调用的结构已经清晰。
在对javascript的执行上,phonegap给我们提供了一个有别于addJavaScriptInterface<wbr></wbr>的另外一种方法。在phonegap1.0之前,它就是采用原生的addJavaScriptInterface<wbr></wbr>这种方法进行调用,后来才改成xhrserver的方式。原因可能是addJavaScripteInterface是一种同步调用,对效率较低或执行时间较长的js语句,会产生阻塞。
在对本地方法的调用上,phonegap给我们提供了一个用js来调用java的插件框架,我们可以这种思路拆分出来,并且进行优化,我目前觉得phonegap对插件的使用上还是比较死板,本地方法的调用都集成在phonegap.js中,实际上还是很难由用户添加新功能,如果不改动此主要js文件的情况下。如果配合反射等手段,我们可能可以做到真正的插件化本地调用,用在我们的代码中。
分享到:
相关推荐
phonegap android在线更新插件,兼容android7.0下载后安装闪退的问题;详细使用见README.md文件。
PhoneGap Android is an Android application library that allows for PhoneGap-based projects to be built for the Android Platform. PhoneGap-based applications are, at the core, an application written in...
phonegap在android的录音照相录像demo,功能简单易懂,主要看懂html里的就行,小白笔记大神勿喷
PhoneGap android的Toast插件,使用方法不用介绍了,用phoneGap开发android应用的人都知道,希望对大家有帮助。
Phonegap Android java 系统推送例子
android+js+css+html+jquery实现的android程序。详细见代码
phoneGap-android实现拍照和选择图库中的图片功能。绝对可以运行。
android+Phonegap开发环境搭建android+Phonegap开发环境搭建android+Phonegap开发环境搭建android+Phonegap开发环境搭建
PhoneGap Android插件 调用toast 和 notification 里面是 java js 源码和配置文件. 使用方式和其他phonegap插件一致
phonegap in android.
android之PhoneGap入门实例http://blog.csdn.net/beifengdelei/article/details/7702461
一个完整的phonegap与android的例子。用在pad上,包含一些自定义插件。
4.复制phonegap中android目录下的xml文件夹到 /res下 5.android默认的项目是针对native app的,所以要用web app(cordova)的话,必须修改它的引用文件。 5.1引用加载cordova-1.7.0.jar,这时候可以按F5刷新工程。 ...
通过自定义plugin插件实现了javascript与Android的交互。
phonegap android plugin 里面有些插件不支持3.*.*,需要自己移植一下。
phonegap-android-master
phonegap选择文件及上传文件插件实现,android studio工程,导入的时候请选择upload/platforms/android目录;选择文件兼容android6.0+闪退的情况,上传文件只是提交文件到服务器,服务器端的上传方法需要自己实现。
实现android平台phonegap登录例子,内容简单,适合初学者.
使用phonegap调用android插件实现GPS实时定位
PhoneGap html5 拍照上传DEMO