Android WebView访问网页+自动播放视频+自动全屏+切换横屏

一、引言

        近期,我发现电视家、火星直播等在线看电视直播的软件都已倒闭,而我奶奶也再无法通过这些平台看电视了。她已六十多岁,快七十岁啦。这些平台的倒下对我来说其实没有多大的影响,但是对于文化不多的她而言,生活中却是少了一大乐趣。因为自己学过编程,所以我想帮她解决这个问题。她只听得懂白话,又最爱看“广东珠江台”,因此,我通过Android的编程技术,为她专门定制一款可以自动看广东珠江台的App,打开即用,免了点来点去的麻烦。虽说需求很小、只够她一人使用,但实现起来却并不简单呀。通过两天时间的深入钻研,最终我还是把这个小需求给实现了。为此编写一篇博客,如果日后自己还需要解决这样的问题时,我就直接ctrl+c加ctrl+v。当然,也希望这篇博客能够为你提供一些指导和帮助。

二、访问网页视频+自动播放的实现思路

        由于许多的m3u8链接都已经失效,现在看电视直播只能通过一些官方网页来实现,比如央视网等等。那么,访问网页的话是可以通过Android的WebView来实现,实现的方法非常简单,就是在Activity界面之中添加一个WebView空间,然后通过下面的代码来访问网页:

main_wv = findViewById(R.id.main_wv);
main_wv.setWebViewClient(new WebViewClient());
main_wv.setWebChromeClient(new WebChromeClient());
main_wv.loadUrl("https://***.***");

        但是这样的话,最多也只能够竖屏中观看视频,显示十分地有限,而且还不会自动播放,如图:

        所以,这里先介绍实现网页访问+自动播放的思路。WebView可以通过自定义的设置来控制它是否支持JavaScript脚本注入,即通过js来实现网页视频的自动播放。第一步是对WebView进行设置,而第二步是执行js自动播放视频的脚本,代码如下:

        设置WebView支持js脚本

WebSettings settings = main_wv.getSettings(); // main_wv为WebView控件
settings.setJavaScriptEnabled(true);

        执行js自动播放视频的脚本

String js = "javascript:";
js += "var videos = document.getElementsByTagName('video');";
js += "var video_last;";
js += "var video = videos[videos.length-1];";
js += "if (video != undefined && video != video_last) {";
{js += "video_last = video;";js += "function video_start() {";{js += "_VideoEnabledWebView.notifyVideoStart();";}js += "}";js += "video.addEventListener('play', video_start);";
}
js += "}";
main_wv.loadUrl(js);    // main_wv为WebView控件

        忘了介绍,该js脚本在什么时候执行了。这里补充一下,为了使得页面自动播放视频,需要重写一个WebViewClient类,类名可以随你定义,比如“MyWebViewClient”,然后重写public void onPageFinished(WebView view, String url)方法,如下:

@Override
public void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);String js = "javascript:";js += "var videos = document.getElementsByTagName('video');";js += "var video_last;";js += "var video = videos[videos.length-1];";js += "if (video != undefined && video != video_last) {";{js += "video_last = video;";js += "function video_start() {";{js += "_VideoEnabledWebView.notifyVideoStart();";}js += "}";js += "video.addEventListener('play', video_start);";}js += "}";main_wv.loadUrl(js); // main_wv为WebView控件
}

        至此,还请记得改

main_wv.setWebViewClient(new WebViewClient()); // main_wv为WebView控件

        为

main_wv.setWebViewClient(new MyWebViewClient()); // main_wv为WebView控件

        这样,在访问网页时,视频就可以自动播放啦。

三、网页自动全屏思路

        网页全屏的实现思路比较复杂,因为Android开发者的初衷是使网页设计者无法通过js的方式直接全屏地播放视频。也就是说,通过js注入的方式无法直接在WebView中实现网页的全屏播放。为什么呢?根据其他人的说法,这是因为Android开发者担心你的手机不小心访问到一个流氓网页,然后该网页直接全屏,使你的手机失控,被它播放的视频霸占许久、不能退出。我想了想,觉得这个理由倒是有些许合理的。因此执行js脚本注入无法直接在WebView中实现网页视频的全屏播放。

        但是网页全屏的实现是完全没有问题的。大体的思路是:重写WebChromeClient和WebView这两个类,通过重写其中的内部方法,在加载完网页后,再调用js脚本注入,进而触发视频的全屏播放。而触发视频的全屏播放的js脚本为:

