为chromium android增加file:///android_asset/支持

出于测试的目的,我希望将一些测试页面打包到浏览器中。chromium中资源打包成pak文件,然后通过一些特殊的接口读取,而android程序则通常将资源放到assets下,通过AssetManager类来访问。在Android中提供的WebView API中,支持file:///android_asset/协议访问assets下的页面。但尝试了一下chromium for android,还没有提供,所以考虑为chromium android增加file:///android_asset支持。得益于chromium在设计上的灵活与可扩展性,增加file:///android_asset/协议支持比想象中要简单得多。

要增加新的协议支持,首先需要实现一个Interceptor(拦截器)的抽象类,该类定义于文件src/net/url_request/url_request_job_factory.h中,其中有一个重要的方法:

URLRequestJob* MaybeIntercept(URLRequest* request, NetworkDelegate* network_delegate);

实现了该抽象类后,还需要注册到URLRequestJobFactory中,注册方法为:

void AddInterceptor(Interceptor* interceptor);

让人感到更舒服的是,chromium中android_webview中已经有参考实现,所以只需把相关的实现(android_protocol_handler.cc, android_stream_reader_url_request_job.cc, AndroidProtocolHandler.java等文件)搬过来,然后在合适的位置注册到URLRequestJobFactory就可以了。

为chromium android增加file:///android_asset/支持》上有 5 条评论

  1. 冷暖自知

    楼主你好,我最近在做基于contentshell的android浏览器开发,在使用ContentView中的loadUrl(LoadUrlParams params)方法加载本地的网页(其中params通过LoadUrlParams.createLoadDataParamsWithBaseUrl方法创建)时,显示中文为乱码,中文是从android资源文件中加载,同时也无法加载图片资源。具体传入的参数是参考WebView中的loadDataWithBaseURL方法,请帮忙分析下,问题可能出在哪里?谢谢!

    回复
  2. alex 文章作者

    显示为乱码可能是由于网页编码的问题,android默认采用utf-8的编码。如果是从资源文件中加载,图片路径就会不正确,所以需要采用文中的方法从asset读取

    回复
    1. 冷暖自知

      现在搞清楚,如果直接将raw目录下的html网页以字符串的形式读出(以UTF-8格式编码)并通过ContentView中的loadUrl(LoadUrlParams params)方法加载,网页中的中文是可以正常显示的,但是如果通过String.format()方法对字符串进行格式化之后在通过loadUrl(LoadUrlParams params)方法加载,那么中文的就显示为乱码。
      现有结论是通过Java String类的方法操作过字符串之后,网页中的中文就无法正常显示了。
      PS:同样的代码Android WebView可以正常显示网页和其中的中文。
      现在正在尝试将读出的字符串以html格式保存为文件,然后以本地文件路径加载这张网页。

      回复
  3. 冷暖自知

    搞定了!原来是LoadUrlParams.createLoadDataParamsWithBaseUrl()方法里的charset参数没传,默认是null,charset改为”UTF-8″就可以了。

    回复
  4. 饭饭风

    根据你上面所说的已经找到了相印的文件,不过有几点问题想问问你:
    1.关于在合适位置注册,我在源码里面只找到了void InitializeURLRequestContext(
    net::URLRequestContextGetter* context_getter,
    AppCacheService* appcache_service,
    FileSystemContext* file_system_context,
    ChromeBlobStorageContext* blob_storage_context)这个函数,
    是不是在这个函数里面调用android_protocol_handler.cc文件里面的CreateAndroidRequestJobFactory()来替换 net::URLRequestJobFactory* job_factory =
    const_cast(context->job_factory());就行了?
    2.关于函数AddInterceptor()这个方法,是不是要把AssetFileProtocolInterceptor对象加进去呢?但是在调用CreateAndroidRequestJobFactory这个函数的时候已经新建了AssetFileProtocolInterceptor对象了,那我们还需要调用 InitializeURLRequestContext()函数里面调用AddInterceptor()函数?

    回复

发表评论

电子邮件地址不会被公开。

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>