当前位置: 首页 > 编程日记 > 正文

Android APP全面屏适配技术要点

全面屏的概念

为什么先要解释一下全面屏,因为这个词在现在来讲就是一个伪命题。全面屏字面意思就是手机的正面全部都是屏幕,100%的屏占比。但是现在推出所谓“全面屏”手机的厂商没有一个能达到全面的。

那么下面来说一下Android开发领域对全面屏的理解和定义吧。

一般手机的屏幕纵横比为16:9,如1080x1920、1440x2560等,其比值为1.77,在全面屏手机出现之前,Android中默认的最大屏幕纵横比(maximum aspect ratio)为1.86,即能够兼容16:9的屏幕。

一些手机厂商为了追求更大的屏幕空间以及更极致的用户体验,于是提高了屏幕纵横比,17:9、19:10、18:9、18.5:9的手机开始进入市场,这些手机的屏幕纵横比大大超过了1.86,这些手机被称为全面屏手机。

为何需要适配

我们将targetSdkVersion的值改为小于等于23,运行程序,我们会发现屏幕底部出现一个黑条。

如何适配

targetSdkVersion<=23,更大的屏幕纵横比

在Galaxy S8发布之后,Android官方提供了适配方案,即提高App所支持的最大屏幕纵横比,实现很简单,在AndroidManifest.xml中可做如下配置:

<meta-data android:name="android.max_aspect"android:value="ratio_float"/>
复制代码

其中ratio_float为浮点数,官方建议为2.1或更大,因为18.5:9=2.055555555……,如果日后出现纵横比更大的手机,此值将会更大。

<meta-data android:name="android.max_aspect" android:value="2.1" />
复制代码

max_aspect值也可以在Java代码中动态地设置,通过下面的方法即可实现:

public void setMaxAspect() {ApplicationInfo applicationInfo = null;try {applicationInfo = getPackageManager().getApplicationInfo(getPackageName(), PackageManager.GET_META_DATA);} catch (PackageManager.NameNotFoundException e) {e.printStackTrace();}if(applicationInfo == null){throw new IllegalArgumentException(" get application info = null, has no meta data! ");}applicationInfo.metaData.putString("android.max_aspect", "2.1");}
复制代码

如果targetSdkVersion的值的值大于23,那么应该不用设置max_aspect即可。

查看适配之后的截图:

android-developers.googleblog.com/2017/03/upd…

图片资源适配

我们看一下启动页,在16:9屏幕中适配的图片,到了18:9的屏幕中就会被拉伸了。

16:9屏幕中显示18:9屏幕中显示

解决这个问题无非就是两种方法,换图片或者是换布局

换图片

不能依赖单一厂商的解决方案,只能从Android系统属性出发。考虑到目前大部分全面屏手机只是在高度上拉长,且大多为6.0英寸左右,像素密度对比xxhdpi并没有多大区别,那我们可以在项目中增加一组资源drawable-xxhdpi-2160x1080 、drawable-long 这样解决图片的拉伸问题,当然这样的方法肯定是不太好的,会增加app的容量。这里就不演示了。

优化布局

当然最好的方法还是用相对布局采用XML的方式,或者.9图的解决方案。

我总结的就是少量多切,尽量减少尺寸对布局的影响。比如这里,使用正方形的切图,让他居中显示,无论屏幕纵横比如何,都不会拉伸这个图片,拉伸的只是背景而已。

<ImageViewandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:scaleType="fitCenter"android:src="@drawable/bz002"/>
复制代码
适配前适配后

全面屏高度问题适配

首先解释一下window,decorview,rootview这几个概念

Window官方文档:Window

public abstract class Window. Abstract base class for a top-level window look and behavior policy. An instance of this class should be used as the top-level view added to the window manager. It provides standard UI policies such as a background, title area, default key processing, etc.

The only existing implementation of this abstract class is android.view.PhoneWindow, which you should instantiate when needing a Window.

