webview html页面加载本地js及img src

我们的客户端软件主要部分用webview的表现形式来实现。当然这个东东有优点、缺点也不少。

今天,我们要解决的就是,如何从节省流量的角度来优化加载速度。

web页面部分,我们可能要用到jquery,但是jquery.js那个文件不小,所以我打算把它放在手机本地。

当然类似地,比较常用的img图片也可以这样做。关键是在整体上要有一个标准,并不是为了用这个技术而去做一些没意义的工作。


查了一些资料,直接用

<script type="text/javascript" charset="utf-8" src="url('file:///sdcard/js/jquery.js')"></script>

<script type="text/javascript" charset="utf-8" src="url('file:///android_asset/js/jquery.js')"></script>

是不行的。可能的原因是html页面读取客户端本地的资源,这涉及权限、安全性方面的问题,所以以file:///的形式默认是不行的。如果谁认为这样可行,并且知道怎么搞请和大家分享一下


最终我找到的方法是:用ContentProvider来读取文件。下面的代码示例来自于http://android-phpmanual.googlecode.com/svn

//LocalFileContentProvider.java

[java] view plain copy
  1. package lu.mind.androidphpmanual;  
  2.   
  3. import java.io.File;  
  4. import java.io.FileNotFoundException;  
  5.   
  6. import android.content.ContentProvider;  
  7. import android.content.ContentValues;  
  8. import android.database.Cursor;  
  9. import android.net.Uri;  
  10. import android.os.ParcelFileDescriptor;  
  11.   
  12. public class LocalFileContentProvider extends ContentProvider {  
  13.     private static final String URI_PREFIX = "content://lu.mind.androidphpmanual";  
  14.   
  15.     public static String constructUri(String url) {  
  16.         Uri uri = Uri.parse(url);  
  17.         return uri.isAbsolute() ? url : URI_PREFIX + url;  
  18.     }  
  19.   
  20.     @Override  
  21.     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {  
  22.         File file = new File(uri.getPath());  
  23.         ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);  
  24.         return parcel;  
  25.     }  
  26.   
  27.     @Override  
  28.     public boolean onCreate() {  
  29.         return true;  
  30.     }  
  31.   
  32.     @Override  
  33.     public int delete(Uri uri, String s, String[] as) {  
  34.         throw new UnsupportedOperationException("Not supported by this provider");  
  35.     }  
  36.   
  37.     @Override  
  38.     public String getType(Uri uri) {  
  39.         throw new UnsupportedOperationException("Not supported by this provider");  
  40.     }  
  41.   
  42.     @Override  
  43.     public Uri insert(Uri uri, ContentValues contentvalues) {  
  44.         throw new UnsupportedOperationException("Not supported by this provider");  
  45.     }  
  46.   
  47.     @Override  
  48.     public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {  
  49.         throw new UnsupportedOperationException("Not supported by this provider");  
  50.     }  
  51.   
  52.     @Override  
  53.     public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {  
  54.         throw new UnsupportedOperationException("Not supported by this provider");  
  55.     }  
  56.   
  57. }  

//html,并提前把js/jquery.js和img/016p.gif两个文件放在手机的sd卡里。

[javascript] view plain copy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6. <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />  
  7. <title>Insert title here</title>  
  8. <script type="text/javascript" charset="utf-8" src="content://lu.mind.androidphpmanual/sdcard/js/jquery.js"></script>  
  9.   
  10. </head>  
  11. <body>b这是一个html页面  
  12. <hr />  
  13. <hr />  
  14. <button onclick="showNote('andy')">showNote</button>  
  15. <img src="content://lu.mind.androidphpmanual/sdcard/img/016p.gif" alt="本地图片">  
  16. </body>  
  17.   
  18.   
  19. </html>  


s



本来想通过assets的形式读取的。可是也失败了。请高人指点!下面是我的代码:

[java] view plain copy
  1. //  @Override  
  2. //  public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {  
  3. //      try {  
  4. //          String path = uri.getPath();  
  5. //          return getContext().getAssets().openFd(path.substring(1)).getParcelFileDescriptor();  
  6. //      } catch (IOException e) {  
  7. //          throw new FileNotFoundException();  
  8. //      }  
  9. //  }  



s

Content Provider 基础 之URI[转]

Content Provider这个东西在Android平台上是最常用的共享数据的方法(似乎应用程序之间共享数据也只有这种方法吧,待求证)。虽然常用,但是这个东 西要理解透彻还是要先掌握一些基础的。URI就是Content Provider(简称CP)的基础。我们要标识一个CP,就必须用URI这个东东。这就类似于我们要通过网址来标识某个特定网站,实际上网址URL本身 就是一种URI。URI全称Uniform Resource Identifier, 它包括了URL和URN。而关于它们的详细解释,有心的朋友可以参考RFC3896:http://tools.ietf.org/html /rfc3986。URI不仅可以标识特定CP,还可以标识CP中特定的数据库表,就好像URL不仅可以标识特定网站,也可以标识这个网站某个特定网页一 样。实际上在Android平台上URI的用途更广泛一些,它还用于Intent中data的标识。
就Android平台而言,URI主要分三个部分:scheme, authority and path。其中authority又分为host和port。格式如下: 
scheme://host:port/path
举个实际的例子:
content://com.example.project:200/folder/subfolder/etc
\---------/  \---------------------------/ \---/ \--------------------------/
scheme                 host               port        path
                \--------------------------------/
                          authority    

现在大家应该知道data flag中那些属性的含义了吧,看下data flag
<data android:host="string"
      android:mimeType="string"
      android:path="string"
      android:pathPattern="string"
      android:pathPrefix="string"
      android:port="string"
      android:scheme="string" />
