【Android -- UI 开发】WebView 的基本使用

2023-11-19

一、简介

WebView 在 Android 平台上是一个特殊的 View, 基于 webkit 引擎、展现 web 页面的控件,这个类可以被用来在你的 app 中仅仅显示一张在线的网页,还可以用来开发浏览器。WebView 内部实现是采用渲染引擎来展示 view的内容,提供网页前进后退,网页放大,缩小,搜索。

二、常用方法

1. 加载url

//方式1. 加载一个网页:
  webView.loadUrl("http://www.google.com/");

  //方式2:加载apk包中的html页面
  webView.loadUrl("file:///android_asset/test.html");

  //方式3:加载手机本地的html页面
   webView.loadUrl("content://com.android.htmlfileprovider/sdcard/test.html");

   // 方式4: 加载 HTML 页面的一小段内容
  WebView.loadData(String data, String mimeType, String encoding)
// 参数说明:
// 参数1:需要截取展示的内容
// 内容里不能出现 ’#’, ‘%’, ‘\’ , ‘?’ 这四个字符,若出现了需用 %23, %25, %27, %3f 对应来替代,否则会出现异常
// 参数2:展示内容的类型
// 参数3:字节码

2. WebView 的状态

//激活WebView为活跃状态,能正常执行网页的响应
webView.onResume()//当页面被失去焦点被切换到后台不可见状态,需要执行onPause
//通过onPause动作通知内核暂停所有的动作,比如DOM的解析、plugin的执行、JavaScript执行。
webView.onPause()//当应用程序(存在webview)被切换到后台时,这个方法不仅仅针对当前的webview而是全局的全应用程序的webview
//它会暂停所有webview的layout,parsing,javascripttimer。降低CPU功耗。
webView.pauseTimers()
//恢复pauseTimers状态
webView.resumeTimers()//销毁Webview
//在关闭了Activity时,如果Webview的音乐或视频,还在播放。就必须销毁Webview
//但是注意:webview调用destory时,webview仍绑定在Activity上
//这是由于自定义webview构建时传入了该Activity的context对象
//因此需要先从父容器中移除webview,然后再销毁webview:
rootLayout.removeView(webView); 
webView.destroy();

3. 关于前进 / 后退网页

//是否可以后退
Webview.canGoBack() 
//后退网页
Webview.goBack()

//是否可以前进                     
Webview.canGoForward()
//前进网页
Webview.goForward()

//以当前的index为起始点前进或者后退到历史记录中指定的steps
//如果steps为负数则为后退,正数则为前进
Webview.goBackOrForward(intsteps) 

问题:在不做任何处理前提下 ,浏览网页时点击系统的“Back”键,整个 Browser 会调用 finish()而结束自身?
解决方案:

public boolean onKeyDown(int keyCode, KeyEvent event) {
    if ((keyCode == KEYCODE_BACK) && mWebView.canGoBack()) { 
        mWebView.goBack();
        return true;
    }
    return super.onKeyDown(keyCode, event);
}

4. 清除缓存数据

//清除网页访问留下的缓存
//由于内核缓存是全局的因此这个方法不仅仅针对webview而是针对整个应用程序.
Webview.clearCache(true);

//清除当前webview访问的历史记录
//只会webview访问历史记录里的所有记录除了当前访问记录
Webview.clearHistory()//这个api仅仅清除自动完成填充的表单数据,并不会清除WebView存储到本地的数据
Webview.clearFormData()

三、实例

需求:

  • 实现显示加载进度条;
  • 网页中的电话号码可以拨打;
  • 网页中添加图片、视频等文件。

在这里插入图片描述

1. 在 AndroidManifest.xml 中添加访问网络权限

<uses-permission android:name="android.permission.INTERNET"/>

2. 布局文件

<?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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.ScanOrderActivity">
    <com.hjq.bar.TitleBar
        android:id="@+id/title_bar"
        android:layout_width="match_parent"
        android:background="@color/purple_500"
        android:layout_height="?android:attr/actionBarSize"
        app:title="@string/new_order"
        app:titleStyle="bold"
        app:titleSize="18sp"
        app:titleColor="@color/white"
        app:leftIcon="@mipmap/ic_back"/>

    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="10dp"/>
