用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. JAVA Comparator 接口排序用法

    java的比较器有两类,分别是Comparable接口和Comparator接口. 在为对象数组进行排序时,比较器的作用非常明显,首先来讲解Comparable接口. 让需要进行排序的对象实现Comp ...

  2. AndroidのBuild工具之Ant动手实践

    好久没有写博客了,没半年也应该有几个月了.在工作上的项目遇到过很多问题或者说积累了不少经验,曾经都蛮想发到博客留个纪念什么的,不求可以为别人获得点经验技巧,只求在多年后遇到同样的问题可以找到个记录.但 ...

  3. 安装Memcache的PHP扩展

    查看memcached是否启动 # ps -ef | grep memcached 安装Memcache的PHP扩展 1.在http://pecl.php.net/package/memcache 选 ...

  4. [Bootstrap] install Bootstrap framework in window 7 by npm

    Install with npm You can also install Bootstrap using npm: $ npm install bootstrap require('bootstra ...

  5. OC开发_Storyboard——block和动画

     一.协议 @optional :可选的 @requied :必须实现的  二.block 代码块 1. 以一个^开头,然后是参数,然后是一个大括号,包含我们的代码块 [aDictionary enu ...

  6. 网络下载功能实现(downloader ) ---- HTML5+

    模块:downloader Downloader模块管理网络文件下载任务,用于从服务器下载各种文件,并支持跨域访问操作.通过plus.downloader获取下载管理对象.Downloader下载使用 ...

  7. xp系统报错 windows explorer has encountered a problem and needs to close.We are sorry for the inconvenience

    xp系统遇到问题: 打开某个软件提示报错信息, windows explorer has encountered a problem and needs to close.We are sorry f ...

  8. Linux系统下tomcat安装配置

    Linux系统中Tomcat的安装配置. 前提JDK已经安装好. 安装 下载tomcatwget http://mirrors.cnnic.cn/apache/tomcat/tomcat-8/v8.0 ...

  9. Publish over SSH插件安装

    1 Publish over SSH插件安装 打开Jenkins的“系统管理>管理插件”,选择“可选插件”,在输入框中输入“Publish over SSH”进行搜索,如果搜索不到可以在“已安装 ...

  10. CentOS 6.7 配置LVM (逻辑卷管理)

    LVM 简介 LVM是逻辑盘卷组管理 (Logical Volume Manager) 的简称. LVM是建立在硬盘和分区之上的一个逻辑层,来提高磁盘分区管理的灵活性,在一定程度上解决普通磁盘分区带来 ...