用PhoneGap封装后的程序有一些瑕疵,比如启动时黑屏,菜单按钮和返回按钮不好控制等。

PhoneGap也在github提交的它的源码(版本:2.8):

https://github.com/apache/cordova-android/tree/master/framework/src/org/apache/cordova

先说loadingpage,其实在phonegap提供的api中已经提供了设置的方法:

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setIntegerProperty("loadUrlTimeoutValue", * );
//设定loadingpage背景
super.setIntegerProperty("splashscreen", R.drawable.bg); //判断网络是否可用,不可用直接转到相关错误提示页面
ConnectivityManager cwjManager=(ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cwjManager.getActiveNetworkInfo();
if(null != netInfo && netInfo.isAvailable()){
super.loadUrl("http://xx.com/index.html", );
}else{
super.loadUrl("file:///android_asset/www/error.html", );
}
}

注意在访问网络地址时,必须调用有2个参数的loadurl方法才会显示背景图,即:

super.loadUrl("http://xx.com/index.html", 10000);

通过看CordovaActivity(你的Activity需要集成的基础Activity)的源码知道2个参数和1个参数的loadurl内容是不一样的。

这样设置后,又出现了一个问题,第二个参数timeout表示背景图显示的时间,不管页面是否加载完,总是会显示给定的时间,哪怕你的应用1秒就已加载完成了。通过大量的观察后,发现在logcat里面有这么一句:

06-24 15:17:35.060: D/DroidGap(30429): onMessage(onPageFinished,http://xx.com/index.html)

推测在页面加载完成后,会调用CordovaActivity的onMessage方法,并且参数分别是onPageFinished和http://xx.com/index.html。在结合源码,发现在onMessage中对有些参数id的动作有所处理,如“splashscreen”,“spinner”。但是没有对“onPageFinished”的处理。

所以考虑在自己的activity中重写该方法,对“onPageFinished”有所处理:

@Override
public Object onMessage(String id, Object data) {
if(id.equals("onPageFinished")){
this.removeSplashScreen();
return null;
}
return super.onMessage(id, data);
}

这样loadingpage的显示时间就会和加载时间相同了。

对于按钮的控制:

通常会对app做"再按一次退出程序"的处理,但是发现用通常的重写keydown事件的方法时,程序并不是那么听话。在其他页面时,会返回,不能在返回时就退出了。内嵌浏览器的痕迹明显。通过观察源码也可以知道,在CordovaActivity中有一个继承自WebView的CordovaWebView。在观察CordovaWebView的源码,发现它对程序的keydown和keyup的事件重写了:

    @Override
public boolean onKeyUp(int keyCode, KeyEvent event)
{
// If back key
if (keyCode == KeyEvent.KEYCODE_BACK) {
// A custom view is currently displayed (e.g. playing a video)
if(mCustomView != null) {
this.hideCustomView();
} else {
// The webview is currently displayed
// If back key is bound, then send event to JavaScript
if (this.bound) {
this.loadUrl("javascript:cordova.fireDocumentEvent('backbutton');");
return true;
} else {
// If not bound
// Go to previous page in webview if it is possible to go back
if (this.backHistory()) {
return true;
}
// If not, then invoke default behaviour
else {
//this.activityState = ACTIVITY_EXITING;
//return false;
// If they hit back button when app is initializing, app should exit instead of hang until initilazation (CB2-458)
this.cordova.getActivity().finish();
}
}
}
}
// Legacy
else if (keyCode == KeyEvent.KEYCODE_MENU) {
if (this.lastMenuEventTime < event.getEventTime()) {
this.loadUrl("javascript:cordova.fireDocumentEvent('menubutton');");
}
this.lastMenuEventTime = event.getEventTime();
return super.onKeyUp(keyCode, event);
}
// If search key
else if (keyCode == KeyEvent.KEYCODE_SEARCH) {
this.loadUrl("javascript:cordova.fireDocumentEvent('searchbutton');");
return true;
}
else if(keyUpCodes.contains(keyCode))
{
//What the hell should this do?
return super.onKeyUp(keyCode, event);
} //Does webkit change this behavior?
return super.onKeyUp(keyCode, event);
}

//由于退出功能在onkeyup,所以只关心onkeyup

还是老办法,自己实现一个继承自CordovaWebView的webview,重写onkeyup方法:

import java.util.Timer;
import java.util.TimerTask; import org.apache.cordova.CordovaWebView; import android.content.Context;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.Toast; /**
* 当按下返回按钮是提示再按退出,而不是返回
* @author Lee
*/
public class NobackWebView extends CordovaWebView { public NobackWebView(Context context) {
super(context);
} public NobackWebView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public NobackWebView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} public NobackWebView(Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
super(context, attrs, defStyle, privateBrowsing);
} @Override
public boolean onKeyUp(int keyCode, KeyEvent event){ if (keyCode == KeyEvent.KEYCODE_BACK) {
exitBy2Click();
return true;
}else{
return super.onKeyUp(keyCode, event);
}
} public void toastMessage(String msg, int duration) {
Toast.makeText(this.getContext(), msg, duration).show();
} private static Boolean isExit = false; private void exitBy2Click() {
Timer tExit = null;
if (isExit == false) {
isExit = true; // 准备退出
toastMessage("再按一次退出程序", 2000);
tExit = new Timer();
tExit.schedule(new TimerTask() {
@Override
public void run() {
isExit = false; // 取消退出
}
}, 2000); // 如果2秒钟内没有按下返回键,则启动定时器取消掉刚才执行的任务
} else {
System.exit(0);
}
} }

这样在app中就可以实现"再按一次退出程序"的功能了。

还剩下最后一个步骤就是将CordovaActivity中的webview替换成自己的webview,老办法,在自己的activity中重写init方法:

    @Override
