现在很多app都是跟web页面混编的。除了原生控件以外,有些功能页面直接用web端的,用webview加载后台同事写的功能,避免重复开发。但是webview加载远程url速度会比较慢,也比较影响用户体验,有些公司产品经理会要求使用html和css、js、jpg等都用本地的来读取,webview只需要加载远程数据,这样既节省了流量,也会大大提升运行速度。
但是这就有两个问题了:
①登陆问题
②访问url如何加载本地web资源
最近做项目的时候,遇到了这个需求,webview加载本地资源,国内帖子少之又少,这个问题辗转了一个多星期,才得以解决,现在把主要的核心代码贴出来,以便后人查阅
//登陆获取session,保存起来,之后然后同步session就可以实现登陆了
RequestParams params = new RequestParams("你的登陆地址");
HashMap
signMap = new HashMap
();
params.addBodyParameter("json", url_post);//json里面包含自己的用户名、加密的密码等信息
//发送到后台验证,我这里是使用xutil3 做请求,也可以改成自己的
x.http().post(params, new Callback.CacheCallback
() {
@Override
public boolean onCache(String result) {
return false;
}
@Override
public void onSuccess(String result) {
Log.e("--------发送到服务器接收成功!!!!!!!!!!!!!", "result:" + result + "");
//Toast.makeText(context, result + "", Toast.LENGTH_LONG).show();
//-----------------------获取session-----------------------//
DbCookieStore instance = DbCookieStore.INSTANCE;
List
cookies = instance.getCookies();
for (int i = 0; i < cookies.size(); i++) {
//保存session
HttpCookie cookie = cookies.get(i);
MyCookieStore.cookies = cookie;
if ((cookies.get(i) + "").contains("JSESSIONID")) {
MyCookieStore.SessionId = cookies.get(i).toString().replace("JSESSIONID=", "");
break;
}
}
//-----------------------获取session-----------------------//
//我们的服务器返回成功啦!正式进入登陆主界面
Intent intent = new Intent(context, MainActivity.class);
context.startActivity(intent);
}
@Override
public void onError(Throwable ex, boolean isOnCallback) {
}
@Override
public void onCancelled(CancelledException cex) {
}
@Override
public void onFinished() {
}
});
//保存cookie的类
public class MyCookieStore {
public static CookieStore cookieStore=null;
public static HttpCookie cookies=null;
public static String SessionId = "";
}
//主MainActivity
public class MainActivity extends Activity{
private Webview webview;
private BMHWebViewClient mBMHWebViewClient;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//webview = (WebView) root.findViewById(R.id.wv_mainui);
WebSettings webSettings = webview.getSettings();
webSettings.setDefaultTextEncodingName("GBK");//设置字符编码
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setAllowFileAccess(true);// 设置允许访问文件数据
webSettings.setAllowContentAccess(true);
webSettings.setSupportZoom(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setDomStorageEnabled(true);
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT);
webSettings.setAppCacheEnabled(true);
webSettings.setDatabaseEnabled(true);
webSettings.setJavaScriptEnabled(true);//滚动条风格,为0指滚动条不占用空间,直接覆盖在网页上
mBMHWebViewClient = new BMHWebViewClient(this);
webview.setWebViewClient(mBMHWebViewClient);//网页跳转监听
String mainUrl = "htpp://192.168.1.1/html/index/index.html"";//url远程地址,改成你的域名
webview.loadUrl(mainUrl);
CookieUtil.syncCookie(getContext(), mainUrl);//同步session实现登陆
}
}
public class BMHWebViewClient extends WebViewClient {
private Activity activity;//当前的活动类
/**
* 监听webview的跳转链接,处理连接本地化、过滤地址
*
* @param activity 活动页上下文
*/
public BMHWebViewClient(Activity activity) {
this.activity = activity;
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
}
//webview每次访问html、css、图片、js、font资源的时候,都回来这里过滤,在这个方法里面,把本需要远程访问的资源,替换成本地读取
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, final String url) {
WebResourceResponse response = null;
try {
String newUrl;//本地的路径
newUrl = url.replace(activity.getString(R.string.url_head), activity.getFilesDir().getPath());//url_head域名,把远程地址替换成files文件夹下的对应资源,如:远程地址需要加载:url是http://www.baidu.com/html/index.html,newUrl就为:/data/data/包名/files/html/index.html
//Log.v("NEWURL--------------------------->",newUrl);
//请求不同的远程资源,生成不同类型的文件返回。
String type;
if (newUrl.contains(".js")) {
type = "text/javascript";
} else if (newUrl.contains(".png")) {
type = "image/png";
} else if (newUrl.contains(".html")) {
type = "text/html";
} else if (newUrl.contains(".css")) {
type = "text/css";
} else if (newUrl.contains(".jpg")) {
type = "image/jpeg";
} else {
return null;
}
FileInputStream input = new FileInputStream(newUrl);
response = new WebResourceResponse(type, "UTF-8", input);
} catch (IOException e) {
//e.printStackTrace();
}
//如果返回null,webview继续访问远程的资源,非null使用本地的资源,不再从远程取
return response;
}
public class CookieUtil {
/**
* 将cookie同步到WebView
*
* @param context 上下文
* @param url WebView要加载的url
*/
public static void syncCookie(Context context, String url) {
try {
CookieSyncManager syncManager = CookieSyncManager.createInstance(ZebraApplication.getContext());
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeAllCookie();
String host = ZebraApplication.getContext().getResources().getString(R.string.url_head);
cookieManager.setCookie(host, "JSESSIONID="+ MyCookieStore.SessionId);
syncManager.sync();
String newCookie = cookieManager.getCookie(url);
} catch (Exception e) {
Log.e("Nat: webView.syncCookie failed", e.toString());
}
}
}