webview html页面加载本地js及img src
2013-02-27 10:45
651 查看
我们的客户端软件主要部分用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 plaincopy
package lu.mind.androidphpmanual;
import java.io.File;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
public class LocalFileContentProvider extends ContentProvider {
private static final String URI_PREFIX = "content://lu.mind.androidphpmanual";
public static String constructUri(String url) {
Uri uri = Uri.parse(url);
return uri.isAbsolute() ? url : URI_PREFIX + url;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File file = new File(uri.getPath());
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return parcel;
}
@Override
public boolean onCreate() {
return true;
}
@Override
public int delete(Uri uri, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
}
//html,并提前把js/jquery.js和img/016p.gif两个文件放在手机的sd卡里。
[javascript]
view plaincopy
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />
<title>Insert title here</title>
<script type="text/javascript" charset="utf-8" src="content://lu.mind.androidphpmanual/sdcard/js/jquery.js"></script>
</head>
<body>b这是一个html页面
<hr />
<hr />
<button onclick="showNote('andy')">showNote</button>
<img src="content://lu.mind.androidphpmanual/sdcard/img/016p.gif" alt="本地图片">
</body>
</html>
s
本来想通过assets的形式读取的。可是也失败了。请高人指点!下面是我的代码:
[java]
view plaincopy
// @Override
// public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
// try {
// String path = uri.getPath();
// return getContext().getAssets().openFd(path.substring(1)).getParcelFileDescriptor();
// } catch (IOException e) {
// throw new FileNotFoundException();
// }
// }
s
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 plaincopy
public class LocalFileContentProvider extends ContentProvider {
private static final String URI_PREFIX = "content://com.andych008.demo.webview";
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
Log.e("path1:", uri.getPath());
File file = new File(uri.getPath());
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return parcel;
}
@Override
public AssetFileDescriptor openAssetFile (Uri uri, String mode) throws FileNotFoundException{
AssetManager am = getContext().getAssets();
String path = uri.getPath().substring(1);
Log.e("path:", path);
//sdcard里有没有
String tpath = "/sdcard/andych008/"+path;
File file = new File(tpath);
if (file.exists()) {
Log.e("path2:", tpath);
Uri turi = Uri.parse(URI_PREFIX+tpath);
return super.openAssetFile(turi, mode);
}
//C盘有没有
tpath = "/data/data/com.andych008.demo.webview/andych008/"+path;
file = new File(tpath);
if (file.exists()) {
Log.e("path2:", tpath);
Uri turi = Uri.parse(URI_PREFIX+tpath);
return super.openAssetFile(turi, mode);
}
try {
AssetFileDescriptor afd = am.openFd(path);
return afd;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.openAssetFile(uri, mode);
}
@Override
public boolean onCreate() {
return true;
}
@Override
public int delete(Uri uri, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
}
html文件
[html]
view plaincopy
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="1.css">
<script type="text/javascript" charset="utf-8" src="1.js"></script>
</head>
<body>sd这是一个html页面
<hr />
<hr />
<button onclick="showNote('andy')">showNote</button>
相对路径
<img src="girl_sd.gif" alt="相对路径">
<hr />
sd图片
<img src="content://com.andych008.demo.webview/girl_sd.gif" alt="sd图片">
<hr />
c图片
<img src="content://com.andych008.demo.webview/girl_c.gif" alt="c图片">
<hr />
asset图片
<img src="content://com.andych008.demo.webview/1/girl.gif" alt="a图片">
<hr />
绝对图片
<img src="content://com.andych008.demo.webview/sdcard/andych008/girl_sd.gif" alt="a图片">
</body>
</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 plaincopy
adb push girl_c.gif "/data/data/com.andych008.demo.webview/andych008/girl_c.gif"
今天,我们要解决的就是,如何从节省流量的角度来优化加载速度。
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 plaincopy
package lu.mind.androidphpmanual;
import java.io.File;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
public class LocalFileContentProvider extends ContentProvider {
private static final String URI_PREFIX = "content://lu.mind.androidphpmanual";
public static String constructUri(String url) {
Uri uri = Uri.parse(url);
return uri.isAbsolute() ? url : URI_PREFIX + url;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
File file = new File(uri.getPath());
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return parcel;
}
@Override
public boolean onCreate() {
return true;
}
@Override
public int delete(Uri uri, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
}
//html,并提前把js/jquery.js和img/016p.gif两个文件放在手机的sd卡里。
[javascript]
view plaincopy
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />
<title>Insert title here</title>
<script type="text/javascript" charset="utf-8" src="content://lu.mind.androidphpmanual/sdcard/js/jquery.js"></script>
</head>
<body>b这是一个html页面
<hr />
<hr />
<button onclick="showNote('andy')">showNote</button>
<img src="content://lu.mind.androidphpmanual/sdcard/img/016p.gif" alt="本地图片">
</body>
</html>
s
本来想通过assets的形式读取的。可是也失败了。请高人指点!下面是我的代码:
[java]
view plaincopy
// @Override
// public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
// try {
// String path = uri.getPath();
// return getContext().getAssets().openFd(path.substring(1)).getParcelFileDescriptor();
// } catch (IOException e) {
// throw new FileNotFoundException();
// }
// }
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 plaincopy
public class LocalFileContentProvider extends ContentProvider {
private static final String URI_PREFIX = "content://com.andych008.demo.webview";
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
Log.e("path1:", uri.getPath());
File file = new File(uri.getPath());
ParcelFileDescriptor parcel = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
return parcel;
}
@Override
public AssetFileDescriptor openAssetFile (Uri uri, String mode) throws FileNotFoundException{
AssetManager am = getContext().getAssets();
String path = uri.getPath().substring(1);
Log.e("path:", path);
//sdcard里有没有
String tpath = "/sdcard/andych008/"+path;
File file = new File(tpath);
if (file.exists()) {
Log.e("path2:", tpath);
Uri turi = Uri.parse(URI_PREFIX+tpath);
return super.openAssetFile(turi, mode);
}
//C盘有没有
tpath = "/data/data/com.andych008.demo.webview/andych008/"+path;
file = new File(tpath);
if (file.exists()) {
Log.e("path2:", tpath);
Uri turi = Uri.parse(URI_PREFIX+tpath);
return super.openAssetFile(turi, mode);
}
try {
AssetFileDescriptor afd = am.openFd(path);
return afd;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return super.openAssetFile(uri, mode);
}
@Override
public boolean onCreate() {
return true;
}
@Override
public int delete(Uri uri, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public String getType(Uri uri) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public Cursor query(Uri uri, String[] as, String s, String[] as1, String s1) {
throw new UnsupportedOperationException("Not supported by this provider");
}
@Override
public int update(Uri uri, ContentValues contentvalues, String s, String[] as) {
throw new UnsupportedOperationException("Not supported by this provider");
}
}
html文件
[html]
view plaincopy
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width,minimum-scale=1.0,maximum-scale=1.0" />
<title>Insert title here</title>
<link type="text/css" rel="stylesheet" href="1.css">
<script type="text/javascript" charset="utf-8" src="1.js"></script>
</head>
<body>sd这是一个html页面
<hr />
<hr />
<button onclick="showNote('andy')">showNote</button>
相对路径
<img src="girl_sd.gif" alt="相对路径">
<hr />
sd图片
<img src="content://com.andych008.demo.webview/girl_sd.gif" alt="sd图片">
<hr />
c图片
<img src="content://com.andych008.demo.webview/girl_c.gif" alt="c图片">
<hr />
asset图片
<img src="content://com.andych008.demo.webview/1/girl.gif" alt="a图片">
<hr />
绝对图片
<img src="content://com.andych008.demo.webview/sdcard/andych008/girl_sd.gif" alt="a图片">
</body>
</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 plaincopy
adb push girl_c.gif "/data/data/com.andych008.demo.webview/andych008/girl_c.gif"
相关文章推荐
- webview html页面加载本地js及img src(一)
- webview html页面加载本地js及img src(二)
- webview html页面加载本地js及img src(二)
- webview html页面加载本地js及img src(一)
- android webview 网络页面从本地(assets)加载js库
- iOS 加载HTML的相关问题(与JS的互相调用和WKWebView加载本地网页)
- Android使用webview控件加载本地html,通过Js与后台Java实现数据的传递
- IOS使用webview加载本地HTML文件,压入JS
- Android的webview加载本地html、assert内html和网络URL&&& JS与移动端webview的相互交互
- IOS开发(7)WKWebView加载本地HTML、CSS、JS文件JS(解决html内访问其他资源路径问题)
- iOS webView加载本地html、css、js文件
- Android WebView使用全面解析(加载网络资源、本地HTML,JS交互)
- Android WebView 远程网页 加载本地资源js/html/css
- Android Webview加载外部html时选择加载本地的js,css等资源文件
- WebView加载本地html、js文件常见问题及解决办法
- iOS webView加载本地html 调用 js,css (基本使用)
- Android Webview 加载外部html时选择加载本地的js,css等资源文件
- WKWebView和UIWebView加载本地html和JS交互各种坑解决办法
- 使用WebView加载本地html页面,实现与java之间的相互响应
- android webview 网络页面从本地(assets)加载js库