x5开源库后续知识点
目录介绍
- 01.基础使用目录介绍
- 1.0.1 常用的基础介绍
- 1.0.2 Android调用Js
- 1.0.3 Js调用Android
- 1.0.4 WebView.loadUrl(url)流程
- 1.0.5 js的调用时机分析
- 1.0.6 清除缓存数据方式有哪些
- 1.0.7 如何使用DeepLink
- 1.0.8 应用被作为第三方浏览器打开
- 02.优化汇总目录介绍
- 2.0.1 视频全屏播放按返回页面被放大
- 2.0.2 加快加载webView中的图片资源
- 2.0.3 自定义加载异常error的状态页面
- 2.0.4 WebView硬件加速导致页面渲染闪烁
- 2.0.5 WebView加载证书错误
- 2.0.6 web音频播放销毁后还有声音
- 2.0.7 DNS采用和客户端API相同的域名
- 2.0.8 如何设置白名单操作
- 2.0.9 后台无法释放js导致发热耗电
- 2.1.0 可以提前显示加载进度条
- 2.1.1 WebView密码明文存储漏洞优化
- 03.问题汇总目录介绍
- 3.0.0 WebView进化史介绍
- 3.0.1 提前初始化WebView必要性
- 3.0.2 x5加载office资源
- 3.0.3 WebView播放视频问题
- 3.0.4 无法获取webView的正确高度
- 3.0.5 使用scheme协议打开链接风险
- 3.0.6 如何处理加载错误
- 3.0.7 webView防止内存泄漏
- 3.0.8 关于js注入时机修改
- 3.0.9 视频/图片宽度超过屏幕
- 3.1.0 如何保证js安全性
- 3.1.1 如何代码开启硬件加速
- 3.1.2 WebView设置Cookie
- 3.1.4 webView加载网页不显示图片
- 3.1.5 绕过证书校验漏洞
- 3.1.6 allowFileAccess漏洞
- 3.1.7 WebView嵌套ScrollView问题
- 3.1.8 WebView中图片点击放大
- 3.1.9 页面滑动期间不渲染/执行
- 3.2.0 被运营商劫持和注入问题
- 3.2.1 解决资源加载缓慢问题
- 3.2.2 判断是否已经滚动到页面底端
- 3.2.3 使用loadData加载html乱码
- 3.2.4 WebView下载进度无法监听
- 3.2.5 webView出现302/303重定向
x5封装库YCWebView开源项目地址
- https://github.com/yangchong211/YCWebView
- 该后续知识点,几乎包含了实际开发中绝大多数的问题,再次学习和巩固webView,希望这篇文章对你有用……更多内容,可以看我的开源项目,如果觉得给你带来一些收获,麻烦star一下,这也可以增加开发者开源项目的动力!
01.基础使用目录介绍
1.0.1 常用的基础介绍
- 在activity中最简单的使用
webview.loadUrl("http://www.baidu.com/"); //加载web资源 //webView.loadUrl("file:///android_asset/example.html"); //加载本地资源 //这个时候发现一个问题,启动应用后,自动的打开了系统内置的浏览器,解决这个问题需要为webview设置 WebViewClient,并重写方法: webview.setWebViewClient(new WebViewClient(){@Overridepublic boolean shouldOverrideUrlLoading(WebView view, String url) {view.loadUrl(url);//返回值是true的时候控制去WebView打开,为false调用系统浏览器或第三方浏览器return true;}//还可以重写其他的方法 });
- 那些因素影响页面加载速度
- 影响页面加载速度的因素有非常多,在对 WebView 加载一个网页的过程进行调试发现
- 每次加载的过程中都会有较多的网络请求,除了 web 页面自身的 URL 请求
- 有 web 页面外部引用的JS、CSS、字体、图片等等都是个独立的http请求。这些请求都是串行的,这些请求加上浏览器的解析、渲染时间就会导致 WebView 整体加载时间变长,消耗的流量也对应的真多。
- 影响页面加载速度的因素有非常多,在对 WebView 加载一个网页的过程进行调试发现
1.0.2 Android调用Js
- 第一种方式:native 调用 js 的方法,方法为:
- 注意的是名字一定要对应上,要不然是调用不成功的,而且还有一点是 JS 的调用一定要在 onPageFinished 函数回调之后才能调用,要不然也是会失败的。
//java //调用无参方法 mWebView.loadUrl("javascript:callByAndroid()"); //调用有参方法 mWebView.loadUrl("javascript:showData(" + result + ")");//javascript,下面是对应的js代码 <script type="text/javascript">function showData(result){alert("result"=result);return "success"; }function callByAndroid(){console.log("callByAndroid")showElement("Js:无参方法callByAndroid被调用"); } </script>
- 第二种方式:
- 如果现在有需求,我们要得到一个 Native 调用 Web 的回调怎么办,Google 在 Android4.4 为我们新增加了一个新方法,这个方法比 loadUrl 方法更加方便简洁,而且比 loadUrl 效率更高,因为 loadUrl 的执行会造成页面刷新一次,这个方法不会,因为这个方法是在 4.4 版本才引入的,所以使用的时候需要添加版本的判断:
if (Build.VERSION.SDK_INT < 18) {mWebView.loadUrl(jsStr); } else {mWebView.evaluateJavascript(jsStr, new ValueCallback<String>() {@Overridepublic void onReceiveValue(String value) {//此处为 js 返回的结果}}); }
- 两种方式的对比
- 一般最常使用的就是第一种方法,但是第一种方法获取返回的值比较麻烦,而第二种方法由于是在 4.4 版本引入的,所以局限性比较大。
- 注意问题
- 记得添加ws.setJavaScriptEnabled(true)代码
1.0.3 Js调用Android
- 第一种方式:通过 addJavascriptInterface 方法进行添加对象映射
- 这种是使用最多的方式了,首先第一步我们需要设置一个属性:
mWebView.getSettings().setJavaScriptEnabled(true);
- 这个函数会有一个警告,因为在特定的版本之下会有非常危险的漏洞,设置完这个属性之后,Native需要定义一个类:
- 在 API17 版本之后,需要在被调用的地方加上 @addJavascriptInterface 约束注解,因为不加上注解的方法是没有办法被调用的
public class JSObject {private Context mContext;public JSObject(Context context) {mContext = context;}@JavascriptInterfacepublic String showToast(String text) {Toast.show(mContext, text, Toast.LENGTH_SHORT).show();return "success";}/*** 前端代码嵌入js:* imageClick 名应和js函数方法名一致** @param src 图片的链接*/@JavascriptInterfacepublic void imageClick(String src) {Log.e("imageClick", "----点击了图片");}/*** 网页使用的js,方法无参数*/@JavascriptInterfacepublic void startFunction() {Log.e("startFunction", "----无参");} }//特定版本下会存在漏洞 mWebView.addJavascriptInterface(new JSObject(this), "yc逗比");
- JS 代码调用
- 这种方式的好处在于使用简单明了,本地和 JS 的约定也很简单,就是对象名称和方法名称约定好即可,缺点就是要提到的漏洞问题。
function showToast(){var result = myObj.showToast("我是来自web的Toast"); }function showToast(){myObj.imageClick("图片"); }function showToast(){myObj.startFunction(); }
- 第二种方式:利用 WebViewClient 接口回调方法拦截 url
- 这种方式其实实现也很简单,使用的频次也很高,上面介绍到了 WebViewClient ,其中有个回调接口 shouldOverrideUrlLoading (WebView view, String url)) ,就是利用这个拦截 url,然后解析这个 url 的协议,如果发现是我们预先约定好的协议就开始解析参数,执行相应的逻辑。注意这个方法在 API24 版本已经废弃了,需要使用 shouldOverrideUrlLoading (WebView view, WebResourceRequest request)) 替代,使用方法很类似,我们这里就使用 shouldOverrideUrlLoading (WebView view, String url)) 方法来介绍一下:
- 代码很简单,这个方法可以拦截 WebView 中加载 url 的过程,得到对应的 url,我们就可以通过这个方法,与网页约定好一个协议,如果匹配,执行相应操作。
public boolean shouldOverrideUrlLoading(WebView view, String url) {//假定传入进来的 url = "js://openActivity?arg1=111&arg2=222",代表需要打开本地页面,并且带入相应的参数Uri uri = Uri.parse(url);String scheme = uri.getScheme();//如果 scheme 为 js,代表为预先约定的 js 协议if (scheme.equals("js")) {//如果 authority 为 openActivity,代表 web 需要打开一个本地的页面if (uri.getAuthority().equals("openActivity")) {//解析 web 页面带过来的相关参数HashMap<String, String> params = new HashMap<>();Set<String> collection = uri.getQueryParameterNames();for (String name : collection) {params.put(name, uri.getQueryParameter(name));}Intent intent = new Intent(getContext(), MainActivity.class);intent.putExtra("params", params);getContext().startActivity(intent);}//代表应用内部处理完成return true;}return super.shouldOverrideUrlLoading(view, url); }
- JS 代码调用
function openActivity(){document.location = "js://openActivity?arg1=111&arg2=222"; }
- 存在问题:这个代码执行之后,就会触发本地的 shouldOverrideUrlLoading 方法,然后进行参数解析,调用指定方法。这个方式不会存在第一种提到的漏洞问题,但是它也有一个很繁琐的地方是,如果 web 端想要得到方法的返回值,只能通过 WebView 的 loadUrl 方法去执行 JS 方法把返回值传递回去,相关的代码如下:
//java mWebView.loadUrl("javascript:returnResult(" + result + ")");//javascript function returnResult(result){alert("result is" + result); }
- 这种方式其实实现也很简单,使用的频次也很高,上面介绍到了 WebViewClient ,其中有个回调接口 shouldOverrideUrlLoading (WebView view, String url)) ,就是利用这个拦截 url,然后解析这个 url 的协议,如果发现是我们预先约定好的协议就开始解析参数,执行相应的逻辑。注意这个方法在 API24 版本已经废弃了,需要使用 shouldOverrideUrlLoading (WebView view, WebResourceRequest request)) 替代,使用方法很类似,我们这里就使用 shouldOverrideUrlLoading (WebView view, String url)) 方法来介绍一下:
- 第三种方式:利用 WebChromeClient 回调接口的三个方法拦截消息
- 这个方法的原理和第二种方式原理一样,都是拦截相关接口,只是拦截的接口不一样:
@Override public boolean onJsAlert(WebView view, String url, String message, JsResult result) {return super.onJsAlert(view, url, message, result); }@Override public boolean onJsConfirm(WebView view, String url, String message, JsResult result) {return super.onJsConfirm(view, url, message, result); }@Override public boolean onJsPrompt(WebView view, String url, String message, String defaultValue, JsPromptResult result) {//假定传入进来的 message = "js://openActivity?arg1=111&arg2=222",代表需要打开本地页面,并且带入相应的参数Uri uri = Uri.parse(message);String scheme = uri.getScheme();if (scheme.equals("js")) {if (uri.getAuthority().equals("openActivity")) {HashMap<String, String> params = new HashMap<>();Set<String> collection = uri.getQueryParameterNames();for (String name : collection) {params.put(name, uri.getQueryParameter(name));}Intent intent = new Intent(getContext(), MainActivity.class);intent.putExtra("params", params);getContext().startActivity(intent);//代表应用内部处理完成result.confirm("success");}return true;}return super.onJsPrompt(view, url, message, defaultValue, result); }
- 和 WebViewClient 一样,这次添加的是WebChromeClient接口,可以拦截JS中的几个提示方法,也就是几种样式的对话框,在 JS 中有三个常用的对话框方法:
- onJsAlert 方法是弹出警告框,一般情况下在 Android 中为 Toast,在文本里面加入\n就可以换行;
- onJsConfirm 弹出确认框,会返回布尔值,通过这个值可以判断点击时确认还是取消,true表示点击了确认,false表示点击了取消;
- onJsPrompt 弹出输入框,点击确认返回输入框中的值,点击取消返回 null。
- 但是这三种对话框都是可以本地拦截到的,所以可以从这里去做一些更改,拦截这些方法,得到他们的内容,进行解析,比如如果是 JS 的协议,则说明为内部协议,进行下一步解析然后进行相关的操作即可,prompt 方法调用如下所示:
function clickprompt(){var result=prompt("js://openActivity?arg1=111&arg2=222");alert("open activity " + result); }
- 需要注意的是 prompt 里面的内容是通过 message 传递过来的,并不是第二个参数的 url,返回值是通过 JsPromptResult 对象传递。为什么要拦截 onJsPrompt 方法,而不是拦截其他的两个方法,这个从某种意义上来说都是可行的,但是如果需要返回值给 web 端的话就不行了,因为 onJsAlert 是不能返回值的,而 onJsConfirm 只能够返回确定或者取消两个值,只有 onJsPrompt 方法是可以返回字符串类型的值,操作最全面方便。
- 以上三种方案的总结和对比
- 以上三种方案都是可行的,在这里总结一下
- 第一种方式:是现在目前最普遍的用法,方便简洁,但是唯一的不足是在 4.2 系统以下存在漏洞问题;
- 第二种方式:通过拦截 url 并解析,如果是已经约定好的协议则进行相应规定好的操作,缺点就是协议的约束需要记录一个规范的文档,而且从 Native 层往 Web 层传递值比较繁琐,优点就是不会存在漏洞,iOS7 之下的版本就是使用的这种方式。
- 第三种方式:和第二种方式的思想其实是类似的,只是拦截的方法变了,这里拦截了 JS 中的三种对话框方法,而这三种对话框方法的区别就在于返回值问题,alert 对话框没有返回值,confirm 的对话框方法只有两种状态的返回值,prompt 对话框方法可以返回任意类型的返回值,缺点就是协议的制定比较麻烦,需要记录详细的文档,但是不会存在第二种方法的漏洞问题。
1.0.4 WebView.loadUrl(url)流程
- WebView.loadUrl(url)加载网页做了什么?
- 加载网页是一个复杂的过程,在这个过程中,我们可能需要执行一些操作,包括:
- 加载网页前,重置WebView状态以及与业务绑定的变量状态。WebView状态包括重定向状态(mTouchByUser)、前端控制的回退栈(mBackStep)等,业务状态包括进度条、当前页的分享内容、分享按钮的显示隐藏等。
- 加载网页前,根据不同的域拼接本地客户端的参数,包括基本的机型信息、版本信息、登录信息以及埋点使用的Refer信息等,有时候涉及交易、财产等还需要做额外的配置。
- 开始执行页面加载操作时,会回调WebViewClient.onPageStarted(webview,url,favicon)。在此方法中,可以重置重定向保护的变量(mRedirectProtected),当然也可以在页面加载前重置,由于历史遗留代码问题,此处尚未省去优化。
- 加载页面的过程中,WebView会回调几个方法。
- 页面加载结束后,WebView会回调几个方法。
- 加载页面的过程中回调哪些方法?
- WebChromeClient.onReceivedTitle(webview, title),用来设置标题。需要注意的是,在部分Android系统版本中可能会回调多次这个方法,而且有时候回调的title是一个url,客户端可以针对这种情况进行特殊处理,避免在标题栏显示不必要的链接。
- WebChromeClient.onProgressChanged(webview, progress),根据这个回调,可以控制进度条的进度(包括显示与隐藏)。一般情况下,想要达到100%的进度需要的时间较长(特别是首次加载),用户长时间等待进度条不消失必定会感到焦虑,影响体验。其实当progress达到80的时候,加载出来的页面已经基本可用了。事实上,国内厂商大部分都会提前隐藏进度条,让用户以为网页加载很快。
- WebViewClient.shouldInterceptRequest(webview, request),无论是普通的页面请求(使用GET/POST),还是页面中的异步请求,或者页面中的资源请求,都会回调这个方法,给开发一次拦截请求的机会。在这个方法中,我们可以进行静态资源的拦截并使用缓存数据代替,也可以拦截页面,使用自己的网络框架来请求数据。包括后面介绍的WebView免流方案,也和此方法有关。
- WebViewClient.shouldOverrideUrlLoading(webview, request),如果遇到了重定向,或者点击了页面中的a标签实现页面跳转,那么会回调这个方法。可以说这个是WebView里面最重要的回调之一,后面WebView与Native页面交互一节将会详细介绍这个方法。
- WebViewClient.onReceivedError(webview,handler,error),加载页面的过程中发生了错误,会回调这个方法。主要是http错误以及ssl错误。在这两个回调中,我们可以进行异常上报,监控异常页面、过期页面,及时反馈给运营或前端修改。在处理ssl错误时,遇到不信任的证书可以进行特殊处理,例如对域名进行判断,针对自己公司的域名“放行”,防止进入丑陋的错误证书页面。也可以与Chrome一样,弹出ssl证书疑问弹窗,给用户选择的余地。
- 加载页面结束回调哪些方法
- 会回调WebViewClient.onPageFinished(webview,url)。
- 这时候可以根据回退栈的情况判断是否显示关闭WebView按钮。通过mActivityWeb.canGoBackOrForward(-1)判断是否可以回退。
1.0.5 js的调用时机分析
- onPageFinished()或者onPageStarted()方法中注入js代码
- 做过WebView开发,并且需要和js交互,大部分都会认为js在WebViewClient.onPageFinished()方法中注入最合适,此时dom树已经构建完成,页面已经完全展现出来。但如果做过页面加载速度的测试,会发现WebViewClient.onPageFinished()方法通常需要等待很久才会回调(首次加载通常超过3s),这是因为WebView需要加载完一个网页里主文档和所有的资源才会回调这个方法。
- 能不能在WebViewClient.onPageStarted()中注入呢?答案是不确定。经过测试,有些机型可以,有些机型不行。在WebViewClient.onPageStarted()中注入还有一个致命的问题——这个方法可能会回调多次,会造成js代码的多次注入。
- 从7.0开始,WebView加载js方式发生了一些小改变,官方建议把js注入的时机放在页面开始加载之后。
- WebViewClient.onProgressChanged()方法中注入js代码
- WebViewClient.onProgressChanged()这个方法在dom树渲染的过程中会回调多次,每次都会告诉我们当前加载的进度。
- 在这个方法中,可以给WebView自定义进度条,类似微信加载网页时的那种进度条
- 如果在此方法中注入js代码,则需要避免重复注入,需要增强逻辑。可以定义一个boolean值变量控制注入时机
- 那么有人会问,加载到多少才需要处理js注入逻辑呢?
- 正是因为这个原因,页面的进度加载到80%的时候,实际上dom树已经渲染得差不多了,表明WebView已经解析了标签,这时候注入一定是成功的。在WebViewClient.onProgressChanged()实现js注入有几个需要注意的地方:
- 1 上文提到的多次注入控制,使用了boolean值变量控制
- 2 重新加载一个URL之前,需要重置boolean值变量,让重新加载后的页面再次注入js
- 3 如果做过本地js,css等缓存,则先判断本地是否存在,若存在则加载本地,否则加载网络js
- 4 注入的进度阈值可以自由定制,理论上10%-100%都是合理的,不过建议使用了75%到90%之间可以。
- WebViewClient.onProgressChanged()这个方法在dom树渲染的过程中会回调多次,每次都会告诉我们当前加载的进度。
1.0.6 清除缓存数据方式有哪些
- 清除缓存数据的方法有哪些?
//清除网页访问留下的缓存 //由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序. Webview.clearCache(true);//清除当前webview访问的历史记录//只会webview访问历史记录里的所有记录除了当前访问记录 Webview.clearHistory();//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据 Webview.clearFormData();
1.0.7 如何使用DeepLink
- 具体可以看这篇文章:https://www.jianshu.com/p/127c80f62655
1.0.8 应用被作为第三方浏览器打开
- 微信里的文章页面,可以选择“在浏览器打开”。现在很多应用都内嵌了WebView,那是否可以使自己的应用作为第三方浏览器打开此文章呢?
- 在Manifest文件中,给想要接收跳转的Activity添加配置:
<activityandroid:name=".X5WebViewActivity"android:configChanges="orientation|screenSize"android:hardwareAccelerated="true"android:launchMode="singleTask"android:screenOrientation="portrait"android:theme="@style/Theme.AppCompat.Light.NoActionBar"><!--需要添加下面的intent-filter配置--><intent-filter tools:ignore="AppLinkUrlError"><action android:name="android.intent.action.VIEW" /><category android:name="android.intent.category.DEFAULT" /><category android:name="android.intent.category.BROWSABLE" /><!--使用http,则只能打开http开头的网页--><data android:scheme="https" /></intent-filter> </activity>
- 然后在 X5WebViewActivity 中获取相关传递数据。具体可以看lib中的X5WebViewActivity类代码。
public class X5WebViewActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_web_view);getIntentData();initTitle();initWebView();webView.loadUrl(mUrl);// 处理 作为三方浏览器打开传过来的值getDataFromBrowser(getIntent());}/*** 使用singleTask启动模式的Activity在系统中只会存在一个实例。* 如果这个实例已经存在,intent就会通过onNewIntent传递到这个Activity。* 否则新的Activity实例被创建。*/@Overrideprotected void onNewIntent(Intent intent) {super.onNewIntent(intent);getDataFromBrowser(intent);}/*** 作为三方浏览器打开传过来的值* Scheme: https* host: www.jianshu.com* path: /p/yc* url = scheme + "://" + host + path;*/private void getDataFromBrowser(Intent intent) {Uri data = intent.getData();if (data != null) {try {String scheme = data.getScheme();String host = data.getHost();String path = data.getPath();String text = "Scheme: " + scheme + "\n" + "host: " + host + "\n" + "path: " + path;Log.e("data", text);String url = scheme + "://" + host + path;webView.loadUrl(url);} catch (Exception e) {e.printStackTrace();}}} }
- 一些重点说明
- 在微信中“通过浏览器”打开自己的应用,然后将自己的应用切到后台。重复上面的操作,会一直创建应用的实例,这样肯定是不好的,为了避免这种情况我们设置启动模式为:launchMode=“singleTask”。
02.优化汇总目录介绍
2.0.1 视频全屏播放按返回页面被放大(部分手机出现)
- 至于原因暂时没有找到,解决方案如下所示
/*** 当缩放改变的时候会调用该方法* @param view view* @param oldScale 之前的缩放比例* @param newScale 现在缩放比例*/ @Override public void onScaleChanged(WebView view, float oldScale, float newScale) {super.onScaleChanged(view, oldScale, newScale);//视频全屏播放按返回页面被放大的问题if (newScale - oldScale > 7) {//异常放大,缩回去。view.setInitialScale((int) (oldScale / newScale * 100));} }
2.0.2 加载webView中的资源时,加快加载的速度优化,主要是针对图片
- html代码下载到WebView后,webkit开始解析网页各个节点,发现有外部样式文件或者外部脚本文件时,会异步发起网络请求下载文件,但如果在这之前也有解析到image节点,那势必也会发起网络请求下载相应的图片。在网络情况较差的情况下,过多的网络请求就会造成带宽紧张,影响到css或js文件加载完成的时间,造成页面空白loading过久。解决的方法就是告诉WebView先不要自动加载图片,等页面finish后再发起图片加载。
//初始化的时候设置,具体代码在X5WebView类中 if(Build.VERSION.SDK_INT >= KITKAT) {//设置网页在加载的时候暂时不加载图片ws.setLoadsImagesAutomatically(true); } else {ws.setLoadsImagesAutomatically(false); }/*** 当页面加载完成会调用该方法* @param view view* @param url url链接*/ @Override public void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);//页面finish后再发起图片加载if(!webView.getSettings().getLoadsImagesAutomatically()) {webView.getSettings().setLoadsImagesAutomatically(true);} }
2.0.3 自定义加载异常error的状态页面,比如下面这些方法中可能会出现error
- 当WebView加载页面出错时(一般为404 NOT FOUND),安卓WebView会默认显示一个出错界面。当WebView加载出错时,会在WebViewClient实例中的onReceivedError(),还有onReceivedTitle方法接收到错误
/*** 请求网络出现error* @param view view* @param errorCode 错误
x5开源库后续知识点相关推荐
- 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本。该案例支持处理 js 的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异常 error 状态、支持视频播放
YCWebView 项目地址:yangchong211/YCWebView 简介: 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本.该案例支持处理 js 的交 ...
- 基于腾讯x5开源库,提高webView开发效率
基于腾讯x5开源库,提高webView开发效率 文章目录 基于腾讯x5开源库,提高webView开发效率 01.前沿说明 1.1 案例展示效果 1.2 该库功能和优势 1.3 相关类介绍说明 02.如 ...
- WebView开源库终极方案
目录介绍 01.前沿说明 1.1 案例展示效果 1.2 该库功能和优势 1.3 相关类介绍说明 1.4 WebView知识点 02.如何使用 2.1 如何引入 2.2 最简单使用 2.3 常用api ...
- 一文应用 AOP | 最全选型考量 + 边剖析经典开源库边实践,美滋滋
前言 繁多的 AOP 方法该如何选择?应用的步骤过于繁琐,语法概念看得头晕脑胀? 本文将详细展示选型种种考量维度,更是砍掉 2 个经典开源库的枝节,取其主干细细体会 AOP 的应用思想和关键流程.一边 ...
- Android常用热门开源库汇总(持续更新)
原文转载:https://www.yundashi168.com/344.html 请及时关注原文网站,因为后续持续更新都在原网站更新.请多多点赞和关注. 前言 收集了一些比较常见的开源库,特此记录( ...
- 最全选型考量 + 剖析经典AOP开源库实践
今日科技快讯 近日,法拉第未来(FF)准备出售内华达州北拉斯维加斯900英亩优质土地,报价为4000万美元.该地块经过多次修缮改造,其中的700英亩已经完全具备了立即进行工业建设的条件.FF还表示,将 ...
- 关于leaflet开源库的学习
总结下使用leaflet这个地图相关的JS开源库 博主是JS小白,因为项目需要使用openstreetmap 这个第三方的开源地图 所以就开始学习这个leaflet这个开源的JS库来配合使用地图: l ...
- librtmp开源库与android平台编译记录
一.编写目的 为了记录编译librtmp开源库过程遇到的问题,帮助后来人提供参考,希望本文能为大家提供参考. 二.简介(官方介绍) The Real-Time Messaging Protocol ( ...
- 关于Android开源库分享平台,(GitClub)微信小程序的开发体验
七八月份的深圳一直在下雨,总有人说雨天适合窝在家看书,对于程序开发者来说更是难得的学习机会.我们502工作室的小伙伴利用这个时间学习了一下微信小程序开发,并上线了一个GitClub小程序,目前功能有些 ...
- Python 代码转 Latex 公式,这个开源库用一行代码帮你搞定
转自 | 机器之心 数学是数据科学和机器学习的重要基础,数学运算的结果对于机器学习项目而言是至关重要的.在编写代码时,我们常常需要定义数学公式的计算形式.像 S=r^2 这样简单的数学公式,大概不会出 ...
最新文章
- Mvc 页面缓存 OutputCache VaryByCustom
- VIM 正则表达式搜索字符串
- Python 中 xpath 语法 与 lxml 库解析 HTML/XML 和 CSS Selector
- css 向左白色箭头,带CSS的工具提示左侧的箭头
- 解决JS文件页面加载时的阻塞
- 第五章 PCB 设计规则设置及 PCB 绘制
- 第二章 Java流程控制 ① 笔记
- 内网环境下的横向移动总结
- python学习(一)数据类型和运算符
- 使用C语言教你轻松学会Cantor表
- html打印时显示不全,打印表格时内容显示不完整怎么办?四种方法解决WPS不完整问题...
- SpringBoot用MultipartFile.transferTo传递相对路径的问题
- PHP删除字符串中的空格和换行符终极方法
- 全奖博士 | 英国利物浦大学可信人工智能组招收博士
- init函数及其使用(go语言基础语法)
- 我和ChatGPT pair 整理的测试类型清单
- Sitewhere物联网云平台安装
- 3. k 近邻法 k-NN
- MySQL需要掌握到什么程度,才有机会进入大厂?来看清华资深架构师推荐文档
- 一、我来说LuCI: LuCI官方----1. 概述
热门文章
- 琴生不等式及其加权形式的证明
- 腾讯反病毒实验室安全研究员杨经宇:开启IoT设备的上帝模式
- java xmx 最大值_java – JVM超过用-Xmx定义的最大内存
- DMAc-TRZ cas:1628752-98-6,双[4-(N-吩噁嗪)苯基]硫砜,热延迟荧光材料TADF
- Spring - 解决 SpringUtil getBean NPE 问题
- dell服务器新bois系统设置u盘启动,跟大家讲讲dell新版biosU盘启动顺序
- 2020 中国独立开发者生存现状调研报告
- Tcl/Tk快速入门
- can是什么时候处于显性_CAN总线什么情况下为空闲状态? - 全文
- A Game of Thrones(105)
- 基于腾讯 x5 开源库,提高 webView 开发效率,大概要节约你百分之六十的时间成本。该案例支持处理 js 的交互逻辑且无耦合、同时暴露进度条加载进度、可以监听异常 error 状态、支持视频播放