一个好用的WebView控件窗口组件

在我们公司的一个项目中使用到了QQ微信微博等三方登陆,但是由于网站已经已成了这些登陆方式,为了简化app端的工作量以及最快的方式让app拥有三方登陆的功能,我们决定在app里使用web登陆的方式。

早在之前我写过一篇文章介绍了一些简单的WebView控件的使用,不过WebView确实是很复杂的一个控件,这里说的复杂并不是说它有多难用,而是很多的状态的不确定性,在不同的手机上可能渲染的效果不一样等等,不过如果api level>=19问题就会相对好得多,所以如果webview需要大量用的话,不妨将api level设置大于19,或者使用Crosswalk,不过比较坑的是,Crosswalk已经不再维护了...

不过眼下解决的问题是,app许多网页和本地代码交互的界面,如果保证不用放置太多的包含WebView的Activity才是关键,这里写了个简单的库 WebFrame,也许是重复造的轮子。

WebFrame https://github.com/yahch/WebFrame

用法:

allprojects {
        repositories {
            ...
            maven { url 'https://www.jitpack.io' }
        }
}
dependencies {
            compile 'com.github.yahch:WebFrame:2017.09.27.2'
}

如果有需要在网页上调用的本地代码,需要继承WebFrameScriptInterface 这个抽象类。

WebFrameSettings 是一个单例,用于对webview 的 activity 进行设置,它的成员如下:

private String url;
private HashMap<String, WebFrameScriptInterface> objs;
private boolean noActionBar;

第一个表示需要导航到的url,第二个表示这个页面和本地代码调用的对象类的集合,第三个设置是否需要ActionBar。

在我的项目中,我点击 QQ 登录的图标后,导航至我们网站的 QQ 登录授权链接,对应在 Android 中的操作如下:

Intent intentForQQLogin = new Intent(LoginActivity.this, WebFrameActivity.class);
WebFrameSettings.instance.reset();
WebFrameSettings.instance.setUrl("http://my.域名.com/oauth/qq?client=android");
WebFrameSettings.instance.addObject("app", new WebInterface());
WebFrameSettings.instance.setNoActionBar(true);
startActivity(intentForQQLogin);

可以看到所有交互传入的对象是 WebInterface 的实例,来看看 WebInterface 的内容。

class WebInterface extends WebFrameScriptInterface {
    @JavascriptInterface
    public void oauth(String uid) {
        if (getWebFrameActivity() != null) getWebFrameActivity().finish();
    }
}

因为在我们网站授权登录后的回调时 app.oauth(qqopenid),所以方法签名一定要对应好。
这里有个黑魔法是在调用方能关闭授权窗口的Activity,也就是能通过 getWebFrameActivity() 获取到打开的窗口的 “句柄”,然后进行操作。

WebFrameScriptInterface 的设计如下:

public abstract class WebFrameScriptInterface {
    private WebFrameActivity webFrameActivity;

    public WebFrameScriptInterface() {
    }

    public WebFrameActivity getWebFrameActivity() {
        return this.webFrameActivity;
    }

    public void setWebFrameActivity(WebFrameActivity webFrameActivity) {
        this.webFrameActivity = webFrameActivity;
    }
}

WebFrameScriptInterface 是一个抽象类,其实不写成抽象类也可以,因为也不需要子类重写或实现什么。它唯一作用就是保存着一个 WebFrame 对象实例,供 Java/JS 调用接口层使用。

在 WebFrameScriptInterface 的 onCreate 方法中,会将当前的实例传递给抽象类的实现者。

@SuppressLint("JavascriptInterface")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    
    ...
    
    HashMap<String, WebFrameScriptInterface> invokeObjects = WebFrameSettings.instance.getObjs();
    if (invokeObjects.size() > 0) {
        for (Map.Entry<String, WebFrameScriptInterface> entry : invokeObjects.entrySet()) {
            WebFrameScriptInterface ws = entry.getValue();
            ws.setWebFrameActivity(WebFrameActivity.this);
            webViewWebFrameModule.addJavascriptInterface(ws, entry.getKey());
        }
    }
    ...
}

到这里这个组件算是介绍完了,我是沿着我的思路是实现的,也可能网络上有更好的第三方库,写了多年的 C# 也可能还是保留有 C# 的某些语法习惯 😂

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,558评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,002评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,024评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,144评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,255评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,295评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,068评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,478评论 1 305
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,789评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,965评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,649评论 4 336
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,267评论 3 318
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,982评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,223评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,800评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,847评论 2 351

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,094评论 1 32
  • 关于 android Webview 基本使用 加载html四种方式 简单使用 在AndroidManifest....
    小面包屑阅读 5,390评论 2 13
  • ¥开启¥ 【iAPP实现进入界面执行逐一显】 〖2017-08-25 15:22:14〗 《//首先开一个线程,因...
    小菜c阅读 6,381评论 0 17
  • 人生的浮影好像一场绚烂的烟花表演,不明就里的人只看到了这场烟花秀极尽辉煌的时刻,只有收拾残局的人才明白,层层繁花过...
    碎微阅读 234评论 0 1
  • 在上海我有两个家,一个是租住的狭小的房间,另一个便是便利店。 初到上海,是上午,那一天的中午饭,就是在7-11便利...
    chen_lei阅读 311评论 0 1