翻译一下:每一个 Activity 都持有一个 Window 对象,但是 Window 是一个抽象类,这里 Android 为 Window 提供了唯一的实现类 PhoneWindow。也就是说 Activity 中的 window 实例就是一个 PhoneWindow 对象。

但是 PhoneWindow 终究是 Window,它并不具备多少 View 相关的能力。不过 PhoneWindow 中持有一个 Android 中非常重要的一个 View 对象 DecorView.

现在的关系就很明确了,每一个 Activity 持有一个 PhoneWindow 的对象,而一个 PhoneWindow 对象持有一个 DecorView 的实例,所以 Activity 中 View 相关的操作其实大都是通过 DecorView 来完成

DecorView就可以理解为手机的内屏,就是那块玻璃,可以发光的屏幕。

这里通过代码,打印出我们页面中的高度的各项数据

int decorviewHeight = decorView.getHeight();
int screenHeight = FullScreenManager.getScreenHeight();
int nativeBarHeight = FullScreenManager.getNativeBarHeight();
int contentViewHeight = rootView.getHeight();
int navigationBarHeight1 = FullScreenManager.getNavigationBarHeight();Log.d("shijiacheng","=======================================");
Log.d("shijiacheng","DecorView height: " + decorviewHeight + " px");
Log.d("shijiacheng","Screen height: " + screenHeight + " px");
Log.d("shijiacheng","NativeBar height: " + nativeBarHeight + " px");
Log.d("shijiacheng","ContentView height: " + contentViewHeight + " px");
Log.d("shijiacheng","NavigationBar height: " + navigationBarHeight + " px");
Log.d("shijiacheng","---------------------------------------");
复制代码

获取decorView的高度

final View decorView = getWindow().getDecorView();
int decorviewHeight = decorView.getHeight();
复制代码

获得屏幕高度

/*** 获得屏幕高度* @return*/
public static int getScreenHeight() {Resources resource = AppContext.getInstance().getResources();DisplayMetrics displayMetrics = resource.getDisplayMetrics();return displayMetrics.heightPixels;
}
复制代码

获取状态栏的高度

/*** 获取状态栏的高度** @return*/
public static int getNativeBarHeight() {Resources resource = AppContext.getInstance().getResources();int result = 0;int resourceId = resource.getIdentifier("status_bar_height", "dimen", "android");if (resourceId > 0) {result = resource.getDimensionPixelSize(resourceId);}return result;
}
复制代码

获取contentView的高度

LinearLayout contentView = findViewById(R.id.root);
int contentViewHeight = contentView.getHeight();
复制代码

获取NavigationBar的高度

public static int getNavigationBarHeight() {Resources resources =  AppContext.getInstance().getResources();int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");int height = resources.getDimensionPixelSize(resourceId);return height;
}
复制代码

为了更加直观的展示各个数据,这里我们使用布局的方式将各个数据展示出来,布局代码比较简单,这里就不展示了。

先展示一下正常的屏幕高度的各项数据

10-08 09:52:03.636 23818-23818/? D/shijiacheng: =========================
10-08 09:52:03.637 23818-23818/? D/shijiacheng: DecorView height: 1280 px
10-08 09:52:03.637 23818-23818/? D/shijiacheng: Screen height: 1280 px
10-08 09:52:03.637 23818-23818/? D/shijiacheng: NativeBar height: 50 px
10-08 09:52:03.637 23818-23818/? D/shijiacheng: ContentView height: 1230 px
10-08 09:52:03.637 23818-23818/? D/shijiacheng: NavigationBar height: 96 px
10-08 09:52:03.637 23818-23818/? D/shijiacheng: -------------------------
复制代码

DecorView = Screen height = NativeBar height + ContentView height

看一下小米mix全面屏的情况

