PhoneGap android方向解析

PhoneGap源码解析



Phonegap的核心是插件。在phonegap的概念中,一切调用native功能,都被封装成插件(plugin),由PlugInManager来管理。而在PhoneGap的使用方法中,PlugInManager是由重写过的Activity,即DroidGap来调用的。


本文主要涉及到的类是PlugInManager,PlugIn,DroidGap, CallbackServer,主要探讨phonegap源码的实现和可供我们结合使用的方式。


1.

DroidGap继承于PhonegapActivity,而PhonegapActivity继承于activity。


PhonegapActivity是一个抽象类,其中方法不多,列举如下:


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 setActivityResultCallback(IPlugin plugin);

abstract public void setActivityResultCallback(IPlugin plugin);


其中sendJavascript和loadUrl是phonegap的关键方法。还有两个关键的继承类,GapViewClient和GapClient。



sendJavascript会被具体的PlugIn回调,例如storage这个插件,在startPlaying方法中,会调用自己的sendJavascript,然后这个sendJavascript会继续调用DroidGap的sendJavascript,然后继续调用CallbackServer的sendJavascript方法,添加到CallbackServer的javascript linkedlist中去。


loadUrl事实上是调用了对应的webview的loadUrl,做了一些额外的处理。loadUrl中调用了loadUrlIntoView方法,其中在加载url之前,初始化了CallbackServer, pluginManager,还为webview设置了超时时间。


DroidGap中,GapViewClient是对WebviewClient的继承。


主要是针对拨打电话,调用地图,发送邮件等本Intent的方式进行拦截和调用。这部分代码我们可以直接copy过来使用。


DroidGap中,GapClient是对WebChromeClient的继承。

在onJsAlert和onJsConfirm方法中,使用Dialog来代替js的默认实现。

在onJsPrompt中,对满足以下条件


(url.startsWith("file://") || url.indexOf(this.ctx.baseUrl) == 0 || isUrlWhiteListed(url))

1).file://开头的本地文件

2).在请求的url域名内

3).在配置的url白名单内,白名单是一个配置文件,通过addWhiteListEntry添加。 放在xml目录下的phonegap.xml文件。默认配置了http://127.0.0.1。


并且满足例如"gap:"等情况。进行了自行重写。


重写条件如下:

1)满足"gap:"开头的,调用plugInManager进行处理。此时每个gap:后面的内容会对应一个具体的调用本地操作的功能。例如摄像头,本地存储等。

2)满足"gap_poll:"开头的,调用callbackServer.getJavascript();

3)满足"gap_callbackServer:"开头的,调用callbackServer.restartServer()等操作。

4)满足"gap_init:"开头的,将webview设置为不可见


其他情况,依然是以一个dialog形式弹出。


重点说一下重写条件1)

调用PlugInManager的时候,每次都会重新开启一个线程,在开启线程前还做了一次同步检查,保证同一时刻同一个插件只被调用一次。在线程中,调用对一个PlugIn,执行PlugIn的exec方法,执行具体功能。执行完成之后,返回一个PluginResult。其中以status标示了本地功能调用结果。如果调用成功或者无结果(也可以说是另一方面的调用成功,比如notifacation这种功能),则调用DroidGap的sendJavaScript方法,通知给CallbackServer。


另外还重写了onPageFinish等一系列方法,我们都可以参考。


按我的理解,在这个部分的写法的好处,从模式上讲是将本地功能模块化,明晰化,封装的比较好,各自调用自己的功能,从执行效率上讲避免了主线程执行功能,但是在异步线程中操作数据库等功能,会不会引起问题,这个可能也是未来我们结合phonegap的方式来处理自己的程序需要注意的地方。


2.

另外一个比较重要的工具类是CallbackServer,这也是phonegap框架后来改名为CallBack的原因。它是一个客户端本地实现的 XHRServer。在调用完js中的代码,执行完本地的功能后,需要给js发送一个反馈,也就是调用sendJavaScript方法。


初始化CallbackServer的时候,会建立一个泛型为String的LinkedList,用于保存javascript代码。CallbackServer在外部被调用最多的sendJavascript方法,实现中就是将发送过来的Js语句,添加到这个LinkedList中。

如果要加载的url不是以file://开头,就会建立一个新的线程,CallbackServer本身是实现了Runnable接口的,这个线程就以this作为参数。同时start这个线程。

所以,在整个CallbackServer中,最核心的方法凸显出来了,就是Run。


Run方法中,建立了一个ServerSocket,将自己作为一个服务器来接收请求。

当LinkedList中有没有处理完的返回结果的时候,就会把链表中的最先进来的提出来,返回给客户端。没有请求来,则 10秒钟返回一个空的回复,以维持XHRServer。


在PhoneGap.js中,PhoneGap.JSCallbackPolling会被setTimeout(1)作为轮询,来访问这个CallBackServer,监听js需要处理的内容。

我个人对这个地方有些疑问,因为这么短时间的轮询,虽然是本地执行,但是会不会有效率问题,需要真正进入开发实战和测试后才能体现。



3.

至此,综合1和2,phonegap对于本地方法的调用的结构已经清晰。

在对javascript的执行上,phonegap给我们提供了一个有别于addJavaScriptInterface 的另外一种方法。在phonegap1.0之前,它就是采用原生的addJavaScriptInterface 这种方法进行调用,后来才改成xhrserver的方式。原因可能是addJavaScripteInterface是一种同步调用,对效率较低或执行时间较长的js语句,会产生阻塞。

在对本地方法的调用上,phonegap给我们提供了一个用js来调用java的插件框架,我们可以这种思路拆分出来,并且进行优化,我目前觉得phonegap对插件的使用上还是比较死板,本地方法的调用都集成在phonegap.js中,实际上还是很难由用户添加新功能,如果不改动此主要js文件的情况下。如果配合反射等手段,我们可能可以做到真正的插件化本地调用,用在我们的代码中。

转自:http://blog.csdn.net/yangdeli888/article/details/7419382

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值