</LinearLayout>

3. 逻辑代码

public class ScanOrderActivity extends BaseActivity {
    private ValueCallback<Uri[]> mUploadCallbackAboveL;
    private ValueCallback<Uri> mUploadCallbackBelow;
    private Uri imageUri;
    private final int REQUEST_CODE_IMG = 10011;
    private final int REQUEST_CODE_VIDEO = 10022;

    @BindView(R.id.title_bar)
    TitleBar mTitleBar;

    @BindView(R.id.webView)
    WebView mWebView;

    private WebSettings mWebSettings;

    private ProgressDialog dialog = null;

    @Override
    protected int getLayoutId() {
        return R.layout.activity_add_order;
    }

    @Override
    protected void initView() {

        mTitleBar.setOnTitleBarListener(new OnTitleBarListener() {
            @Override
            public void onLeftClick(View view) {
                finish();
            }

            @Override
            public void onTitleClick(View view) {

            }

            @Override
            public void onRightClick(View view) {

            }
        });

        Bundle bundle = getIntent().getExtras();
        String url = bundle.getString("newOrder");
        mWebView.loadUrl(url);

        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (url.startsWith("tel:")) {
                    Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
                    startActivity(intent);
                }else if (url.startsWith("http:") || url.startsWith("https:")) {
                    view.loadUrl(url);
                }

                return true;
            }
        });

        mWebSettings = mWebView.getSettings();
        mWebSettings.setJavaScriptEnabled(true);
        mWebSettings.setAllowFileAccess(true);
        mWebSettings.setAllowFileAccessFromFileURLs(true);
        mWebSettings.setAllowUniversalAccessFromFileURLs(true);
        mWebSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        mWebSettings.setBuiltInZoomControls(true);
        mWebSettings.setSupportZoom(false);
        mWebSettings.setUseWideViewPort(true);
        mWebSettings.setLoadWithOverviewMode(true);
        mWebSettings.setGeolocationEnabled(true);
        mWebSettings.setDomStorageEnabled(true);
        mWebView.requestFocus();
        mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
        //优先使用缓存
        mWebSettings.setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);

        mWebView.setWebChromeClient(new WebChromeClient() {
                                        @Override
                                        public void onPermissionRequest(PermissionRequest request) {
                                            request.grant(request.getResources());
                                            request.getOrigin();
                                        }

                                        @Override
                                        public void onProgressChanged(WebView view, int newProgress) {
                                            if (newProgress == 100) {
                                                // 加载完毕
                                                closeDialog(newProgress);
                                            } else {
                                                openDialog(newProgress);
                                            }
                                            super.onProgressChanged(view, newProgress);
                                        }

                                        @Override
                                        public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
                                            mUploadCallbackAboveL = filePathCallback;
                                            String[] acceptTypes = fileChooserParams.getAcceptTypes();
                                            if (acceptTypes.length > 0) {
                                                openCamera(acceptTypes[0]);
                                            }
                                            return true;
                                        }
                                    }
        );

    }

    private void openDialog(int newProgress) {
        if (dialog == null) {
            dialog = new ProgressDialog(ScanOrderActivity.this);
            dialog.setTitle("正在加载");
            dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            dialog.setProgress(newProgress);
            dialog.show();
        } else {
            dialog.setProgress(newProgress);
        }
    }

    private void closeDialog(int newProgress) {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
            dialog = null;
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_CODE_VIDEO) {
            if (null != mUploadCallbackBelow) {
                Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
                mUploadCallbackBelow.onReceiveValue(result);
                mUploadCallbackBelow = null;
            } else if (null != mUploadCallbackAboveL) {
                Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();
                if (result != null) {
                    mUploadCallbackAboveL.onReceiveValue(new Uri[]{result});
                } else {
                    mUploadCallbackAboveL.onReceiveValue(null);
                }
                mUploadCallbackAboveL = null;
            }
        } else if (requestCode == REQUEST_CODE_IMG) {
            // 经过上边(1)、(2)两个赋值操作,此处即可根据其值是否为空来决定采用哪种处理方法
            if (mUploadCallbackBelow != null) {
                chooseBelow(resultCode, data);
            } else if (mUploadCallbackAboveL != null) {
                chooseAbove(resultCode, data);
            } else {
                ToastUtils.showToast(ScanOrderActivity.this,"发生错误");
            }
        }
    }

    /**
     * 调用相机/相册选择器弹窗
     */
    private void openCamera(String accept) {
        if (accept.contains("video")) {
            Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);//设置视频录制的质量,0为低质量,1为高质量。
            //intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 6);//限制时长 单位秒
            //intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, 1024L * 1024 * 10);//指定视频最大允许的尺寸,单位为byte
            //开启摄像机
            startActivityForResult(intent, REQUEST_CODE_VIDEO);
        } else {
            // 指定拍照存储位置的方式调起相机
            String filePath = Environment.getExternalStorageDirectory() + File.separator
                    + Environment.DIRECTORY_PICTURES + File.separator;
            String fileName = "IMG_" + DateFormat.format("yyyyMMdd_hhmmss", Calendar.getInstance(Locale.CHINA)) + ".jpg";
            imageUri = Uri.fromFile(new File(filePath + fileName));

//        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
//        startActivityForResult(intent, REQUEST_CODE_IMG);


            // 选择图片(不包括相机拍照),则不用成功后发刷新图库的广播
//        Intent i = new Intent(Intent.ACTION_GET_CONTENT);
//        i.addCategory(Intent.CATEGORY_OPENABLE);
//        i.setType("image/*");
//        startActivityForResult(Intent.createChooser(i, "Image Chooser"), REQUEST_CODE_IMG);

            Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);

            Intent photo = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            Intent chooserIntent = Intent.createChooser(photo, "Image Chooser");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Parcelable[]{captureIntent});

            startActivityForResult(chooserIntent, REQUEST_CODE_IMG);
        }
    }

    /**
     * Android API < 21(Android 5.0)版本的回调处理
     *
     * @param resultCode 选取文件或拍照的返回码
     * @param data       选取文件或拍照的返回结果
     */
    private void chooseBelow(int resultCode, Intent data) {
        if (RESULT_OK == resultCode) {
            updatePhotos();
            if (data != null) {
                // 这里是针对文件路径处理
                Uri uri = data.getData();
                if (uri != null) {
                    mUploadCallbackBelow.onReceiveValue(uri);
                } else {
                    mUploadCallbackBelow.onReceiveValue(null);
                }
            } else {
                // 以指定图像存储路径的方式调起相机,成功后返回data为空
                mUploadCallbackBelow.onReceiveValue(imageUri);
            }
        } else {
            mUploadCallbackBelow.onReceiveValue(null);
        }
        mUploadCallbackBelow = null;
    }

    /**
     * Android API >= 21(Android 5.0) 版本的回调处理
     *
     * @param resultCode 选取文件或拍照的返回码
     * @param data       选取文件或拍照的返回结果
     */
    private void chooseAbove(int resultCode, Intent data) {
        if (RESULT_OK == resultCode) {
            updatePhotos();
            if (data != null) {
                // 这里是针对从文件中选图片的处理
                Uri[] results;
                Uri uriData = data.getData();
                if (uriData != null) {
                    results = new Uri[]{uriData};
                    for (Uri uri : results) {
                        Log.d("TAG", "chooseAbove: "+uri.toString());
                    }
                    mUploadCallbackAboveL.onReceiveValue(results);
                } else {
                    mUploadCallbackAboveL.onReceiveValue(null);
                }
            } else {
                mUploadCallbackAboveL.onReceiveValue(new Uri[]{imageUri});
            }
        } else {
            mUploadCallbackAboveL.onReceiveValue(null);
        }
        mUploadCallbackAboveL = null;
    }

    private void updatePhotos() {
        // 该广播即使多发(即选取照片成功时也发送)也没有关系,只是唤醒系统刷新媒体文件
        Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent.setData(imageUri);
        sendBroadcast(intent);
    }


    //销毁Webview
    @Override
    protected void onDestroy() {
        if (mWebView != null) {
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebView.clearHistory();

            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }

}