2018-10-08 09:54:15.640 /? D/shijiacheng: =========================
2018-10-08 09:54:15.640 /? D/shijiacheng: DecorView height: 2160 px
2018-10-08 09:54:15.641 /? D/shijiacheng: RootView height: 2094 px
2018-10-08 09:54:15.641 /? D/shijiacheng: Screen height: 2030 px
2018-10-08 09:54:15.641 /? D/shijiacheng: NativeBar height: 66 px
2018-10-08 09:54:15.641 /? D/shijiacheng: ContentView height: 2094 px
2018-10-08 09:54:15.641 /? D/shijiacheng: NavigationBar height: 130 px
2018-10-08 09:54:15.641 /? D/shijiacheng: -------------------------
复制代码

问题出现了,可以发现contentView的高度比screen屏幕的高度还要大,不禁要怀疑,我们的获取屏幕高度的方法在全面屏下计算错误了。

问题1:获取屏幕高度方法计算不准确

我们一直都是使用如下方法进行屏幕高度测量的:

public static int getScreenHeight() {Resources resource = AppContext.getInstance().getResources();DisplayMetrics displayMetrics = resource.getDisplayMetrics();return displayMetrics.heightPixels;
}
复制代码

但是这个方法却是一个十分古老的方法,没有与时俱进,虽然说在普通屏幕上这种方法没有问题,但是在全面屏手机上来说,这种方法就不灵了。

下面我们就来研究一下获取屏幕尺寸的方法的演进。

获取屏幕宽高

获取屏幕的宽高是我们开发中经常遇到的问题,而且相信大家都已经非常熟悉,最常用的为以下两种:

public static int getScreenHeight1(Activity activity) {return activity.getWindowManager().getDefaultDisplay().getHeight();
}
public static int getScreenHeight2(Activity activity) {DisplayMetrics displayMetrics = new DisplayMetrics();activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);return displayMetrics.heightPixels;
}
复制代码

其实以上两种方式是一样的,只不过第二种是把信息封装到 DesplayMetrics中,再从DesplayMetrics得到数据。

在 Android 3.2(Api 13) 之后又提供了如下的一个方法,将数据封装到Point中,然后返回宽度高度信息。

@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
public static int getScreenHeight3(Activity activity) {Point point = new Point();activity.getWindowManager().getDefaultDisplay().getSize(point);return point.y;
}
复制代码

在 Android 4.2(Api17) 之后提供了如下方法,与第三种类似也是将数据封装到Point中,然后返回款高度信息。

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
public static int getScreenHeight4(Activity activity) {Point realSize = new Point();activity.getWindowManager().getDefaultDisplay().getRealSize(realSize);return realSize.y;
}
复制代码

其实getRealSize这个方法在Android Api15的时候就已经加入了,不过是被隐藏了,通过查阅源码我们可以看到。

Android Api15 Display.java源码中getRealSize()方法被标记为@hide

因此,我们可以重写获取高度的方法,适配所有机型,所有系统。

适配所有屏幕的获取屏幕尺寸的方法

public static int[] getScreenSize(Context context) {int[] size = new int[2];WindowManager w = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);Display d = w.getDefaultDisplay();DisplayMetrics metrics = new DisplayMetrics();d.getMetrics(metrics);// since SDK_INT = 1;int widthPixels = metrics.widthPixels;int heightPixels = metrics.heightPixels;// includes window decorations (statusbar bar/menu bar)if (Build.VERSION.SDK_INT >= 14 && Build.VERSION.SDK_INT < 17)try {widthPixels = (Integer) Display.class.getMethod("getRawWidth").invoke(d);heightPixels = (Integer) Display.class.getMethod("getRawHeight").invoke(d);} catch (Exception ignored) {}// includes window decorations (statusbar bar/menu bar)if (Build.VERSION.SDK_INT >= 17)try {Point realSize = new Point();Display.class.getMethod("getRealSize", Point.class).invoke(d, realSize);widthPixels = realSize.x;heightPixels = realSize.y;} catch (Exception ignored) {}size[0] = widthPixels;size[1] = heightPixels;return size;}
复制代码

