更新时间:2016-01-31
在 activity_web.xml(当前所用 activity 所对应的 layout)中 WebView 的布局设置
<WebView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/ng"/>
进行相应的设置就能行了
private String url;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_web);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
final WebView webView = (WebView)findViewById(R.id.ng);
final WebSettings webSettings = webView.getSettings();
// 要在网页中启用JavaScript,这句不能少
webSettings.setJavaScriptEnabled(true);
webSettings.setSupportZoom(false);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
url = "file:///android_asset/ng.html";
// 避免调用手机上其他外部浏览器打开html页面
webView.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
// 打开网页
webView.loadUrl(url);
}
在 Android 4.4 之后 WebSQL 无法改变数据库的路径,需要借助 addJavasciptInterface() 来实现网页对 Android 方法的调用。由于网页通过 JavaScript 和 Android 中的 Java 的接口,也就是说,数据库的操作是通过 Android 代码实现的。
webView.addJavascriptInterface(new Object() {
// 在android4.2以后一定需要这句话
@JavascriptInterface
// 方法一定要是public类型的
public void doSomething() {
//code..
}
}, "Demo");
在 JavaScript 中调用:
// Demo前面定义过的
window.Demo.doSomething();
数据库操作部分,如果你有使用 SQL 的经验,应该比较好理解
首先需要定义表的结构,即需要一个 Contract Class
public final class RedContract {
public RedContract() { }
public static abstract class RedEntry implements BaseColumns {
public static final String TABLE_NAME = "RedMoney";
public static final String COLUMN_NAME_ENTRY_ID = "redid";
public static final String COLUMN_NAME_AMOUNT = "amount";
public static final String COLUMN_NAME_COMMENT = "comment";
}
}
为了使用 SQLiteOpenHelper, 需要创建一个子类并重写 onCreate()
, onUpgrade()
与 onOpen()
等 callback 方法。也许还需要实现 onDowngrade()
, 但这并不是必需的。
public class RedDbHelper extends SQLiteOpenHelper {
public static final int DATABASE_VERSION = 1;
public static final String DATABASE_NAME = "Red.db";
public static final String SQL_CREATE_ENTRIES =
"CREATE TABLE " + RedContract.RedEntry.TABLE_NAME + " (" +
RedContract.RedEntry._ID + " INTEGER PRIMARY KEY," +
RedContract.RedEntry.COLUMN_NAME_ENTRY_ID + " INTEGER,"+
RedContract.RedEntry.COLUMN_NAME_AMOUNT + " INTEGER,"+
RedContract.RedEntry.COLUMN_NAME_COMMENT + " TEXT" +
" )";
public static final String SQL_DELETE_ENTRIES =
"DROP TABLE IF EXISTS " + RedContract.RedEntry.TABLE_NAME;
public RedDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
public void onCreate(SQLiteDatabase db) {
db.execSQL(SQL_CREATE_ENTRIES);
}
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(SQL_DELETE_ENTRIES);
onCreate(db);
}
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
onUpgrade(db, oldVersion, newVersion);
}
}
添加信息至数据库,通过传递一个 ContentValues 对象到 insert() 方法:
public void insert(View view) {
RedDbHelper mDbHelper = new RedDbHelper(getBaseContext());
SQLiteDatabase db = mDbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(RedContract.RedEntry.COLUMN_NAME_ENTRY_ID, 2);
values.put(RedContract.RedEntry.COLUMN_NAME_AMOUNT, 666);
values.put(RedContract.RedEntry.COLUMN_NAME_COMMENT, "happy");
int rowid;
rowId = db.insert(
RedContract.RedEntry.TABLE_NAME,
null, //对于没有数据的项不进行补充
values);
}
从数据库中读取信息,需要使用 query() 方法,传递需要查询的条件。查询后会返回一个 Cursor 对象。
RedDbHelper mDbHelper = new RedDbHelper(getBaseContext());
SQLiteDatabase db = mDbHelper.getReadableDatabase();
String[] projection = {
RedContract.RedEntry.COLUMN_NAME_ENTRY_ID,
RedContract.RedEntry.COLUMN_NAME_AMOUNT,
RedContract.RedEntry.COLUMN_NAME_COMMENT
};
String selection = RedContract.RedEntry._ID + " Like ?";
String[] selectionArgs = { String.valueOf(1) };
String sortOrder = RedContract.RedEntry.COLUMN_NAME_ENTRY_ID + " DESC";
Cursor c = db.query(
RedContract.RedEntry.TABLE_NAME, //Table red
projection, //select id,amount,comment
selection, //where _ID like ?
selectionArgs, //1
null,
null,
sortOrder); // id desc
要查询在 cursor 中的行,使用 cursor 的其中一个 move 方法,但必须在读取值之前调用。一般来说应该先调用 moveToFirst() 函数,将读取位置置于结果集最开始的位置。
对每一行,我们可以使用 cursor 的其中一个 get 方法如 getString() 或 getLong() 获取列的值。对于每一个 get 方法必须传递想要获取的列的索引位置(index position),索引位置可以通过调用 getColumnIndex() 或 getColumnIndexOrThrow() 获得。
c.moveToFirst();
int id = c.getInt(
c.getColumnIndexOrThrow(RedContract.RedEntry.COLUMN_NAME_ENTRY_ID)
);
JavaScript 与 Android 传输的数据使用 JSON 格式
Android 端需要使用 Gson
下载 gson-2.x.jar 并导入到 libs 文件夹下,举个栗子:
import com.google.gson.Gson;
class BagOfPrimitives {
private int value1 = 1;
private String value2 = "abc";
private transient int value3 = 3;
BagOfPrimitives() {
// no-args constructor
}
}
// Serialization
BagOfPrimitives obj = new BagOfPrimitives();
Gson gson = new Gson();
String item = gson.toJson(obj);
// ==> item is {"value1":1,"value2":"abc"}
JavaScript 中需先处理一下得到 JSON 类
item = JSON.parse(item);
// ==> item is {"value1":1,"value2":"abc"}
// TODO
在4.4之后,Android 浏览器使用的内核从 Android webkit 切换到 Chromium webkit, WebView API也相应发生变化,其中包括 database storage API.
设置 Web SQL 的数据库路径
final String databasePath = this.getApplicationContext().getDir(“database”, Context.MODE_PRIVATE).getPath();
WebSettings settings = webView.getSettings();
settings.setDatabasePath(databasePath);
然后就可以通过 JavaScript 来操作数据库了,例如:
function loaddb() {
// 建立/打开一个数据库
var db = openDatabase(‘testdb’, ‘1.0’, ‘说明’, 2 * 1024 * 1024);
db.transaction(function (tx){
// 创建表
tx.executeSql(‘CREATE TABLE IF NOT EXISTS person (_id INTEGER,
person_name TEXT, address TEXT)’);
// 在表中插入数据
tx.executeSql(‘INSERT INTO person (_id, person_name, address)
VALUES(1, “Hardik Trivedi”, “Ahmedabad,Gujarat,India”)’);
});
}
查看相关 Java 文件的完整代码:点我
要是你发现本文有哪里说错的,还请指出