public void init() {
//只是把源码中的CordovaWebView换成NobackWebView,其他还是源码
CordovaWebView webView = new NobackWebView(this);
CordovaWebViewClient webViewClient;
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB) {
webViewClient = new CordovaWebViewClient(this, webView);
} else {
webViewClient = new IceCreamCordovaWebViewClient(this, webView);
}
this.init(webView, webViewClient,
new CordovaChromeClient(this, webView));
}

这样就大功告成了。菜单按钮的操作也是类似的方法,就不介绍了,如果像实现返回按钮还是执行返回动作,只是在首页时才提示退出,可以参考源码,在重写的方法中调用返回方法,在首页时退出。

以上的方法只是针对js不熟或不喜欢js处理的同学,因为PhoneGap在js代码中提供的相似的功能,比如loadingpage的关闭可以在设备初始化后调用:navigator.splashscreen.hide();方法。菜单,返回按钮的操作可以在js中注册等,这些网上应该比较多,就不介绍了。

Android用PhoneGap封装webapp在android代码中实现连按退出和loadingpage的更多相关文章

  1. Android OpenGL ES(六)----进入三维在代码中创建投影矩阵和旋转矩阵

    我们如今准备好在代码中加入透视投影了. Android的Matrix类为它准备了两个方法------frustumM()和perspectiveM(). 不幸的是.frustumM()的个缺陷,它会影 ...

  2. Android 之px于dp在Java代码中的转换

    现在由于用到了,使用代码进行动态布局,所以需要进行px于dp之间的转换. 现将其封装为方法,以便于调用. public int DpToPx(Context context,float dp){ fl ...

  3. Android学习笔记_52_全面了解Android开发规范:性能及UI优化

    一.Android编码规范 1.java代码中不出现中文,最多注释中可以出现中文 2.局部变量命名.静态成员变量命名 只能包含字母,单词首字母出第一个外,都为大写,其他字母都为小写 3.常量命名 只能 ...

  4. Android源码阅读技巧--查找开发者选项中显示触摸操作源码

    在开发者模式下,在开发者选项中,可以勾选“显示触摸操作”,然后只要点击屏幕就会在点击的位置有圈圈显示.如何找到绘制圈圈的代码部分,有什么技巧来阅读代码量这么大的android系统源码呢?以下请跟着小老 ...

  5. 代码二次封装-xUtils(android)

    通常我们会引用很多lib 而且会出现lib 与我们的功能仅仅差一点点 这种情况我们最好不要去改动源代码 而是进行二次封装 举例我使用 xUtils的二次封装 此处说明我是搞ios的 这个是androi ...

  6. (转载)Android支付宝支付封装代码

    Android支付宝支付封装代码 投稿:lijiao 字体:[增加 减小] 类型:转载 时间:2015-12-22我要评论 这篇文章主要介绍了Android支付宝支付封装代码,Android支付的时候 ...

  7. phonegap(cordova) 自己定义插件代码篇(五)----android ,iOS 集成微信登陆

    统一登陆还是非常有必要的,安全,放心.代码 /*cordov 微信自己定义插件*/ (function (cordova) { var define = cordova.define; define( ...

  8. (转)android平台phonegap框架实现原理

    (原文)http://blog.csdn.net/wuruixn/article/details/7405175 android平台phonegap框架实现原理 分类: Android2012-03- ...

  9. Android 将HTML5封装成android应用APK文件的几种方法

    越来越多的开发者热衷于使用html5+JavaScript开发移动Web App.不过,HTML5 Web APP的出现能否在未来取代移动应用,就目前来说,还是个未知数.一方面,用户在使用习惯上,不喜 ...

随机推荐

  1. PyQt4网格布局

    最通用的布局类别是网格布局(QGridLayout).该布局方式将窗口空间划分为许多行和列.要创建该布局方式,我们需要使用QGridLayout类. #!/usr/bin/python # -*- c ...

  2. Android TextView实现跑马灯

    TextView实现跑马灯的效果:例子一: 这个例子可以解决给一个TextView实现跑马灯的效果,但是不能解决给所有的TextView实现跑马灯的效果. <TextView android:l ...

  3. poj_1743 后缀数组

    题目大意 给定一串数字,长度为N.定义数字中的某个连续的子串为一个"theme",只要子串满足: (1)长度 >= 5 (2)和该子串相同或者该子串的“变种串”在整串数字中出 ...

  4. 关于Android图片资源瘦身的奇思妙想

    版权声明:本文由况鹰原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/77 来源:腾云阁 https://www.qcloud ...

  5. JavaWeb温习之HttpServletResquest对象

    HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法,可以获得客户端请求的所有信息. 1 ...

  6. myBatis调用postgreSQL存储过程

    1.调用没有OUT参数的存储过程: 创建存储过程: create or replace function get_code(a1 varchar(32)) returns varchar(32) as ...

  7. 【BZOJ2661】[BeiJing wc2012]连连看 最大费用流

    [BZOJ2661][BeiJing wc2012]连连看 Description 凡是考智商的题里面总会有这么一种消除游戏.不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏.我们的规则是,给 ...

  8. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  9. android极光推送

    版权声明:本文为博主原创文章,未经博主允许不得转载. Android开发记录18-集成推送服务的一点说明 关于推送服务,国内有很多选择,笔者也对它们进行了一个详细的对比,一般我们产品选择推送服务主要考 ...

  10. NIO之Buffer的clear()、rewind()、flip()方法的区别

    Java的NIO中有关Buffer的几种常用方法比如clear,rewind和flip到底有哪些区别.下面给大家这三种方法的源码,方便大家记忆.clear()方法用于写模式,其作用为情况Buffer中 ...