四、面试题

  • 如何避免 WebView 内存泄露?
  1. 不在 xml 中定义 Webview ,而是在需要的时候在 Activity 中创建,并且 Context 使用 getApplicationgContext()。
		LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        mWebView = new WebView(getApplicationContext());
        mWebView.setLayoutParams(params);
        mLayout.addView(mWebView);
  1. 在 Activity 销毁( WebView )的时候,先让 WebView 加载null内容,然后移除 WebView,再销毁 WebView,最后置空。
	@Override
    protected void onDestroy() {
        if (mWebView != null) {
            mWebView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null);
            mWebView.clearHistory();

            ((ViewGroup) mWebView.getParent()).removeView(mWebView);
            mWebView.destroy();
            mWebView = null;
        }
        super.onDestroy();
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Android -- UI 开发】WebView 的基本使用 的相关文章

  • 是否可以使用最新的 APP_PLATFORM,同时仍保持向后兼容性?

    这是我的 Application mk APP ABI armeabi v7a APP PLATFORM android 16 APP OPTIM release APP STL gnustl static APP CPPFLAGS std
  • 显示警报或收到通知时的视图

    我正在关注this http tokudu com 2010 how to implement push notifications for android 显示的教程通知 on an 安卓设备 当我在设备上运行该应用程序时 状态栏上会出现
  • Android Studio - 错误:未捕获翻译错误:com.android.dx.cf.code.SimException:本地 0001:无效

    我刚刚使用 Android Studio 设置了一台新计算机 并从 bitbucket 导入了我的项目 问题是我现在在尝试构建项目时遇到此错误 信息 Gradle 任务 app clean app generateDebugSources
  • Google Firebase - 如何删除崩溃报告?

    我最终失明了吗 还是没有明显的方法可以通过 Google Firebase Web 控制台删除 Firebase 崩溃报告 我的 Android 应用程序已成功记录报告 但现在出现大量 开发崩溃 占用了我在控制台中的大部分视图 这使得找到实
  • 为什么按钮上的 maxWidth 不起作用以及如何解决它?

    我的布局上有两个按钮 在大屏幕设备 平板电脑 上我想限制它们的宽度 这样它们看起来就不会很荒谬 我希望使用 maxWidth 属性 但它显然在我的场景中没有任何作用 这是布局定义 按钮使用布局的整个宽度 忽略 maxWidth 中的任何值
  • Android Studio - 如何关闭“单词‘word’中的拼写错误?”

    当命名变量或给出字符串参数时 Android Studio 似乎对我如何标记事物有问题 有办法把它关掉吗 是的 打开Preferences gt Editor gt Inspections gt Spelling gt 关闭Typo并按OK
  • 从多个选项卡中的编辑文本字段获取文本

    我正在尝试创建一个使用选项卡作为输入表单的 Android 应用程序 基本上 我希望对其进行设置 以便用户可以在一个选项卡上输入一些信息 然后提交该信息 或者转到另一个选项卡并输入更多信息 然后从两个选项卡提交信息 我正在使用操作栏和片段来
  • AnalyticsService 未在应用程序清单中注册 - 错误

    我正在尝试使用 sdk 中提供的以下文档向 Android 应用程序实施谷歌分析服务 https developers google com analytics devguides collection android v4 https d
  • Android Web Intent 问题

    G day 免责声明 我不是 Android 开发人员 我正在对我所描述的问题进行质量检查 我用来描述这个问题的技术术语可能是错误的 我正在测试一个 Android 应用程序 该应用程序在其清单中描述它可以使用 type 的地址处理 Web
  • 如何从android获取应用程序安装时间

    我尝试了一些方法 但没有成功 请帮助我 PackageManager pm context getPackageManager ApplicationInfo appInfo pm getApplicationInfo app packag
  • 加快 ImageView 中的缩放功能

    我目前正在处理非常大的图像 7 10mb 由于多种原因无法调整大小或压缩 现在 我们的想法是在自定义 ImageView 中显示它们 使用户能够进行双击缩放 捏合缩放等 我使用这个库来完成这项工作 https github com Mike
  • 如何在android中的操作栏中创建Edittext?

    我们可以在操作栏中使用编辑文本吗 在阅读了 Google 中的大量资源后 我找不到如何在操作栏中创建编辑文本 谁能告诉我该怎么做 您可以设置自定义View为了ActionBar像这样 getActionBar setCustomView R
  • 通过列表视图检查动态生成的复选框时遇到问题

    我知道其他成员已经提出了这个问题 一些成员也给出了解决方案 但问题是我没有找到任何适合我的应用程序的解决方案 我正在创建一个应用程序 其中我有一个屏幕 它将显示动态列表视图 其中包含列表项 复选框和三个文本视图 一个用于候选人姓名 另外两个
  • 从手机访问本地主机[关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 我正在使用
  • ACCESS_BACKGROUND_LOCATION 不适用于低于 Q (29) 的 Android 版本

    我的应用程序面向 Android API 28 根据文档 https developer android com preview privacy location target android 10 我应该要求ACCESS BACKGROU
  • 内部存储的安全性如何?

    我需要的 对于 Android 我需要永久保存数据 但也能够编辑 并且显然是读取 它 用户不应访问此数据 它可以包含诸如高分之类的内容 用户不得对其进行编辑 我的问题 我会 并且已经 使用过Internal Storage 但我不确定它实际
  • Android:确定 2.2 及更高版本上的摄像头数量

    我的应用程序需要在 Android 2 2 及更高版本上运行 我需要一种方法来确定可用摄像机的数量 有很多帖子解决了这个问题 但我找不到一个有效的 一种解决方案是简单地检测操作系统版本 任何 2 2 版本的设备都仅限于 1 个摄像头 即使该
  • “无法实例化活动”错误

    我的一个 Android 应用程序拥有大约 100 000 个用户 每周大约 10 次 我会通过 Google 的市场工具向我报告以下异常情况 java lang RuntimeException Unable to instantiate
  • Android:无法发送http post

    我一直在绞尽脑汁试图弄清楚如何在 Android 中发送 post 方法 这就是我的代码的样子 public class HomeActivity extends Activity implements OnClickListener pr
  • [cocos2d-x]当我尝试在 Windows 10 中运行“python android-build.py -p 19 cpp-tests”时出现错误

    当我尝试运行命令时python android build p cpp tests 我收到如图所示的错误 在此之前 我收到了另一条关于 Android SDK Tools 版本兼容性的错误消息 所以 我只是将 sdk 版本从 26 0 0

随机推荐

  • 软件和建筑的结构

    一般都倾向于将软件比作建筑 因为建筑的架构和软件框架类似 好的建筑需要好的框架 但是大家忽略了另外一个情况 一个建筑要能居住 不但要好的建 筑风格和框架 更需要有好的家居和内部装修 建筑居住的舒适度很大程度上由内部装修细节决定的 装修时家居
  • 程序员,职场上请远离这种人!

    对有些职场人来讲 甩锅就是一种生存手段 01 从大学打篮球说起 上大学的时候喜欢打篮球 然后我又特别喜欢抢篮板 经常是跳起来的时候没事 落下来的时候偶尔会踩到别人的脚上 于是左脚经常性崴脚 这是背景 我们班上有一个同学也喜欢打篮球 我俩水平
  • 多媒体透明屏,在户外广告领域中,有哪些应用展示?

    多媒体透明屏是一种新型的显示技术 它能够将图像和视频直接投射到透明的屏幕上 使得观众可以同时看到屏幕后面的实物 这种技术在广告 展览 商场等场合有着广泛的应用前景 多媒体透明屏的原理是利用透明显示技术 将图像和视频通过光学投射技术投射到透明
  • 【C语言初学】作业:计算在贷款第一个月、第二个月、第三个月后需要还款金额

    贷款金额 20000 00元 年贷款利率 6 0 每个月还款金额 386 66 第一个月剩余的需还款金额 19713 34元 第二个月剩余的需还款金额 19425 25元 第三个月剩余的需还款金额 19135 71元 提示 每个月剩余的贷款
  • 深入浅出 sideEffects

    前言 最近在给团队对 webpack 中的 sideEffects 字段用途进行微分享 于是乎 我最后就整理成一篇文章 希望帮助更多的人理解 sideEffects 的作用 sideEffects 是什么呢 我用一句话来概括就是 让 web
  • redis 安装配置

    原文链接 https www cpweb top 1266 一 介绍 Redis 是一个开源的 基于内存的数据结构存储系统 它可以用作数据库 缓存和消息中间件 它是一个键值 Key Value 存储数据库 为非关系型数据库 它支持多种类型的
  • 在el-table的功能,并且在单元格里面加入输入框

    在我们的前端拿到后端返回的数据的时候 需要在el table的功能 并且在单元格里面加入输入框 为了让输入框的输入时候不会影响到其他的输入框 可以使用 input来获取输入框内容的值
  • python 多个logger对象使用,输出到多个文件

    就不介绍logger基础配置了 如何创建多个logger对象 输出到多个文件 import logging from datetime import datetime def get logger name logger logging g
  • 解决BookxNotePro在linux下无法启动或GLIBC_2.29‘ not found的问题

    问题描述如题 命令行启动出现如下报错 usr local BookxNotePro BookxNotePro usr local BookxNotePro BookxNotePro lib x86 64 linux gnu libm so
  • JS声明二维数组常见办法

    JS声明二维数组常见办法 目录 文章目录 前言 new Array 和 fill fill 灵活插入 for 笨办法 Array from 前言 目前论坛常见的办法代码质量奇差 因此针对这个问题进行整理 new Array和fill con
  • 使用机器学习算法打造一个简单的“微博指数”

    欢迎大家前往腾讯云技术社区 获取更多腾讯海量技术实践干货哦 作者 林浩威 前言 随着人工智能的大热 越来越多的小伙伴们开始投身到机器学习的大潮中 作为其中的一员 我对此也是极有兴趣的 当然我更感兴趣的 是怎么利用这些有趣的算法 来实现脑海里
  • element样式无法修改

    在使用el form组件时 组件中的字体是黑色的 需要显示白色字体就加了个color fff 结果发现修改并没有什么效果 还是原来的黑色 打开F12发现属于 el form item label选择器下面的 我就在css下面修改了该选择器
  • 端口占用查询

    我们做WEB开发 本地调试时 有时出现 Caused by java net BindException Address already in use bind at sun nio ch Net bind0 Native Method a
  • 机械孔与盲孔

    过孔是什么 过孔 Via 电路板上的孔 连接不同层之间的线路 把电路板从平面结构变成立体结构 单层线路想不交叉太难了 双层或更多层线路 必须通过过孔来连接 通过孔壁上的铜 连通上下层的电路铜线 单层PCB 有些时候无法布线 必须通过过孔换层
  • Chisel手册之Types

    本文是Chisel手册第二篇Types Types 表示硬件设计的Chisel图包含原始节点和类型节点 Chisel类型系统与底层Scala类型系统分开维护 因此类型节点散布在原始节点之间 以允许Chisel检查并响应Chisel类型 Ch
  • 微信小程序 实现底部导航栏tabbar

    参考链接 1 微信小程序底部导航Tabbar https www cnblogs com huangjialin p 6278429 html 2 小程序自定义tabbar实现中间图标突出效果 附带wx hideTabBar不生效的bug解
  • Spring Boot 启动报错解决:No active profile set, falling back to default profiles: default

    在SpringBoot启动时 控制台打印出来的信息有这么一条 No active profile set falling back to default profiles default 如下图 这句话的意思是 没有指定项目的配置文件 使用
  • Skyfire: 一种用于Fuzzing的数据驱动的种子生成工具

    Skyfire Data Driven Seed Generation for Fuzzing 作者 杨鑫 清华大学 论文发表于 IEEE S P 2017 原文作者 Junjie Wang Bihuan Chen Lei Wei and
  • C# 使用SignalR实现消息通知

    背景 Web端需要能实时接收到消息推送 当客户有新消息来时 在客户端的右下角进行弹框提醒 什么是signalR Asp net SignalR是微软为实现实时通信的一个类库 一般情况下 signalR会使用JavaScript的长轮询 lo
  • 【Android -- UI 开发】WebView 的基本使用

    一 简介 WebView 在 Android 平台上是一个特殊的 View 基于 webkit 引擎 展现 web 页面的控件 这个类可以被用来在你的 app 中仅仅显示一张在线的网页 还可以用来开发浏览器 WebView 内部实现是采用渲