使用新的获取高度的方法,重新运行程序,运行结果已经正常显示了。

2018-10-08 13:19:32.389 /? D/shijiacheng: ==========================
2018-10-08 13:19:32.390 /? D/shijiacheng: DecorView height: 2160 px
2018-10-08 13:19:32.390 /? D/shijiacheng: Screen height: 2160 px
2018-10-08 13:19:32.390 /? D/shijiacheng: NativeBar height: 66 px
2018-10-08 13:19:32.390 /? D/shijiacheng: ContentView height: 2094 px
2018-10-08 13:19:32.390 /? D/shijiacheng: NavigationBar height: 130 px
2018-10-08 13:19:32.390 /? D/shijiacheng: --------------------------
复制代码

问题2:小米mix切为经典导航键模式下的计算问题

我们在MIUI设置中将全面屏导航样式修改为“经典导航键”样式。

重新运行程序,运行结果如下:

可以发现又出问题了,DecorView = Screen height > NativeBar height + ContentView height

这里不难发现,Screen height将底部虚拟导航栏的高度也算进里面了。

很多情况下,我们都用如下方法获取导航栏的高度:

public static int getNavigationBarHeight() {Resources resources =  AppContext.getInstance().getResources();int resourceId = resources.getIdentifier("navigation_bar_height","dimen", "android");int height = resources.getDimensionPixelSize(resourceId);return height;}
复制代码

这种方法得到的导航栏的高度数值是没问题的,但是在全面屏的手机上,即使隐藏了导航栏,也是可以获取到导航栏的高度的。通过上面的logcat日志可以看到,即使没有导航栏,导航栏的高度的计算也是有值的。

适配小米mix虚拟导航栏

小米mix的机型中,我们可以“force_fsg_nav_bar”来判断小米手机是否开启了全面屏手势。

