Android Webview H5资源本地化
一. 创建读取资源项目独立模块
1. 项目依赖的好处
符合模块化的思想,他们相互独立。一个项目持有另一个项目的引用,修改更加方便。
(注:compile project编译引用的项目其内容必须包含有java代码、xml布局文件、AndroidManifest等,而且还要在项目的setting.gradle中用include的形式声明引用)
2. 操作步骤导入项目ProjectR
被依赖的项目ProjectR不需要任何改动!
1. 在需要使用的项目中的settings.gradle
添加配置
include ':ProjectR'
project(':ProjectR').projectDir = new File(settingsDir,'../../ProjectR/')
include ':ProjectR:app'
2. 在需要使用的项目中的Module
中添加需要引入的library
dependencies {
...
compile project(path: ':ProjectR:app')
...
}
3. 设置正确的被依赖的项目路径
project(':BProject').projectDir = new File(settingsDir,'../../ProjectR/')
其中 new File(settingsDir,'../../ProjectR/')
参数说明:
参数一: settingsDir 指的是相对于 settings.gradle 文件所在路径
参数二: 填写被依赖项目的路径,**../**表示上级目录,所以根据自己的路径修改
3. 坑(注意)
如果你不小心填错了被依赖项目的路径,而且还点了同步项目。那么可能会在Project和Module 目录下生成类似 xxx_xxx.iml 的文件,如果异常文件存在,后面就算你的路径配置正确也可能同步不成功,不断的提示错误。这是你只需要删除上叙文件同步项目即可。
4. Assets资源文件读取和AssetManager
AssetManager管理对assets文件夹资源的访问,它允许你以简单的字节流的形式打开和读取和应用程序绑定在一起的原始资源文件。主要用到list()及open()方法。
注意:要创建一个assets文件夹和java文件夹同级,然后再asset创建一个文件夹命H5Res,此句不要assets不然会找不到文件异常处理
InputStream stream = assetManager.open("H5Res/" + resUrl);
finalString[] list(Stringpath) 返回指定路径下的所有文件及目录名,path是相对路径,是assets子目录。
finalInputStream open(String fileName) 使用 ACCESS_STREAMING模式打开assets下的指定文件,fileName是相对路径,是assets子目录。
finalInputStream open(String fileName,int accessMode) 使用显示的访问模式打开assets下的指定文件。
5. ProjectR项目主要代码
import android.app.Activity; import android.content.res.AssetManager; import android.webkit.MimeTypeMap; import android.webkit.WebResourceResponse; import android.webkit.WebView; import java.io.FileNotFoundException; import java.io.InputStream; public class LocalAssets{ private static LocalAssets _instance = null; public static LocalAssets getInstance() { return _instance != null ? _instance : (_instance = new LocalAssets()); } private Activity mainContext = null;
// 用于保存请求链接截取出的本地路径 private String resUrl = ""; /** * 初始化此类获得上下文 */ public boolean init(Activity context) { mainContext = context; return true; } /** * 拦截webview请求地址换成读取本地文件 */ public WebResourceResponse doLoadRes(WebView view, String url) { try { // 根据url判断是否是需要加载的本地资源进行拦截替换响应资源
if (url === 'assets') { AssetManager assetManager = mainContext.getAssets(); InputStream stream = assetManager.open("H5Res/" + resUrl); WebResourceResponse response = new WebResourceResponse( MimeTypeMap.getSingleton().getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(url)) , "UTF-8", stream ); return response; } } catch (FileNotFoundException e) { } catch (Exception e) { e.printStackTrace(); } return null; } }
二. 主项目代码
1. 将需要本地化的资源放入assets/H5Res文件夹下。
2. 设置完webview后初始化导入的库:
LocalAssets.getInstance().init(this);
3. 设置webview拦截请求:
@Override public WebResourceResponse shouldInterceptRequest(WebView view, String url) { WebResourceResponse resp = LocalAssets.getInstance().doLoadRes(view, url); if (resp != null) { return resp; } return super.shouldInterceptRequest(view, url); } @Override @RequiresApi(Build.VERSION_CODES.LOLLIPOP) public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) { WebResourceResponse resp = LocaalAssets.getInstance().doLoadRes(view, request.getUrl().toString()); if (resp != null) { return resp; } return super.shouldInterceptRequest(view, request); }