MyWebViewDemo【封装Webview常用配置和选择文件、打开相机、录音、打开本地相册的用法】
版权声明:本文为HaiyuKing原创文章,转载请注明出处!
前言
封装webview的常用配置和选择文件、打开相机、录音、打开本地相册的用法。【如果想要使用简单的预览功能,可以参考《MyBridgeWebViewDemo【集成JsBridge开源库的的封装的webview】》】
注意:如果使用选择文件、打开相机、录音、打开本地相册的功能,那么就需要搭配《Android6.0运行时权限(基于RxPermission开源库)》的申请运行时权限(相机、录音、存储权限)、《AppUtils【获取手机的信息和应用版本号、安装apk】》的适配7.0FileProvider功能。
效果图

代码分析
一、申请运行时权限主要涉及到以下文件:
app中的build.gradle

AndroidManifest.xml

MainActivity.java

二、适配7.0File Provider主要涉及到以下文件:
AndroidManifest.xml

xml/provider_paths.xml

使用步骤
一、项目组织结构图



注意事项:
1、 导入类文件后需要change包名以及重新import R文件路径
2、 Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖
二、导入步骤
0-1、申请运行时权限,参考《Android6.0运行时权限(基于RxPermission开源库)》
0-2、适配Android7.0FileProvider功能,参考《AppUtils【获取手机的信息和应用版本号、安装apk】》
1、将assets文件夹复制到项目中