public static int getHeightOfNavigationBar(Context context) {//如果小米手机开启了全面屏手势隐藏了导航栏则返回 0if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {if (Settings.Global.getInt(context.getContentResolver(), "force_fsg_nav_bar", 0) != 0) {return 0;}}int realHeight = getScreenSize(context)[1];Display d = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();DisplayMetrics displayMetrics = new DisplayMetrics();d.getMetrics(displayMetrics);int displayHeight = displayMetrics.heightPixels;return realHeight - displayHeight;}
复制代码

因此可以通过这个方法来判断是否显示了底部导航栏,并且可以计算导航栏的高度。

int navigationBarHeight = FullScreenManager.getHeightOfNavigationBar(MainActivity.this);
if (navigationBarHeight > 0){container_navigationview.setVisibility(View.VISIBLE);
}else {container_navigationview.setVisibility(View.GONE);
}
复制代码

正常的显示效果如下:

有虚拟导航栏没有虚拟导航栏

没有虚拟导航栏Log

2018-10-08 13:19:32.389 /? D/shijiacheng: ==========================
2018-10-08 13:19:32.390 /? D/shijiacheng: DecorView height: 2160 px
2018-10-08 13:19:32.390 /? D/shijiacheng: Screen height: 2160 px
2018-10-08 13:19:32.390 /? D/shijiacheng: NativeBar height: 66 px
2018-10-08 13:19:32.390 /? D/shijiacheng: ContentView height: 2094 px
2018-10-08 13:19:32.390 /? D/shijiacheng: NavigationBar height: 0 px
2018-10-08 13:19:32.390 /? D/shijiacheng: --------------------------复制代码

有虚拟导航栏Log

2018-10-08 13:38:03.229 /? D/shijiacheng: ==========================
2018-10-08 13:38:03.230 /? D/shijiacheng: DecorView height: 2160 px
2018-10-08 13:38:03.230 /? D/shijiacheng: Screen height: 2160 px
2018-10-08 13:38:03.230 /? D/shijiacheng: NativeBar height: 66 px
2018-10-08 13:38:03.230 /? D/shijiacheng: ContentView height: 1964 px
2018-10-08 13:38:03.230 /? D/shijiacheng: NavigationBar height: 130 px
2018-10-08 13:38:03.230 /? D/shijiacheng: --------------------------
复制代码

转载于:https://juejin.im/post/5bc59db16fb9a05ce95c89fe

相关文章:

PHP数据库连接池SQL Relay安装使用

SQL Relay按照其官网http://sqlrelay.sourceforge.net/index.html上所说是&#xff1a;A powerful database connection management solution. 翻译为中文也就是说SQL Relay是一个开源的数据库池连接代理服务器。目前SQL Relay支持的数据库很多&#xff1a; SQL Relay supports…

oracle实例由,Oracle数据库和实例

Oracle数据库服务器由一个数据库和至少一个数据库实例组成。 数据库是一组存储数据的文件&#xff0c;而数据库实例是一组管理数据库文件的内存结构。 另外&#xff0c;数据库由后台进程组成。一个数据库和一个实例是紧密相连的&#xff0c;因此术语 - Oracle数据库 通常用来指…

说一说activity

activity与service&#xff0c;provider&#xff0c;receiver并称为 android的四大对象。 而activity&#xff0c;是展现界面的必不可少的组件。我这里有几个问题要问了&#xff0c;他是如何加载&#xff0c;他是如何进行npc的。具体是怎么实现的了。 说道activity的加载&#…

zookeeper脑裂

出现&#xff1a; 在搭建hadoop的HA集群环境后&#xff0c;由于两个namenode的状态不一&#xff0c;当active的namenode由于网络等原因出现假死状态&#xff0c;standby接收不到active的心跳&#xff0c;因此判断active的namenode宕机&#xff0c;但实际上active并没有死亡。此…

C语言编写的PHP框架--yaf入门编程

首先--添加dll&#xff0c;修改php.ini--不同的版本&#xff0c;不同的需求 其次&#xff0c;根据教程http://www.laruence.com/manual/tutorial.firstpage.html#tutorial.directory手动搭建好目录结构 入口文件index.php位置稍作修改--个人习惯 入口文件内容 <?php header…

调试JDK源码-ConcurrentHashMap实现原理

调试JDK源码-一步一步看HashMap怎么Hash和扩容 调试JDK源码-ConcurrentHashMap实现原理 调试JDK源码-HashSet实现原理 调试JDK源码-调试JDK源码-Hashtable实现原理以及线程安全的原因ConcurrentHashMap线程安全的总结是我从源码分析出来的&#xff1a; ConcurrentHashMap所谓线…

oracle某个表丢失,丢失一个控制文件并恢复数据库

只丢失或损坏一个控制文件的情况下来恢复数据库&#xff0c;相对来说简单一点。一般来说&#xff0c;控制文件都需要形成一个多路径冗余策略&#xff0c;来提高数据库的安全性。这样的话只需将完好的控制文件复制一个副本放到丢失或者损坏了的控制文件所在路径的目录下&#xf…

MySQL:一个死锁分析 (未分析出来的死锁)

最近一个朋友给了我一个死锁 没分析出来搞了好几天&#xff0c;但是把以前出现的一个死锁理了一下流程。这里大概记录一下&#xff0c;并且给出朋友的案例。 RC 隔离级别很少出GAP我已经知道的 继承和分裂会出LOCK_GAP这是代码写死的purge线程可能触发页的分裂融合可能触发内部…

经历一次真实的XSS跨站攻击以及应付之策

这是一个线上真实的事情&#xff0c;黑客已经攻破网站&#xff0c;并主动给我们上报了问题的根源以及解决方案还是不错的。1.前端网站某处存在用户评论输入&#xff0c;黑客再此输出跨站脚本&#xff0c;下面的是从数据库查出来的2.后台管理人员如果浏览到这条数据就会触发这个…

在linux中 要删除abc目录,在 Linux 中,要删除 abc 目录及其全部内容的命令为:

【单选题】星子本地人说( )【判断题】音乐的音响,虽然不能直接传达抽象概念,但是却可以通过同构联觉的去描摹围绕着抽象概念的氛围。( )【判断题】专项耐力负荷量度是通过对糖酵解无氧代谢供能能力与非乳酸供能无氧耐力能力的监控实现的。【单选题】电动轮廓仪是根据( )原理制成…

ECHO.js 纯javascript轻量级延迟加载

演示 <!DOCTYPE html> <html lang"zh-CN"> <head> <meta charset"utf-8"> <title>简单的JavaScript图像延迟加载库Echo.js</title> <style> .demo img { width: 736px; height: 490px; background: url(images/…

SQL中的case when then else end用法

2019独角兽企业重金招聘Python工程师标准>>> Case具有两种格式。简单Case函数和Case搜索函数。 --简单Case函数 CASE sexWHEN 1 THEN 男WHEN 2 THEN 女 ELSE 其他 END --Case搜索函数 CASE WHEN sex 1 THEN 男WHEN sex 2 THEN 女 ELSE 其他 END这两种方式&#xf…

linux run文件夹,Linux下运行run文件

比如realplay.run安装方法如下chmod xrealplay.run./realplay.run然后他就会执行安装了&#xff0c;在过程中可能会要求你输入yes或no安装完后就可以用了,chmod实际上是加权限命令。&#xff0b;x表示可以执行chmod[-cfvR][--help][--version]modefile...说明:Linux/Unix的档案…

POJ2796 Feel Good(单调栈)

题意&#xff1a; 给出一列数据&#xff0c;要求一个区间内最小值与区间内数据总和乘积最大值 要点&#xff1a; 还是单调栈&#xff0c;这次我自己写的&#xff0c;先做了几题比较简单的果然还是有效果的&#xff0c;这题也是一样&#xff0c;按点遍历&#xff0c;网上大神做的…

Solr占用CPU持续过高原因查询

线上java进程占用CPU忽高忽低&#xff0c;就是说一下子40%左右&#xff0c;一下子减下去。这台服务器只有Solr&#xff0c;所以估计是Solr在GC。 # jstat -gcutil 2072 2sJVM名词解释参考java内存泄漏的定位与分析 一些术语的中文解释&#xff1a; S0C&#xff1a;年轻…

通过一个案例理解 JWT

原文出自&#xff1a;https://www.pandashen.com JWT 简述 JWT&#xff08;json web token&#xff09;是为了在网络应用环境之间传递声明而基于 json 的开放标准&#xff0c;JWT 的声明一般被采用在身份提供者和服务器提供者间传递被认证的身份信息&#xff0c;以便于从资源服…

gitlab报错 fatal: index-pack failed error: RPC failed; result=18, HTTP code = 200解决方案

gitlab报错 "fatal: index-pack failed error: RPC failed; result18, HTTP code 200"&#xff0c;如下图这个问题网上有些人给出这样的解决方法是不行的&#xff0c; 所谓&#xff1a;git config --globalhttp.postBuffer 24288000 git config --list 最有代表的是…

(10)Spring Boot修改端口号【从零开始学Spring Boot】

Spring boot 默认端口是8080&#xff0c;如果想要进行更改的话&#xff0c;只需要修改applicatoin.properties文件&#xff0c;在配置文件中加入&#xff1a; server.port9090 常用配置&#xff1a; ######################################################## ###EMBEDDED SER…

linux查看文件安全权限,Linux系统下如何查看及修改文件读写权限

查看文件权限的语句&#xff1a;在终端输入:ls -l xxx.xxx (xxx.xxx是文件名)那么就会出现相类似的信息&#xff0c;主要都是这些&#xff1a;-rw-rw-r--一共有10位数其中&#xff1a; 最前面那个 - 代表的是类型中间那三个 rw- 代表的是所有者(user)然后那三个 rw- 代表的是组…

【网摘】检测 iframe 是否加载完成

var iframeSet document.getElementById("iframeSet"); //需要检测的 iframe if(iframeSet.attachEvent) {iframeSet.attachEvent("onload", function() {$("#loading").hide();}); } else {iframeSet.onload function() {$("#loading&q…

Java json转Map,转bean,转Listbean

引用jackson /** * json转Map&#xff0c;转bean&#xff0c;转List<bean> by http://blog.csdn.net/21aspnet/ * 需要jackjson jar包 */ public class JsonUtil {/*** Object转Json*/public static String ObjectToJson(Object value) {try {ObjectMapper mapper new…

JVM实用参数 GC日志

为什么80%的码农都做不了架构师&#xff1f;>>> 原文章地址&#xff1a;http://blog.panaihua.com/archives/151 GC日志是一个很重要的工具&#xff0c;它准确记录了每一次的GC的执行时间和执行结果&#xff0c;通过分析GC日志可以优化堆设置和GC设置&#xff0c;或…

linux 搜索so文件,Linux下查找和安装依赖的.so文件

以解决Webex在Linux下运行问题为例说明查找和安装依赖的.so文件方法&#xff1a;查找依赖的.so文件$ ldd $HOME/.webex/1324/*.so | grep not foundlibgtk-x11-2.0.so.0 > not foundlibgdk-x11-2.0.so.0 > not foundlibXmu.so.6 > not foundlibXtst.so.6 > not fou…

CentOS7.4下 VNC Server的搭建和客户端的连接配置

CentOS7.4下 VNC Server的搭建和客户端的连接配置 服务器版本&#xff1a;CentOS Linux release 7.4.1708 (Core) yum方式安装VNC server yum install tigervnc-server 启动vnc 服务初次启动服务时&#xff0c;按提示设置VNC Service密码&#xff1b;服务成功启动后会在 /root/…

Java生成html为pdf

使用这个&#xff1a; http://wkhtmltopdf.org/ 下载&#xff1a;http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz 解压到/usr目录 调用这个bin /usr/wkhtmltox/bin/wkhtmltopdf需要注意如果中文不显示&#xff0c;显示为框框&…

GCD之信号量机制二

在前面GCD之信号量机制一中介绍了通过信号量设置并行最大线程数,依此信号量还可以防止多线程访问公有变量时数据有误&#xff0c;下面的代码能说明。 1.下面是不采用信号量修改公有变量的值 dispatch_group_t groupdispatch_group_create();// dispatch_semaphore_t semapho…

qtdll在linux系统运行,在QT下编写带DLL的程序

注:我的工作目录是: D:\My Documents\MyProject一.运行QtCreator1.新建工程/选择C Library 这里设计被调用的DLL下一步:然后输入类名:它会生成相应的(.h .cpp)下面一路NEXT就好了.二.1.新建一个空工程名为(MyTest) 这里设计调用DLL的主模块输入工程名后完成2.在工程文件内添…

Python 安装selenium

一、报错信息 No module named selenium 二、系统环境 操作系统&#xff1a;Win10 64位 Python版本&#xff1a;Python 3.7.0 三、安装参考 1、使用pip安装selenium pip install selenium 安装不成功 2、网上下载selenium, 地址&#xff1a;http://pypi.python.org/pypi/seleni…

跨域攻击XSS防御

Java的view层可以使用EL和JSTL 后端的ModelAndView增加 mv.addObject("xss", "<script>alert(\"test\")</script>"); View页面 ${xss} <c:out value"${xss}" escapeXml"true"></c:out> <c:out v…

[Core Java® for the Impatient]重载Java2

2019独角兽企业重金招聘Python工程师标准>>> Chapter 2. Object-Oriented Programming Set&#xff08;Mutator Methods&#xff09;方法改变对象的状态&#xff0c;Get&#xff08;accessor methods&#xff09;方法则不&#xff1b;Java中变量不持有对象&#xff…