"javascript:(" +
"function() { " +
" var videos = document.getElementsByTagName('video'); " +
" var video = videos[0]; " +
" if (!document.webkitFullScreen && video.webkitEnterFullscreen) {" +
" video.webkitEnterFullscreen(); " +
" } " +
" })()"

        由于实现的细节很多,再加上我只是简单地研究了一下,所以没法更详细地展开说说了。请大家看后边“全部代码”的章节部分,了解更多细节。

四、手机默认横屏思路

        手机默认横屏的思路实现起来非常简单,简单得不得了,只需要在Manifest.xml这个清单文件中对指定的Activity声明相关的属性即可。例如,用于播放的Activity为MainActivity,那么就这样设置:

<activity android:name=".MainActivity"android:theme="@android:style/Theme.NoTitleBar.Fullscreen"android:screenOrientation="landscape"android:configChanges="orientation|screenSize|keyboardHidden"android:hardwareAccelerated="true">
</activity>

        其中,最关键的两行代码为

android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
android:screenOrientation="landscape"

        上面一行说的是让app在手机上运行时不显示标题栏(这个可以看你个人需求,有的人喜欢留着,有的人喜欢去掉),而下面一行则是实现横屏的开关,landscape指的是风景,意为通过手机横屏的方式欣赏图片中的风景,以尽可能地使你更加清楚地目睹一张横向的风景图。

五、全部代码

        项目的代码目录,其中画横线部分是重点,我从创建项目到生成可运行且有效果的App只改动过这些文件。下面我将每个框中的文件中的代码罗列出来。

        AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="***.***.******"><uses-permission android:name="android.permission.INTERNET" /><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><applicationandroid:allowBackup="true"android:icon="@mipmap/ic_launcher"android:label="@string/app_name"android:roundIcon="@mipmap/ic_launcher_round"android:supportsRtl="true"android:theme="@style/AppTheme"><activity android:name=".MainActivity"android:hardwareAccelerated="true"android:theme="@android:style/Theme.NoTitleBar.Fullscreen"android:screenOrientation="landscape"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application>
</manifest>

        MainActivity.java

package ***.***.***;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;public class MainActivity extends Activity {VideoEnabledWebView mainWebView;RelativeLayout mainNonVideoRelativeLayout;ViewGroup mainVideoLayout;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);initView();         // initialize ui componentssetWebView();       // set webview's settingsloadVideoUrl();     // load video url}private void initView() {setContentView(R.layout.activity_main);mainNonVideoRelativeLayout = (RelativeLayout) findViewById(R.id.main_rl_non_video);mainVideoLayout = (ViewGroup)findViewById(R.id.main_rl_video);}@SuppressLint("SetJavaScriptEnabled")private void setWebView() {// create a webview instancemainWebView = new VideoEnabledWebView(this);mainWebView.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));// add the webview instance to the main layoutmainNonVideoRelativeLayout.addView(mainWebView);// set general settings of webviewWebSettings settings = mainWebView.getSettings();settings.setAllowFileAccess(true);settings.setBuiltInZoomControls(false);settings.setJavaScriptEnabled(true);settings.setBuiltInZoomControls(false);// create a WebChromeClient instance and use it to set the webviewVideoEnabledWebChromeClient videoEnabledWebChromeClient = new VideoEnabledWebChromeClient(mainNonVideoRelativeLayout, mainVideoLayout,null, mainWebView);mainWebView.setWebChromeClient(videoEnabledWebChromeClient);// create a WebViewClient for webviewmainWebView.setWebViewClient(new WebViewClient(){@Overridepublic void onPageFinished(WebView view, String url) {super.onPageFinished(view, url);// execute a javascript to automatically play the videoString js = "javascript:";js += "var videos = document.getElementsByTagName('video');";js += "var video_last;";js += "var video = videos[videos.length-1];";js += "if (video != undefined && video != video_last) {";{js += "video_last = video;";js += "function video_start() {";{js += "_VideoEnabledWebView.notifyVideoStart();";}js += "}";js += "video.addEventListener('play', video_start);";}js += "}";mainWebView.loadUrl(js);}});}private void loadVideoUrl() {mainWebView.loadUrl("https://******"); // your url that contains the video}
}

        activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><RelativeLayoutandroid:id="@+id/main_rl_non_video"android:layout_width="match_parent"android:layout_height="match_parent" ></RelativeLayout><RelativeLayoutandroid:id="@+id/main_rl_video"android:layout_width="match_parent"android:layout_height="match_parent" ></RelativeLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

        VideoEnabledWebChromeClient.java