但是我们在程序中一般是不直接用URI来标识CP的,是的,正如我们通常见到的用定义的常量来标识。例如standard CP中的Contacts,我们就用Contacts.People.CONTENT_URI来标识Contacts CP中People这个表。那么要标识某个具体的人怎么办呢? 这就用到了ContentUris.withAppendedId() 和 Uri.withAppendedPath()。例如我们要表示content://contacts/people/20,那么我们就可以用如下语句:
Uri uri = ContentUris.withAppendedId(People.CONTENT_URI, 20); 或者

Uri uri = Uri.withAppendedPath(People.CONTENT_URI, "20");


最近又有了新的进展。

首先我们要实现web页加载手机本地的资源(以图片为例)

如content://com.andych008.demo.webview/girl_sd.gif这样的link,我们要在html上显示手机本地的girl_sd.gif这张图片,

至于girl_sd.gif这张图片的位置,依次从以下位置查找,如果找到就打开。

/sdcard/andych008/

/data/data/com.andych008.demo.webview/andych008/

apk:assets/

当然也可以指定只从某个位置打开。

下面是代码实现

[java] view plain copy
  1. public class LocalFileContentProvider extends ContentProvider {  
  2.       
  3.     private static final String URI_PREFIX = "content://com.andych008.demo.webview";  
  4.       
  5.     @Override  
  6.     public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {  
  7.           
  8.         Log.e("path1:", uri.getPath());  
  9.         File file = new File(uri.getPath());  
  10.         ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);  
  11.         return parcel;  
  12.           
  13.     }  
  14.       
  15.     @Override  
  16.     public AssetFileDescriptor openAssetFile (Uri uri, String mode) throws FileNotFoundException{  
  17.         AssetManager am = getContext().getAssets();    
  18.         String path = uri.getPath().substring(1);    
  19.         Log.e("path:", path);  
  20.           
  21.         //sdcard里有没有  
  22.         String tpath = "/sdcard/andych008/"+path;  
  23.         File file = new File(tpath);  
  24.         if (file.exists()) {  
  25.             Log.e("path2:", tpath);  
  26.             Uri turi = Uri.parse(URI_PREFIX+tpath);  
  27.             return super.openAssetFile(turi, mode);  
  28.         }  
  29.           
  30.         //C盘有没有  
  31.         tpath = "/data/data/com.andych008.demo.webview/andych008/"+path;  
  32.         file = new File(tpath);  
  33.         if (file.exists()) {  
  34.             Log.e("path2:", tpath);  
  35.             Uri turi = Uri.parse(URI_PREFIX+tpath);  
  36.             return super.openAssetFile(turi, mode);  
  37.         }  
  38.           
  39.         try {  
  40.             AssetFileDescriptor afd = am.openFd(path);  
  41.             return afd;  
  42.         } catch (IOException e) {  
  43.             // TODO Auto-generated catch block  
  44.             e.printStackTrace();  
  45.         }  
  46.         return super.openAssetFile(uri, mode);  
  47.     }  
  48.   
  49.     @Override  
  50.     public boolean onCreate() {  
  51.         return true;  
  52.     }  
  53.   
  54.     @Override  
  55.     public int delete(Uri uri, String s, String[] as) {  
  56.         throw new UnsupportedOperationException("Not supported by this provider");  
  57.     }  
  58.   
  59.     @Override  
  60.     public String getType(Uri uri) {  
  61.         throw new UnsupportedOperationException("Not supported by this provider");  
  62.     }  
  63.   
  64.     @Override  
  65.     public Uri insert(Uri uri, ContentValues contentvalues) {  
  66.         throw new UnsupportedOperationException("Not supported by this provider");  
  67.     }  
  68.   
  69.     @Override  
  70.     public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {  
  71.         throw new UnsupportedOperationException("Not supported by this provider");  
  72.     }  
  73.   
  74.     @Override  
  75.     public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {  
  76.         throw new UnsupportedOperationException("Not supported by this provider");  
  77.     }  
  78.   
  79. }  

html文件
[html] view plain copy
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"  
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">  
  4. <head>  
  5. <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">  
  6. <meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />  
  7. <title>Insert title here</title>  
  8. <link type="text/css" rel="stylesheet" href="1.css">  
  9. <script type="text/javascript" charset="utf-8" src="1.js"></script>  
  10.   
  11. </head>  
  12. <body>sd这是一个html页面  
  13. <hr />  
  14. <hr />  
  15. <button onclick="showNote('andy')">showNote</button>  
  16. 相对路径  
  17. <img src="girl_sd.gif" alt="相对路径">  
  18. <hr />  
  19. sd图片  
  20. <img src="content://com.andych008.demo.webview/girl_sd.gif" alt="sd图片">  
  21. <hr />  
  22. c图片  
  23. <img src="content://com.andych008.demo.webview/girl_c.gif" alt="c图片">  
  24. <hr />  
  25. asset图片  
  26. <img src="content://com.andych008.demo.webview/1/girl.gif" alt="a图片">  
  27. <hr />  
  28. 绝对图片  
  29. <img src="content://com.andych008.demo.webview/sdcard/andych008/girl_sd.gif" alt="a图片">  
  30. </body>  
  31.   
  32. </html>  

要求 存在以下文件

/sdcard/andych008/girl_sd.gif

/data/data/com.andych008.demo.webview/andych008/girl_c.gif

apk:assets/1/girl.gif


/data/data下面的文件可以这样cp进去(要求手机是Root过的),或者自己通过程序写文件进去

[plain] view plain copy
  1. adb push girl_c.gif "/data/data/com.andych008.demo.webview/andych008/girl_c.gif"  



你可能感兴趣的:(webview html页面加载本地js及img src)