android开发AngularJS & WebView 混合应用遇到的问题

混合应用,可以理解为html5 + app,我个人认为这种开发方式很适合小型企业,中大型的一般都有完整的开发团队,所以他们开发原生的根本不是问题,但是为了给企业节约维护成本,比如公司的一个官网、门户网站、网店等等,都可以使用混合应用去实现,app的WebView框架比较简单,一般开发出来只需要维护html5网站就可以了,更新基本不涉及到app的源代码,这样公司只需要2个程序员基本可以搞定。

创建简单的混合应用,首先需要一个WebView控件:

mWebView.loadUrl(uri);
mWebView.setWebViewClient(new WebViewClient());//WebViewClientServer类可以拦截webview的一些错误,可以在这里面拦截后进行显示;

可能你需要对应用进行简单的配置:
WebSettings webSettings =  mWebView.getSettings();
webSettings.setJavaScriptEnabled(true); //允许javascript代码
webSettings.setCacheMode(WebSettings.LOAD_NO_CACHE);//关闭缓存
webSettings.setAllowFileAccess(true);//允许读取文件
webSettings.setAllowContentAccess(true);
webSettings.setSupportZoom(false);//禁止缩放
webSettings.setDomStorageEnabled(true);//开启本地数据库储存
webSettings.setDatabaseEnabled(true);
webSettings.setAppCachePath(getApplicationContext().getCacheDir().getAbsolutePath());
webSettings.setAppCacheEnabled(true);

又或许,你需要:
mWebChromeClientServer = WebChromeClientServer.getInstance(mContext,mToolbar,mRefresh);
mWebView.setWebChromeClient(mWebChromeClientServer);
WebChromeClient我把它直接改写了一个类,因为太多方法需要在里面实现了。
最主要的可能是onShowFileChooser这个方法,就是input type=file的时候需要用到的,但是只支持4.4.2以上的系统,我测试过4.4.2以下无效,网上说<4.4.2系统的是调用
openFileChooser这个方法,但是别找了,也无效,最后不得不放弃,但是可以使用js调java的接口,然后通过app进行图片上传,传送完毕后用WebView.loadUrl(Javascript function);方法把服务器返回的数据传输给网页端。
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
 if (mFilePathCallback != null) {
 mFilePathCallback.onReceiveValue(null);
 }
 mFilePathCallback = filePathCallback;

 startOnResult(FILECHOOSER_RESULTCODE5);

 return true;
}

/**
 * 由于android < 5.0 以下均无法使用onShowFileChooser的方法,所以,这里直接使用js调用
 * @param uploadMsg
 */
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
 if (mUploadMessage != null) {
//mUploadMessage.onReceiveValue这个方法我实现了,把数据传递给网页端,这里的代码保持跟onShowFileChooser一样,为了让其他人方便理解
 mUploadMessage.onReceiveValue(null);
 }

 mUploadMessage = uploadMsg;
 startOnResult(FILECHOOSER_RESULTCODE4);
}

再智能一点,加入javacript对象调java对象:

mWebView.addJavascriptInterface(new WebJavaScroptInterface(mContext,mWebChromeClientServer,mWebView),"JsObject");
WebJavaScroptInterface是我写的一个java类,所有的方法,只要使用public的方法并且注释@JavascriptInterface,网页端是可以直接调用的,JsObject就是调取的对象名字。

如果上传文件到最后都用不了,可以试试在proguard-rules.pro文件中增加几行代码:
-keep class android.webkit.JavascriptInterface {*;}
-keepclassmembers class * extends android.webkit.WebChromeClient {
   public void openFileChooser(...);
}

-keepclassmembers class com.suisuilam.app.interfaces.WebJavaScroptInterface {
   public *;
}

 

Leave a Comment