package ***.***.***;import android.media.MediaPlayer;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;public class VideoEnabledWebChromeClient extends WebChromeClient implements MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {public interface ToggledFullscreenCallback {void toggledFullscreen(boolean fullscreen);}private View activityNonVideoView;private ViewGroup activityVideoView;private View loadingView;private VideoEnabledWebView webView;// Indicates if the video is being displayed using a custom view (typically full-screen)private boolean isVideoFullscreen;private FrameLayout videoViewContainer;private CustomViewCallback videoViewCallback;private ToggledFullscreenCallback toggledFullscreenCallback;/*** Never use this constructor alone.* This constructor allows this class to be defined as an inline inner class in which the user can override methods*/@SuppressWarnings("unused")public VideoEnabledWebChromeClient() {}/*** Builds a video enabled WebChromeClient.* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.* @param activityVideoView    A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.*/@SuppressWarnings("unused")public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView) {this.activityNonVideoView = activityNonVideoView;this.activityVideoView = activityVideoView;this.loadingView = null;this.webView = null;this.isVideoFullscreen = false;}/*** Builds a video enabled WebChromeClient.* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.* @param activityVideoView    A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.* @param loadingView          A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and not attached to a parent view.*/@SuppressWarnings("unused")public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView) {this.activityNonVideoView = activityNonVideoView;this.activityVideoView = activityVideoView;this.loadingView = loadingView;this.webView = null;this.isVideoFullscreen = false;}/*** Builds a video enabled WebChromeClient.* @param activityNonVideoView A View in the activity's layout that contains every other view that should be hidden when the video goes full-screen.* @param activityVideoView    A ViewGroup in the activity's layout that will display the video. Typically you would like this to fill the whole layout.* @param loadingView          A View to be shown while the video is loading (typically only used in API level <11). Must be already inflated and not attached to a parent view.* @param webView              The owner VideoEnabledWebView. Passing it will enable the VideoEnabledWebChromeClient to detect the HTML5 video ended event and exit full-screen.*                             Note: The web page must only contain one video tag in order for the HTML5 video ended event to work. This could be improved if needed (see Javascript code).*/@SuppressWarnings("unused")public VideoEnabledWebChromeClient(View activityNonVideoView, ViewGroup activityVideoView, View loadingView, VideoEnabledWebView webView) {this.activityNonVideoView = activityNonVideoView;this.activityVideoView = activityVideoView;this.loadingView = loadingView;this.webView = webView;this.isVideoFullscreen = false;}/*** Indicates if the video is being displayed using a custom view (typically full-screen)* @return true it the video is being displayed using a custom view (typically full-screen)*/public boolean isVideoFullscreen() {return isVideoFullscreen;}/*** Set a callback that will be fired when the video starts or finishes displaying using a custom view (typically full-screen)* @param callback A VideoEnabledWebChromeClient.ToggledFullscreenCallback callback*/@SuppressWarnings("unused")public void setOnToggledFullscreen(ToggledFullscreenCallback callback) {this.toggledFullscreenCallback = callback;}@Overridepublic void onShowCustomView(View view, CustomViewCallback callback) {if (view instanceof FrameLayout) {// A video wants to be shownFrameLayout frameLayout = (FrameLayout) view;View focusedChild = frameLayout.getFocusedChild();// Save video related variablesthis.isVideoFullscreen = true;this.videoViewContainer = frameLayout;this.videoViewCallback = callback;// Hide the non-video view, add the video view, and show itactivityNonVideoView.setVisibility(View.INVISIBLE);activityVideoView.addView(videoViewContainer, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));activityVideoView.setVisibility(View.VISIBLE);if (focusedChild instanceof android.widget.VideoView) {// android.widget.VideoView (typically API level <11)android.widget.VideoView videoView = (android.widget.VideoView) focusedChild;// Handle all the required eventsvideoView.setOnPreparedListener(this);videoView.setOnCompletionListener(this);videoView.setOnErrorListener(this);} else {// Other classes, including:// - android.webkit.HTML5VideoFullScreen$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 11-18)// - android.webkit.HTML5VideoFullScreen$VideoTextureView, which inherits from android.view.TextureView (typically API level 11-18)// - com.android.org.chromium.content.browser.ContentVideoView$VideoSurfaceView, which inherits from android.view.SurfaceView (typically API level 19+)// Handle HTML5 video ended event only if the class is a SurfaceView// Test case: TextureView of Sony Xperia T API level 16 doesn't work fullscreen when loading the javascript belowif (webView != null && webView.getSettings().getJavaScriptEnabled() && focusedChild instanceof SurfaceView) {// Run javascript code that detects the video end and notifies the Javascript interfaceString js = "javascript:";js += "var _ytrp_html5_video_last;";js += "var _ytrp_html5_video = document.getElementsByTagName('video')[0];";js += "if (_ytrp_html5_video != undefined && _ytrp_html5_video != _ytrp_html5_video_last) {";{js += "_ytrp_html5_video_last = _ytrp_html5_video;";js += "function _ytrp_html5_video_ended() {";{js += "_VideoEnabledWebView.notifyVideoEnd();"; // Must match Javascript interface name and method of VideoEnableWebView}js += "}";js += "_ytrp_html5_video.addEventListener('ended', _ytrp_html5_video_ended);";}js += "}";webView.loadUrl(js);}}// Notify full-screen changeif (toggledFullscreenCallback != null) {toggledFullscreenCallback.toggledFullscreen(true);}}}@Override// Available in API level 14+, deprecated in API level 18+public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {onShowCustomView(view, callback);}@Override// This method should be manually called on video end in all cases because it's not always called automatically.// This method must be manually called on back key press (from this class' onBackPressed() method).public void onHideCustomView() {if (isVideoFullscreen) {// Hide the video view, remove it, and show the non-video viewactivityVideoView.setVisibility(View.INVISIBLE);activityVideoView.removeView(videoViewContainer);activityNonVideoView.setVisibility(View.VISIBLE);// Call back (only in API level <19, because in API level 19+ with chromium webview it crashes)if (videoViewCallback != null && !videoViewCallback.getClass().getName().contains(".chromium.")) {videoViewCallback.onCustomViewHidden();}// Reset video related variablesisVideoFullscreen = false;videoViewContainer = null;videoViewCallback = null;// Notify full-screen changeif (toggledFullscreenCallback != null) {toggledFullscreenCallback.toggledFullscreen(false);}}}@Override// Video will start loadingpublic View getVideoLoadingProgressView() {if (loadingView != null) {loadingView.setVisibility(View.VISIBLE);return loadingView;} else {return super.getVideoLoadingProgressView();}}@Override// Video will start playing, only called in the case of android.widget.VideoView (typically API level <11)public void onPrepared(MediaPlayer mp) {if (loadingView != null) {loadingView.setVisibility(View.GONE);}}@Override// Video finished playing, only called in the case of android.widget.VideoView (typically API level <11)public void onCompletion(MediaPlayer mp) {onHideCustomView();}@Override// Error while playing video, only called in the case of android.widget.VideoView (typically API level <11)public boolean onError(MediaPlayer mp, int what, int extra) {return false; // By returning false, onCompletion() will be called}/*** Notifies the class that the back key has been pressed by the user.* This must be called from the Activity's onBackPressed(), and if it returns false, the activity itself should handle it. Otherwise don't do anything.* @return Returns true if the event was handled, and false if was not (video view is not visible)*/@SuppressWarnings("unused")public boolean onBackPressed() {if (isVideoFullscreen) {onHideCustomView();return true;} else {return false;}}
}

        VideoEnabledWebView.java

