用PhoneGap封裝後的程序有一些瑕疵,好比啓動時黑屏,菜單按鈕和返回按鈕很差控制等。javascript
PhoneGap也在github提交的它的源碼(版本:2.8):html
https://github.com/apache/cordova-android/tree/master/framework/src/org/apache/cordovajava
先說loadingpage,其實在phonegap提供的api中已經提供了設置的方法:android
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setIntegerProperty("loadUrlTimeoutValue",30 * 1000); //設定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", 10000); }else{ super.loadUrl("file:///android_asset/www/error.html", 3000); } }
注意在訪問網絡地址時,必須調用有2個參數的loadurl方法纔會顯示背景圖,即:git
super.loadUrl("http://xx.com/index.html", 10000);github
經過看CordovaActivity(你的Activity須要集成的基礎Activity)的源碼知道2個參數和1個參數的loadurl內容是不同的。web
這樣設置後,又出現了一個問題,第二個參數timeout表示背景圖顯示的時間,無論頁面是否加載完,老是會顯示給定的時間,哪怕你的應用1秒就已加載完成了。經過大量的觀察後,發如今logcat裏面有這麼一句:apache
06-24 15:17:35.060: D/DroidGap(30429): onMessage(onPageFinished,http://xx.com/index.html)api
推測在頁面加載完成後,會調用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中註冊等,這些網上應該比較多,就不介紹了。