404.html【自定义404页面,会调用WebViewJSInterface中的refresh方法】
<!DOCTYPE html>
<html>
<head>
<meta charset=utf-8 />
<meta http-equiv="keywords" content="404">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="renderer" content="webkit"> <title>404哟</title>
</head>
<body>
<div class="demo">
<p><span>4</span><span>0</span><span>4</span></p>
<p>网络正在开小差(´・ω・`)</p><br/>
<p><a onclick="window.androidMethod.refresh();">重新加载</a></p>
</div>
</body>
</html> <style type="text/css">
body {
background-color: #ECECEC;
font-family: 'Open Sans', sans-serif;
font-size: 14px;
color: #3c3c3c;
} .demo p:first-child {
text-align: center;
font-family: cursive;
font-size: 150px;
font-weight: bold;
line-height: 100px;
letter-spacing: 5px;
color: #fff;
} .demo p:first-child span {
cursor: pointer;
text-shadow: 0px 0px 2px #686868,
0px 1px 1px #ddd,
0px 2px 1px #d6d6d6,
0px 3px 1px #ccc,
0px 4px 1px #c5c5c5,
0px 5px 1px #c1c1c1,
0px 6px 1px #bbb,
0px 7px 1px #777,
0px 8px 3px rgba(100, 100, 100, 0.4),
0px 9px 5px rgba(100, 100, 100, 0.1),
0px 10px 7px rgba(100, 100, 100, 0.15),
0px 11px 9px rgba(100, 100, 100, 0.2),
0px 12px 11px rgba(100, 100, 100, 0.25),
0px 13px 15px rgba(100, 100, 100, 0.3);
-webkit-transition: all .1s linear;
transition: all .1s linear;
} .demo p:first-child span:hover {
text-shadow: 0px 0px 2px #686868,
0px 1px 1px #fff,
0px 2px 1px #fff,
0px 3px 1px #fff,
0px 4px 1px #fff,
0px 5px 1px #fff,
0px 6px 1px #fff,
0px 7px 1px #777,
0px 8px 3px #fff,
0px 9px 5px #fff,
0px 10px 7px #fff,
0px 11px 9px #fff,
0px 12px 11px #fff,
0px 13px 15px #fff;
-webkit-transition: all .1s linear;
transition: all .1s linear;
} .demo p:not(:first-child) {
text-align: center;
color: #666;
font-family: cursive;
font-size: 20px;
text-shadow: 0 1px 0 #fff;
letter-spacing: 1px;
line-height: 2em;
margin-top: -50px;
}
</style>
demo.html【用于演示选择文件、打开相机、录音、打开本地相册功能】
<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="content-type">
<meta http-equiv="keywords" content="测试">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<title>
webview
</title>
</head> <body>
<p>
<input type="file" value="打开文件" />
</p> <p>
点击下面的按钮,获取的文件路径:
</p>
<p>
<input type="text" id="filePath" value="文件路径" style="width:100%"/>
</p>
<p>
<input type="button" id="openRecord" value="打开录音" onclick="window.androidMethod.openRecord();"/>
</p>
<p>
<input type="button" id="takePicture" value="打开相机" onclick="window.androidMethod.takePicture();"/>
</p>
<p>
<input type="button" id="choosePic" value="打开本地相册" onclick="window.androidMethod.choosePic();"/>
</p>
<p>
<a href='tel:10010'>拨打电话:10010</a>
</p>
</body>
<script>
//打开录音、打开相机、打开本地相册,选择文件后返回的路径
function setInputText(urlPath){
document.getElementById("filePath").value = urlPath;
}
</script> </html>
demo.html
2、将customwebview包复制到项目中

3、将mywebview_progress_dialog_img_drawable.xml复制到项目中
<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框进度圆圈 -->
<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/mywebview_progress_dialog_img"
android:pivotX="50%"
android:pivotY="50%"
android:fromDegrees="0.0"
android:toDegrees="360.0"
android:repeatMode="restart"
/>
mywebview_progress_dialog_img_drawable.xml
4、将mywebview_progress_dialog_img.png图片复制到项目中


5、将mywebview_dialog_webviewprogress.xml复制到项目中
<?xml version="1.0" encoding="utf-8"?>
<!-- WebView使用的进度加载对话框布局文件 -->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/dialog_view"
android:layout_width="match_parent"
android:layout_height="match_parent"> <!-- 自定义圆形进度条 -->
<!-- android:indeterminateDrawable自定义动画图标 -->
<ProgressBar
android:id="@+id/loadProgressBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:layout_marginLeft="5dp"
android:layout_marginRight="5dp"
android:indeterminateDrawable="@drawable/mywebview_progress_dialog_img_drawable"
/> </RelativeLayout>
mywebview_dialog_webviewprogress.xml
6、在styles.xml文件中添加以下代码
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<!-- ==================MyWebview========网页加载时的进度对话框========================== -->
<style name="mywebview_loading_style" parent="android:style/Theme.Dialog">
<!-- Dialog的windowFrame框为无 -->
<item name="android:windowFrame">@null</item>
<!-- 是否显示title -->
<item name="android:windowNoTitle">true</item>
<!-- 是否浮现在activity之上 -->
<item name="android:windowIsFloating">true</item>
<!-- 设置dialog的背景:#00000000透明色 -->
<item name="android:windowBackground">@android:color/transparent</item>
<!-- 半透明 -->
<item name="android:windowIsTranslucent">true</item>
<!-- 背景变灰:整个屏幕变灰,配合setCanceledOnTouchOutside(false) -->
<item name="android:backgroundDimEnabled">false</item>
<!-- 对话框是否有遮盖 -->
<item name="android:windowContentOverlay">@null</item>
</style>
</resources>
7、在AndroidManifest.xml中添加以下代码
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.why.project.mywebviewdemo"> <!-- ======================(MyWebView)========================== -->
<!-- 允许程序打开网络套接字 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- ======================拍照用到的========================== -->
<uses-permission android:name="android.permission.CAMERA" />
<!-- ======================录音用到的========================== -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 向SD卡写入数据权限 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application
android: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"> <!-- =================7.0上读取文件========================== -->
<!--参考资料https://blog.csdn.net/lmj623565791/article/details/72859156-->
<!--authorities:{app的包名}.provider
grantUriPermissions:必须是true,表示授予 URI 临时访问权限
exported:必须是false
resource:中的@xml/provider_paths是我们接下来要添加的文件-->
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
</provider> <activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- 网页页面 -->
<activity android:name=".MyWebviewActivity">
</activity>
</application> </manifest>
三、使用方法
在布局文件activity_mywebview.xml中声明【实际项目中实际新的完整路径】
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.why.project.mywebviewdemo.customwebview.mywebview.MyWebView
android:id="@+id/web_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1"> </com.why.project.mywebviewdemo.customwebview.mywebview.MyWebView> </android.support.constraint.ConstraintLayout>
在Activity中使用如下
package com.why.project.mywebviewdemo; import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.util.Log;
import android.webkit.ValueCallback;
import android.webkit.WebView;
import android.widget.Toast; import com.why.project.mywebviewdemo.customwebview.mywebview.MyWebView;
import com.why.project.mywebviewdemo.customwebview.mywebview.WebViewJSInterface;
import com.why.project.mywebviewdemo.customwebview.utils.GetPathFromUri4kitkat;
import com.why.project.mywebviewdemo.customwebview.utils.WebviewGlobals; import java.io.File; /**
* Created by HaiyuKing
* Used webview
*/ public class MyWebviewActivity extends AppCompatActivity {
private static final String TAG = MyWebviewActivity.class.getSimpleName(); private MyWebView myWebView; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_mywebview); initViews();
initDatas();
initEvents();
} @Override
public void onDestroy()
{
//销毁webview控件
myWebView.removeAllViews();
myWebView.destroy();
super.onDestroy();
} private void initViews() {
myWebView = findViewById(R.id.web_view);
myWebView.setCanBackPreviousPage(true,MyWebviewActivity.this);//可以返回上一页
} private void initDatas() {
String openUrl = getIntent().getExtras().getString("urlKey");
if(TextUtils.isEmpty(openUrl)){
myWebView.loadLocalUrl("demo.html");
}else {
myWebView.loadWebUrl(openUrl);
}
} private void initEvents() { } /*=========================================实现webview调用相机、打开文件管理器功能==============================================*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.w(TAG, "{onActivityResult}resultCode="+resultCode);
Log.w(TAG, "{onActivityResult}requestCode="+requestCode);
Log.w(TAG, "{onActivityResult}data="+data);
if (resultCode == Activity.RESULT_OK) {
//webview界面调用打开本地文件管理器选择文件的回调
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE ) {
Uri result = data == null ? null : data.getData();
Log.w(TAG,"{onActivityResult}文件路径地址:" + result.toString()); //如果mUploadMessage或者mUploadCallbackAboveL不为空,代表是触发input[type]类型的标签
if (null != myWebView.getMyWebChromeClient().getmUploadMessage() || null != myWebView.getMyWebChromeClient().getmUploadCallbackAboveL()) {
if (myWebView.getMyWebChromeClient().getmUploadCallbackAboveL() != null) {
onActivityResultAboveL(requestCode, data);//5.0++
} else if (myWebView.getMyWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyWebChromeClient().getmUploadMessage().onReceiveValue(result);//将文件路径返回去,填充到input中
myWebView.getMyWebChromeClient().setmUploadMessage(null);
}
}else{
//此处代码是处理通过js方法触发的情况
Log.w(TAG,"{onActivityResult}文件路径地址(js):" + result.toString());
String filePath = GetPathFromUri4kitkat.getPath(MyWebviewActivity.this, Uri.parse(result.toString())); setUrlPathInput(myWebView,"打开本地相册:" + filePath);//修改网页输入框文本
}
}
//因为拍照指定了路径,所以data值为null
if(requestCode == WebviewGlobals.CAMERA_REQUEST_CODE){
File pictureFile = new File(WebViewJSInterface.mCurrentPhotoPath); Uri uri = Uri.fromFile(pictureFile);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
MyWebviewActivity.this.sendBroadcast(intent); // 这里我们发送广播让MediaScanner 扫描我们制定的文件
// 这样在系统的相册中我们就可以找到我们拍摄的照片了【但是这样一来,就会执行MediaScanner服务中onLoadFinished方法,所以需要注意】 //拍照
// String fileName = FileUtils.getFileName(WebViewJSInterface.mCurrentPhotoPath);
Log.e(TAG,"WebViewJSInterface.mCurrentPhotoPath="+ WebViewJSInterface.mCurrentPhotoPath);
setUrlPathInput(myWebView,"打开相机:" + WebViewJSInterface.mCurrentPhotoPath);//修改网页输入框文本
} //录音
if(requestCode == WebviewGlobals.RECORD_REQUEST_CODE){
Uri result = data == null ? null : data.getData();
Log.w(TAG,"录音文件路径地址:" + result.toString());//录音文件路径地址:content://media/external/audio/media/111 String filePath = GetPathFromUri4kitkat.getPath(MyWebviewActivity.this, Uri.parse(result.toString()));
Log.w(TAG,"录音文件路径地址:" + filePath); setUrlPathInput(myWebView,"打开录音:" + filePath);//修改网页输入框文本
}
}else if(resultCode == RESULT_CANCELED){//resultCode == RESULT_CANCELED 解决不选择文件,直接返回后无法再次点击的问题
if (myWebView.getMyWebChromeClient().getmUploadMessage() != null) {
myWebView.getMyWebChromeClient().getmUploadMessage().onReceiveValue(null);
myWebView.getMyWebChromeClient().setmUploadMessage(null);
}
if (myWebView.getMyWebChromeClient().getmUploadCallbackAboveL() != null) {
myWebView.getMyWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(null);
myWebView.getMyWebChromeClient().setmUploadCallbackAboveL(null);
}
}
} //5.0以上版本,由于api不一样,要单独处理
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, Intent data) { if (myWebView.getMyWebChromeClient().getmUploadCallbackAboveL() == null) {
return;
}
Uri result = null;
if (requestCode == WebviewGlobals.CHOOSE_FILE_REQUEST_CODE) {//打开本地文件管理器选择图片
result = data == null ? null : data.getData();
} else if (requestCode == WebviewGlobals.CAMERA_REQUEST_CODE) {//调用相机拍照
File pictureFile = new File(WebViewJSInterface.mCurrentPhotoPath); Uri uri = Uri.fromFile(pictureFile);
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
intent.setData(uri);
MyWebviewActivity.this.sendBroadcast(intent); // 这里我们发送广播让MediaScanner 扫描我们制定的文件
// 这样在系统的相册中我们就可以找到我们拍摄的照片了【但是这样一来,就会执行MediaScanner服务中onLoadFinished方法,所以需要注意】 result = Uri.fromFile(pictureFile);
}
Log.w(TAG,"{onActivityResultAboveL}文件路径地址:"+result.toString());
myWebView.getMyWebChromeClient().getmUploadCallbackAboveL().onReceiveValue(new Uri[]{result});//将文件路径返回去,填充到input中
myWebView.getMyWebChromeClient().setmUploadCallbackAboveL(null);
return;
} //设置网页上的文件路径输入框文本
private void setUrlPathInput(WebView webView, String urlPath) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
webView.evaluateJavascript("setInputText('"+ urlPath +"')", new ValueCallback<String>() {
@Override
public void onReceiveValue(String value) {
Log.i(TAG, "onReceiveValue value=" + value);
}});
}else{
Toast.makeText(MyWebviewActivity.this,"当前版本号小于19,无法支持evaluateJavascript,需要使用第三方库JSBridge", Toast.LENGTH_SHORT).show();
}
}
}
混淆配置
注意:根据实际项目的路径修改下面表红色的文字
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#} # Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile #====WebView + js====
-keepclassmembers class com.why.project.mywebviewdemo.customwebview.mywebview.MyWebView {
public *;
}
-keepclassmembers class com.why.project.mywebviewdemo.customwebview.mywebview.MyWebChromeClient {
public *;
}
-keepclassmembers class com.why.project.mywebviewdemo.customwebview.mywebview.MyWebViewClient {
public *;
}
# keep 使用 webview 的类
-keepclassmembers class com.why.project.mywebviewdemo.MyWebviewActivity {
public *;
}
-keepattributes *Annotation*
#解决:android sdk api >= 17 时需要加@JavascriptInterface”所出现的问题。
-keepattributes *JavascriptInterface*
参考资料
Android-WebView-解决对选择文件 input type="file"无响应
项目demo下载地址
https://github.com/haiyuKing/MyWebviewDemo
MyWebViewDemo【封装Webview常用配置和选择文件、打开相机、录音、打开本地相册的用法】的更多相关文章
- android系统webview使用input实现选择文件并预览
一般系统的实现方式: 代码实现 <!doctype html> <html> <head> <meta charset="utf-8"&g ...
- log4j常用配置以及日志文件保存位置
log4j.rootLogger=INFO,CONSOLE log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender log4j.appender ...
- Tomcat server.xml常用配置 含有外带文件及默认host
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE server-xml [<!ENTITY ...
- MFC_选择目录对话框_选择文件对话框_指定目录遍历文件
选择目录对话框 void C资源共享吧视频广告清理工具Dlg::OnBnClickedCls() { // 清空编辑框内容 m_Edit.SetWindowTextW(L""); ...
- UltraEdit设置打开的文件类型,怎么打开大文本文件
点击高级,配置,选择文件处理下的临时文件,设置如图即可打开超大文本文件. 补充:视图——显示行号.
- IOS研究院之打开照相机与本地相册选择图片
如下图所示 在本地相册中选择一张图片后,我们将他拷贝至沙盒当中,在客户端中将它的缩略图放在按钮旁边,这个结构其实和新浪微薄中选择图片后的效果一样.最终点击发送将按钮将图片2进制图片上传服务器. 下面我 ...
- IOS研究院之打开照相机与本地相册选择图片(六)
原创文章如需转载请注明:转载自雨松MOMO程序研究院本文链接地址:IOS研究院之打开照相机与本地相册选择图片(六) Hello 大家好 IOS的文章好久都木有更新了,今天更新一篇哈. 这篇文章主要学习 ...
- SpringMVC常用配置(二),最简洁的配置实现文件上传
Spring.SpringMVC持续介绍中,基础配置前面已经介绍了很多,如果小伙伴们还不熟悉可以参考这几篇文章: 1.Spring基础配置 2.Spring常用配置 3.Spring常用配置(二) 4 ...
- zend studio一些常用配置
zend studio 常用 配置 1.zend中添加注释是ctrl+slash,这个slash在哪里?如何来取消注释 slash是斜杠'/'那个键,就是在,.之后的那个. 进行注释是 ctrl+'/ ...
随机推荐
- VS编译代码未通过,常见问题。
问题一:LNK2028 这个问题一般是什么函数在哪里被引用.修改的方法是:先检查是否包含头文件,如果已经包含了头文件,则检查在源文件的"import.cpp"中是否包含了该lib文 ...
- BZOJ_3282_Tree_LCT
BZOJ_3282_Tree_LCT Description 给定N个点以及每个点的权值,要你处理接下来的M个操作. 操作有4种.操作从0到3编号.点从1到N编号. 0:后接两个整数(x,y),代表询 ...
- BZOJ_5015_[Snoi2017]礼物_矩阵乘法
BZOJ_5015_[Snoi2017]礼物_矩阵乘法 Description 热情好客的请森林中的朋友们吃饭,他的朋友被编号为 1-N,每个到来的朋友都会带给他一些礼物:.其中,第 一个朋友会带给他 ...
- struts2 上传与下载
1.Struts.xml <action name="addfileAction" class="Action.addfileAction"> &l ...
- appium 运行报错:...... Attempt to re-install io.appium.settings without first uninstalling解决方案
报错形式: Failed to install D:\AutoTest\appium\Appium\node_modules\appium\build\settings_apk\settings_ap ...
- CSS 圣杯布局 / 双飞翼布局的实现
工作的越久,有些基础知识我们可能就逐渐淡忘了,今天我们来回顾一下css的圣杯布局和双飞翼布局, 这两个名词你可能不熟, 那三栏布局你肯定就非常熟悉了, 就是两边定宽, 中间自适应 的 布局 1 , 圣 ...
- 从壹开始微服务 [ DDD ] 之九 ║从军事故事中,明白领域命令验证(上)
烽烟 哈喽大家周二好呀,咱们又见面了,上周末掐指一算,距离 圣诞节 只有 5 周的时间了(如果你还不知道为啥我要提圣诞节这个时间点,可以看看我的第二系列开篇<之一 ║ D3模式设计初探 与 我的 ...
- SSH免密登陆原理及实现
声明:作者原创,转载注明出处. 作者:帅气陈吃苹果 一.SSH简介 SSH(Secure Shell)是一种通信加密协议,加密算法包括:RSA.DSA等. RSA:非对称加密算法,其安全性基于极其困难 ...
- Caffe源码理解2:SyncedMemory CPU和GPU间的数据同步
目录 写在前面 成员变量的含义及作用 构造与析构 内存同步管理 参考 博客:blog.shinelee.me | 博客园 | CSDN 写在前面 在Caffe源码理解1中介绍了Blob类,其中的数据成 ...
- centos7 修改ip和dns
RHEL7.CentOS7命令添加和修改网卡IP地址和NDS RHEL7.CentOS7默认安装之后是没有启动网络连接!(我们就不按6的方试设置IP了,用命令方试添加IP.网关和DNS) 一.设置 ...