Skip to content

Commit

Permalink
add readme and fix some bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
JoeSteven committed Aug 21, 2018
1 parent 9657005 commit df4f6fd
Show file tree
Hide file tree
Showing 9 changed files with 249 additions and 41 deletions.
182 changes: 182 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
# XWebViewAssistant 文档

### 概述

XWebViewAssistant 提供给Android开发者更简单的WebView开发方式,基于Android原生`WebView`,轻量封装相关操作

- 链式调用,初始化`WebView` 更简洁
-`Activity`或者`Fragment` 基类,不需要继承,在任何页面都可以直接使用
- 自动绑定生命周期,无需手动操作,避免内存泄露
- 支持`JSBridge` ,拦截URL或者`onJsPrompt`都的方式二选一(官方注解的方式本身不需要封装,如果使用注解的方式,关闭本库的`JSBridge`功能即可
- `JSBridge` 注册的Java方法支持权限管理,支持双向调用及回调

### 依赖



### 使用

#### 1.WebView 基本使用

```java
XWebView xWeb = XWebView.with(webView, this)// 传入原生WebView, 传入LifecycleOwner
.setWebTitleEnable(titleView)// 开启标题
.setProgressEnable(progressBar)// 开启加载进度
.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK)// 设置缓存模式
.setJSBridgeUrlEnabled(jsRegister, urlParser)// 开启JSBridge
.loadUrl(url);// 加载url
```

- 生命周期

`Lifecycle` 为Google官方的生命周期管理方案,只要是继承自`AppCompatActivity` 或者v4包中的`Fragment`均已实现了`LifecycleOwner` 接口,如果页面没有实现这个接口,需要自行实现或者手动管理生命周期

- 标题

该接口会在标题获取成功后回调,可以在回调接口中设置标题,也可以通过一个自定义View实现这个接口

```Java
public interface IWebTitle {
void onTitleReady(String text);
}
```

- 加载进度

同标题,可以在回调中操作,也可以通过自定义View实现该接口,库中默认实现了 XWebProgressBar 直接继承自系统的 ProgressBar

```java
public interface IWebProgress {
void onProgressChanged(int progress);

void onProgressStart();

void onProgressDone();
}
```

- 基本API

```JAVA
public WebView webView()// 获取注入的WebView

public XWebView loadUrl(String url)//加载
public XWebView loadUrl(String url, Map<String, String> additionalHttpHeaders)

public void invokeJavaScript(String func, String... params)// 调用JS函数

public boolean goBack()// 前端页面回退,回退成功返回true,返回false则说明不可回退

public void clearCache(boolean includeDisFile)// 清除缓存

public void clearHistory() // 清除历史记录

public JSBridgeCore JSBridge()// 获取JSBridge 的操作类,一般不需要获取

public WebSettings settings()// 获取WebSettings
```

#### 2.JSBridge 使用

本库采用注册的方式来给前端页面提供 Java 方法,尽量实现每个方法逻辑单一,可复用,便于权限管理提供安全性

- 实现 Java 方法

```java
public class ExampleMethod extends XJavaMethod{

@Override
public void call(JSMessage message) {
//doSomething here
JsonObject params = message.params

// 执行成功后需要回调,则调用该方法,回调js函数由前端提供,参数为双方约定
callback(message.callback, "success");

// 异常回调
callError(message.errorCallback," error");
}

@Override
public Permission permission() {
// 标记该方法的权限
return Permission.PUBLIC;
}
}
```

- 权限管理,每一个注册的 Java 方法都必须指定调用权限

```java
public enum Permission{
PUBLIC,// 公开方法,所以的网页只要知道该应用的js协议都可以调用

AUTHORIZED,// 授权方法,只有白名单或者被授权过的网页才可以调用该方法,授权判断由业务层自己实现

PRIVATE // 私有方法,只有该在该应用中注册了域名白名单的网页可以调用
}

// 检查该网页是否有该方法的授权接口,默认实现为永远返回false
//例如:应用启动的时候从服务端获取一个对应方法的授权网页列表,调用的时候判断该网页是否有授权
public interface IAuthorizedChecker {
boolean isAuthorized(String javaFunc, String url);
}

// 设置授权检查接口,该方法必须在setJSBridgeUrlEnabled或者setJSBridgePromptEnabled之后调用
xWeb.setJSBridgeAuthorizedChecker(checker);
```

- 构造 `JSBridgeRegister`, 注册 Java 方法

```java
JSBridgeRegister register = JSBridgeRegister.create()
.register("toast", JSToast.class)// js 约定的方法名及真实方法
.register("login", JSLogin.class)
.register("user_info", JSUserInfo.class)
.whiteList("api.xwebview.com")// 设置域名白名单
.whiteList("api.xwebview.cn");
```

- `IMethodInitializer` 方法初始化器

如果注册的 Java 方法依赖外界注入参数,可以通过设置方法初始化接口,在创建该方法实例后注入参数等

```java
register.setMethodInitializer((func, method) -> {
if (method instanceof JSToast)
((JSToast) method).setContext(SampleActivity.this);
});
```

- 实现 JSBridge 协议解析接口

```java
// 拦截url的方式实现JSBridge
public interface IJSBridgeUrlParser {
JSMessage parse(String url);
}

// 拦截onJsPrompt的方式实现
public interface IJSBridgePromptParser {
JSMessage parse(String url, String message, String defaultValue, JsPromptResult result);
}

// 满足协议则返回一个 JSMessage 对象,否则返回null
public class JSMessage {
public String url;// 调用该方法的网页url,可选
public String callback;// 执行成功后需要回调的JS函数,可选
public String errorCallback;// 异常发生时回调的JS函数,可选
public String javaMethod;// 要调用的Java方法,必须
public JSONObject params;// Java方法所需要的参数,Json格式,可选
}
```

- 开启`JSBridge`

```java
xWeb.setJSBridgeUrlEnabled(register, urlParser
//.setJSBridgePromptEnabled(register, promptParser)
.setJSBridgeAuthorizedChecker(checker);//可选
```

**注意:拦截url和拦截 prompt 方案只能二选一,调用了其中一个就不能开启另外一个**
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package com.joey.xwebassistant.sample;

import android.net.Uri;

import com.joey.xwebview.jsbridge.IJSBridgeUrlParser;
import com.joey.xwebview.jsbridge.method.JSMessage;

import org.json.JSONException;
import org.json.JSONObject;

/**
* Description:
* author:Joey
Expand All @@ -11,6 +16,18 @@
public class JSBridgeUrlParser implements IJSBridgeUrlParser{
@Override
public JSMessage parse(String url) {
if (!url.startsWith("Xwebview")) return null;
Uri uri = Uri.parse(url);
try {
JSONObject params = new JSONObject(uri.getQueryParameter("params"));
return new JSMessage(url,
uri.getQueryParameter("callback"),
uri.getQueryParameter("error_callback"),
uri.getQueryParameter("func"),
params);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,16 @@ public void setContext(Context context) {

@Override
public void call(JSMessage message) {
if (context != null) Toast.makeText(context, message.params.optString("message"), Toast.LENGTH_SHORT).show();
if (context != null){
Toast.makeText(context, message.params.optString("message"), Toast.LENGTH_SHORT).show();
callback(message.callback, "call JSToast success");
} else {
callError(message.errorCallback, "call JSToast failed! context is null!");
}
}

@Override
public Permission permission() {
return Permission.PRIVATE;
return Permission.PUBLIC;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import android.webkit.WebSettings;
import android.widget.EditText;

import com.joey.xwebassistant.sample.JavaMethod.JSLog;
import com.joey.xwebassistant.sample.JavaMethod.JSToast;
import com.joey.xwebview.XWebView;
import com.joey.xwebview.jsbridge.JSBridgeRegister;
Expand All @@ -18,31 +17,29 @@ public class SampleActivity extends AppCompatActivity implements IWebTitle {

private XWebView webView;
private EditText etUrl;
private EditText etJs;

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sample);
etUrl = findViewById(R.id.et_url);

findViewById(R.id.btn_load).setOnClickListener(v -> webView.loadUrl(etUrl.getText().toString()));
etJs = findViewById(R.id.et_js);

webView = XWebView.with(findViewById(R.id.wv), this)
.setWebTitleEnable(this)
.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW)
.setCacheMode(WebSettings.LOAD_NO_CACHE)
.setProgressEnable(findViewById(R.id.progress_bar))
.setJSBridgeUrlEnabled(register(), new JSBridgeUrlParser())
.loadUrl("https://www.joey.com");
.setJSBridgeUrlEnabled(register(), new JSBridgeUrlParser());

webView.invokeJavaScript("log", "hi, this is java");
findViewById(R.id.btn_load).setOnClickListener(v -> webView.loadUrl(etUrl.getText().toString()));
findViewById(R.id.btn_input).setOnClickListener(v-> webView.invokeJavaScript("msg", etJs.getText().toString()));
}

private JSBridgeRegister register() {
return JSBridgeRegister.create()
.register("toast", JSToast.class)
.register("log", JSLog.class)
.whiteList("www.joey.com")
.setMethodInitializer((func, method) -> {
if (method instanceof JSToast)
((JSToast) method).setContext(SampleActivity.this);
Expand Down
21 changes: 18 additions & 3 deletions app/src/main/res/layout/activity_sample.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
Expand All @@ -24,12 +23,28 @@

<com.joey.xwebview.ui.XWebProgressBar
android:id="@+id/progress_bar"
android:progress="10"
android:visibility="gone"
style="@style/Base.Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<WebView
android:layout_weight="1"
android:id="@+id/wv"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
android:layout_height="0dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/et_js"
android:hint="input message for js here"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_input"
android:text="call js"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</LinearLayout>
10 changes: 9 additions & 1 deletion xwebview/src/main/java/com/joey/xwebview/XWebView.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.joey.xwebview.jsbridge.IJSBridgeUrlParser;
import com.joey.xwebview.jsbridge.JSBridgeCore;
import com.joey.xwebview.jsbridge.JSBridgeRegister;
import com.joey.xwebview.jsbridge.method.IAuthorizedChecker;
import com.joey.xwebview.ui.IWebProgress;
import com.joey.xwebview.ui.IWebTitle;

Expand Down Expand Up @@ -43,7 +44,6 @@ private XWebView(WebView webView, LifecycleOwner owner) {

private void initWebView() {
setJavaScriptEnabled(true)
.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK)
.setDomStorageEnable(true)
.setWebViewClient(new XWebViewClient())
.setWebChromeClient(new XWebChromeClient());
Expand Down Expand Up @@ -122,6 +122,11 @@ public XWebView setJSBridgePromptEnabled(JSBridgeRegister register, IJSBridgePro
return this;
}

public XWebView setJSBridgeAuthorizedChecker(IAuthorizedChecker checker) {
jsBridgeCore.setAuthorizedChecker(checker);
return this;
}

public XWebView setJavaScriptEnabled(boolean enable) {
webView().getSettings().setJavaScriptEnabled(enable);
return this;
Expand Down Expand Up @@ -185,6 +190,9 @@ public void onDestroy() {
if (jsBridgeCore != null) jsBridgeCore.release();
webView().removeAllViews();
webView().destroy();
webProgress = null;
webTitle = null;
jsBridgeCore = null;
}

@Override
Expand Down
Loading

0 comments on commit df4f6fd

Please sign in to comment.