package ***.***.***;import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.util.AttributeSet;
import android.webkit.WebChromeClient;
import android.webkit.WebView;import java.util.Map;public class VideoEnabledWebView extends WebView {public class JavascriptInterface {@android.webkit.JavascriptInterface@SuppressWarnings("unused")// Must match Javascript interface method of VideoEnabledWebChromeClientpublic void notifyVideoEnd() {// This code is not executed in the UI thread, so we must force that to happennew Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() {if (videoEnabledWebChromeClient != null) {videoEnabledWebChromeClient.onHideCustomView();}}});}@android.webkit.JavascriptInterface@SuppressWarnings("unused")// Must match Javascript interface method of VideoEnabledWebChromeClientpublic void notifyVideoStart() {// This code is not executed in the UI thread, so we must force that to happennew Handler(Looper.getMainLooper()).post(new Runnable() {@Overridepublic void run() {loadUrl("javascript:(" +"function() { " +" var videos = document.getElementsByTagName('video'); " +" var video = videos[0]; " +" if (!document.webkitFullScreen && video.webkitEnterFullscreen) {" +" video.webkitEnterFullscreen(); " +" } " +" })()");}});}}private VideoEnabledWebChromeClient videoEnabledWebChromeClient;private boolean addedJavascriptInterface;@SuppressWarnings("unused")public VideoEnabledWebView(Context context) {super(context);addedJavascriptInterface = false;}@SuppressWarnings("unused")public VideoEnabledWebView(Context context, AttributeSet attrs) {super(context, attrs);addedJavascriptInterface = false;}@SuppressWarnings("unused")public VideoEnabledWebView(Context context, AttributeSet attrs, int defStyle) {super(context, attrs, defStyle);addedJavascriptInterface = false;}/*** Indicates if the video is being displayed using a custom view (typically full-screen)** @return true it the video is being displayed using a custom view (typically full-screen)*/@SuppressWarnings("unused")public boolean isVideoFullscreen() {return videoEnabledWebChromeClient != null && videoEnabledWebChromeClient.isVideoFullscreen();}/*** Pass only a VideoEnabledWebChromeClient instance.*/@Override@SuppressLint("SetJavaScriptEnabled")public void setWebChromeClient(WebChromeClient client) {getSettings().setJavaScriptEnabled(true);if (client instanceof VideoEnabledWebChromeClient) {this.videoEnabledWebChromeClient = (VideoEnabledWebChromeClient) client;}super.setWebChromeClient(client);}@Overridepublic void loadData(String data, String mimeType, String encoding) {addJavascriptInterface();super.loadData(data, mimeType, encoding);}@Overridepublic void loadDataWithBaseURL(String baseUrl, String data, String mimeType, String encoding, String historyUrl) {addJavascriptInterface();super.loadDataWithBaseURL(baseUrl, data, mimeType, encoding, historyUrl);}@Overridepublic void loadUrl(String url) {super.loadUrl(url);addJavascriptInterface();}@Overridepublic void loadUrl(String url, Map<String, String> additionalHttpHeaders) {addJavascriptInterface();super.loadUrl(url, additionalHttpHeaders);}@SuppressLint("AddJavascriptInterface")private void addJavascriptInterface() {if (!addedJavascriptInterface) {// Add javascript interface to be called when the video ends (must be done before page load)// Must match Javascript interface name of VideoEnabledWebChromeClientaddJavascriptInterface(new JavascriptInterface(), "_VideoEnabledWebView");addedJavascriptInterface = true;}}
}

六、效果

        打开App之后,经过2s的时间(对于个人而言,2s是可接受的等待时间)直接视频全屏播放

        但我发现url有时候不是特别稳定,所以有时候看不了,并建议使用电脑端访问。

七、参考资料

1.如何在android WebView中全屏播放HTML5视频?

2.android webview播放视频自动全屏

八、声明

上述代码仅限个人的学习使用,请勿用于商业用途,请勿非法使用,谢谢。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2812009.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

大模型学习笔记四:LangChain开发框架解析

文章目录 一、langChain核心组件介绍二、模块I/O封装1&#xff09;多轮对话 Session 封装2&#xff09;模型的输入&#xff08;1&#xff09;Prompt模板封装&#xff08;2&#xff09;从文件加载Prompt模板 3&#xff09;模型的输出&#xff08;1&#xff09;Pydantic (JSON) P…

c入门第二十四篇: 学生成绩管理系统优化(可执行文件传参)

前言 我&#xff1a;“师弟&#xff0c;review完你的代码之后&#xff0c;你觉得有没有什么地方可以优化&#xff1f;” 师弟一脸懵。 我&#xff1a;“比如&#xff0c;你把客户端和服务端的可执行文件生成之后&#xff0c;我把服务端部署到我的测试机器上&#xff0c;客户端…

通过css修改video标签的原生样式

通过css修改video标签的原生样式 描述实现结果 描述 修改video标签的原生样式 实现 在控制台中打开设置&#xff0c;勾选显示用户代理 shadow DOM&#xff0c;就可以审查video标签的内部样式了 箭头处标出来的就是shodow DOM的内容&#xff0c;这些内容正常不可见的&#x…

下载huggingface数据集到本地并读取.arrow文件遇到的问题

文章目录 1. 524MB中文维基百科语料&#xff08;需要下载的数据集&#xff09;2. 下载 hugging face 网站上的数据集3. 读取 .arrow 文件报错代码4. 纠正后代码 1. 524MB中文维基百科语料&#xff08;需要下载的数据集&#xff09; 2. 下载 hugging face 网站上的数据集 要将H…

07_第七章 前端工程化(es6,Vue3,Element_plus组件库)

文章目录 第七章 前端工程化一、前端工程化开篇1.1 什么是前端工程化1.2 前端工程化实现技术栈 二、ECMA6Script2.1. es6的介绍2.2 es6的变量和模板字符串2.3 es6的解构表达式2.4 es6的箭头函数2.4.1 声明和特点2.4.2 实践和应用场景2.4.3 rest和spread 2.5 es6的对象创建和拷贝…

绝地求生:春节部分活动将结束,3月有新版本上线,通行证不偷懒可换成长型

嗨&#xff0c;我是闲游盒~ 感觉过年就在眼前但是已经结束了&#xff0c;时间过的太快了又回归了工作的生活中&#xff0c;而年前更新的28.1新春版本也进行到了小一半的进度。 ◆ 春节版本部分活动即将结束 在大厅首页右上角的活动中心里&#xff0c;春节积分商店和觉醒之旅活动…

MATLAB环境下一种改进的瞬时频率(IF)估计方法

相对于频率成分单一、周期性强的平稳信号来说&#xff0c;具有非平稳、非周期、非可积特性的非平稳信号更普遍地存在于自然界中。调频信号作为非平稳信号的一种&#xff0c;由于其频率时变、距离分辨率高、截获率低等特性&#xff0c;被广泛应用于雷达、地震勘测等领域。调频信…

sqllabs第46关 order by 注入(通过盲注)

打开第46关 提示我们(请将参数输入为sort&#xff08;带数值&#xff09;) 用sort注入排序 尝试操作 order by注入 什么是order by 在MySQL支持使用ORDER BY语句对查询结果集进行排序处理&#xff0c;使用ORDER BY语句不仅支持对单列数据的排序&#xff0c;还支持对数据表中…

vulnhub----hackme2-DHCP靶机

文章目录 一&#xff0c;信息收集1.网段探测2.端口扫描3.目录扫描 二&#xff0c;信息分析三&#xff0c;sql注入1.判断SQL注入2.查询显示位3.查询注入点4.查询库5.查询表6.查字段7. 查user表中的值8.登陆superadmin用户 四&#xff0c;漏洞利用文件上传命令执行蚁剑连接 五&am…

商家入驻平台怎么让资金自动分配给商家

最近很多上线了多商户电商系统的朋友咨询&#xff0c;我们平台的用户支付后&#xff0c;钱进入了我们的对公账户&#xff0c;怎样让钱在走完流程后&#xff0c;自动进入商家的账户呢&#xff1f;今天商淘云为您分享商户入驻平台自动分配给商家资金的三种方法。 首先是平台应建立…

k8s二进制部署的搭建

1.1 常见k8s安装部署方式 ●Minikube Minikube是一个工具&#xff0c;可以在本地快速运行一个单节点微型K8S&#xff0c;仅用于学习、预览K8S的一些特性使用。 部署地址&#xff1a;Install Tools | Kubernetes ●Kubeadm Kubeadm也是一个工具&#xff0c;提供kubeadm init…

Java根据excel模版导出Excel(easyexcel、poi)——含项目测试例子拿来即用

Java根据excel模版导出Excel&#xff08;easyexcel、poi&#xff09;——含项目测试例子拿来即用 1. 前言1.1 关于Excel的一般导出2.2 关于easyexcel的根据模版导出 2. 先看效果2.1 模版2.2 效果 3. 代码实现&#xff08;核心代码&#xff09;3.1 项目代码结构3.2 静态填充例子…

数字电路 第四章—第一节(触发器——概述)

一、对触发器的基本要求 1、触发器的概念 在数字电路中&#xff0c;基本的工作信号是二进制数字信号和两状态逻辑信号&#xff0c;而触发器就是存放这些信号的单元电路。 2、对触发器的基本要求 &#xff08;1&#xff09;具有两个稳定状态——0状态和1状态&#xff0c;以正…

负载均衡.

简介: 将请求/数据【均匀】分摊到多个操作单元上执行&#xff0c;负载均衡的关键在于【均匀】。 负载均衡的分类: 网络通信分类 四层负载均衡:基于 IP 地址和端口进行请求的转发。七层负载均衡:根据访问用户的 HTTP 请求头、URL 信息将请求转发到特定的主机。 载体维度分类 硬…

物资管理新篇章:Java+SpringBoot实战

✍✍计算机编程指导师 ⭐⭐个人介绍&#xff1a;自己非常喜欢研究技术问题&#xff01;专业做Java、Python、微信小程序、安卓、大数据、爬虫、Golang、大屏等实战项目。 ⛽⛽实战项目&#xff1a;有源码或者技术上的问题欢迎在评论区一起讨论交流&#xff01; ⚡⚡ Java实战 |…

List去重有几种方式

目录 1、for循环添加去重 2、for 双循环去重 3、for 双循环重复坐标去重 4、Set去重 5、stream流去重 1、for循环添加去重 List<String> oldList new ArrayList<>();oldList.add("张三");oldList.add("张三");oldList.add("李四&q…

数字电路 第三章—第七节(用中规模集成电路实现组合逻辑函数)

一、用数据选择器实现组合逻辑函数 1、基本原理和步骤 &#xff08;1&#xff09;原理&#xff1a;选择器的输出为标准与或式&#xff0c;含地址变量的全部最小项&#xff08;如下图所示的红线标注部分&#xff09;&#xff0c;而任何组合逻辑函数都可以表示成为最小项之和的…

项目管理工具git

git 1. git介绍1.1. 版本控制系统 2. 创建本地版本库2.1 概念2.2 操作步骤 3. 修改文件4. 练习: 添加一个本地项目到仓库5. 添加远程仓库5.1 添加远程仓库5.2 本地仓库同步到远程仓库5.3 克隆远程仓库到本地5.4 SSH设置 6. 分支管理6.1 创建分支6.2 切换分支6.3 合并分支6.4 解…

实践航拍小目标检测,基于轻量级YOLOv8n开发构建无人机航拍场景下的小目标检测识别分析系统

关于无人机相关的场景在我们之前的博文也有一些比较早期的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《deepLabV3Plus实现无人机航拍目标分割识别系统》 《基于目标检测的无人机航拍场景下小目标检测实践》 《助力环保河道水质监测&#xff0c;基于yolov…

QT之项目经验(windows下的sqlite,c++开发)

目录 一、需要时间去磨练gui的调整和优化 1. 借鉴网上开源项目学习 2. gui的布局及调整是磨人的一件事情 3. gui的布局也是可以用组件复刻的 4. 耗时的设备树 二、多线程异步弹窗 三、定时任务动态变更设定 1.确定按钮触发 2.此处监听定时任务时间的改变 3.此处对改变做出具…