JAVA简单调用C/C++语言(JNI学习三)

JNI的目的是可以使用C/C++完成部分逻辑,一方面 代码复用,避免重复劳动。另外一方面有些东西还是C语言处理起来比较方便,比如和底层驱动程序打交道等等。JAVA调用C/C++方法,就要把参数传递给C/C++代码,或者C/C++代码可以获取到JVM的内存数据, JAVA和C之间可以数据交互。 1、数据类型 JAVA和C/C++之间传递数据,就要有相互对应的数据类型。 首先是基本类型,每种语言都会有的,所以直接用typedef 定义完成: typedef unsigned char jboolean; typedef unsigned short jchar; typedef short jshort; typedef float jfloat; typedef double jdouble; typedef long jint; typedef __int64 jlong; typedef signed char jbyte; 在java里除此之外的对象都是继承于java.lang.Object。所以JNI里也定义了一个jobject的结构体。 这样java所有的对象都可以用jobject传递。 参考官方文档:http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/types.html 为了方便使用,JNI还定义了一些特殊的常用对象,比如类对象jclass, 异常对象jthrowable,数组对象jarray等等。 不过这些对象都是空的,也就是你不通过调用它们的方法的方式去调用java里的方法。 如果想调用它们的方法,或者获取它们的一些属性。你需要把它们当作参数,传递给JNIENV的对应api。 比如你想获取一个数组的长度,你需要调用JNIENV的GetArrayLength方法: jsize GetArrayLength(jarray array) 2、JNIEnv指针。 在JNI自动生成的代码里,函数参数,必须有一个JNIEnv *指针,这个就是用来调用JVM的方法的。 关于JNIENV的定义可以查看jni.h。你会发现它是一个struct。 如果你是C++语言实现,那么它这个struct就相当于一个class,大家知道在C++里,struct和class是没有多大区别的,唯一的区别就默认访问权限的问题。这都不是很重要。重要的是struct里可以定义方法和属性。JNIENV里提供了一系列的api,供使用者调用。 如果是C语言实现的呢,会发现JNIENV也是一个struct,但是C语言是一种面向过程的语言,他没有对象的概念,它的struct里是不能定义方法的。但是有一个叫“函数指针”的东西,可以让C语言实现一种面向对象的感觉,JNI就是这样做到的,它在struct里定义了一系列的函数指针,用于访问JVM。 这样无论C,还是C++。都可以使用JNIENV的api访问jvm。 jni.h里是通过__cplusplus控制的 都有那些方法,可以查看oracle官方文档: http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/functions.html 3、共享内存。 Java除了提供参数传递的方式,和C/C++交互数据之外,还有一种共享数据的方式就是共享内存。Java里可以直接申请JVM的堆外的内存,和C语言共用。 那就是java里的一个特殊类:ByteBuffer,它的allocateDirect方法,可以直接在JVM之外的内存中开辟空间。 这种开辟内存的方式要比直接申请JVM堆内内存耗时多,所以这种方式一般用于使用比较频繁,可以重复使用的场景。 比如java和c之间有大量数据要交互,那么就可以使用ByteBuffer申请一块一定大小内存作为缓存。使用ByteBuffer可以大量减少JVM和C语言之间的内存copy产生的开销 下一篇学习ByteBuffer的实际使用。

2016年5月29日 · 1 分钟

JAVA简单调用C/C++语言(JNI学习二)

一个maven的典型目录结构: src/main/java src/main/resources src/test/java src/test/resources 根据含义src代码源码库, main代表主代码 test表示测试代码。java表示java部分。 那么如果再加上C语言部分,那目录可以这样安排 src/main/java src/main/c — c语言部分 src/test/java src/test/c — c语言测试代码 src/test/resources include —引用的其它c语言头文件 lib —引用的其它动态链接库 使用maven编译c语言,还是要用插件: org.fusesource.hawtjni maven-hawtjni-plugin 1.13 这个插件会帮你生成一个c语言工程(主要是configure文件和makefile文件),并帮你编译成so文件,并放到jar包的指定目录下,非常好用。 示例配置如下: org.fusesource.hawtjni maven-hawtjni-plugin 1.10 build-linux64 ${project.artifactId} ${project.build.directory}/linux64 ${basedir}/src/main/c ${basedir}/target/classes/ --with-arch=x86_64 CFLAGS=-I${basedir}/include LDFLAGS=-L${basedir}/lib LIBS=-lXXXX linux64 true true generate build compile configureArgs 里包含了makefile需要的参数,其中XXXX表示你依赖的库名,也可以加上更多你需要的其它的参数。 假设你的工程名叫hello。执行mvn clean package 之后 maven会帮你在你的target/native-build目录下生成一个c语言工程,并执行相应操作系统的编译。 就比如上面的linux64位系统,最终会生成一个libhello.so文件到你的jar包的META-INF/native/linux64/ 目录下 你可以用各种手段使用System.loadLibrary加载它。 下一篇学习java和c语言之间的参数传递和方法调用。

2016年5月22日 · 1 分钟

JAVA简单调用C/C++语言(JNI学习一)

程序都是从hello world开始的,写一个简单的demo,java里调用c语言的方法输出一句hello world。 第一:首先实现一个java类:com.zhaoyanblog.Demo package com.zhaoyanblog; public class Demo { static{ System.loadLibrary("demo"); } public static void main(String[] args) { Demo demo = new Demo(); demo.printHelloWord(); } public native void printHelloWord(); } 声明为native的方法,jvm会主动从加载的library中对应寻找。 System.loadLibrary就是用于加载c语言编译的库文件。 在linux下面lib库文件的命名默认是: lib+{name}+.so java会到环境变量java.library.path对应的目录下寻找并加载。 第二: 编写c/c++语言部分 使用javah得到c/c++对应的头文件, 在com目录的父目录下执行 javah -jni javah -jni com.zhaoyanblog.Demo 会产生一个头文件 com_zhaoyanblog_Demo.h /* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class com_zhaoyanblog_Demo */ #ifndef _Included_com_zhaoyanblog_Demo #define _Included_com_zhaoyanblog_Demo #ifdef __cplusplus extern "C" { #endif /* * Class: com_zhaoyanblog_Demo * Method: printHelloWord * Signature: ()V */ JNIEXPORT void JNICALL Java_com_zhaoyanblog_Demo_printHelloWord (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif 根据头文件完成源文件com_zhaoyanblog_Demo.cc ...

2016年5月14日 · 1 分钟

[翻译]有关cassandra的存储引擎

Cassandra使用一个类似于日志结构的结合树(Log-Structured Merge Tree)的存储结构,不像传统关系数据库那样使用B-Tree。 Cassandra会避免在写之前去读。 “写前读”(Read-before-write), 特别是在一个大的分布式系统里,会对读性能产生影响,还会带来其它问题,比如,两个客户端同时去读,其中一个去更新该行的A列,另外一个去更新该行的B列,就可能把对A列的更新覆盖掉。“写前读”,也会破坏cache,增加IO。 为了避免“写前读”的情况,cassandra的存储引擎会对即将要进行的插入、更新进行整理,只会按顺序,以追加的模式仅写入这一行更新的部分。 。 一个日志模式的存储引擎,为了避免数据相互覆盖,使用顺序IO去更新数据写入普通硬盘HDD或者固态硬盘SSD是必须的。 在HDD中,随机写比顺序写会导致大量的寻址操作,这个寻址操作的危害是相当大的。使用顺序IO,从而避免更多写入被放大和磁盘故障,Cassandra特别适合廉价的、大众消费的SSD。

2016年5月2日 · 1 分钟

[翻译]Cassandra的写过程

Cassandra的写操作包含几个过程。从开始实时写日志到最后进行压缩。 1、把数据写入commit log 2、数据写入内存表memtable 3、从memtable中刷新 4、存储到磁盘中的sstables里 5、压缩 写日志和memtable存储 当有一个写入发生,cassandra会把数据存到内存里叫memtable的数据结构里,也会写到磁盘的commitlog里,提供持久化存储。commitlog接受每个请求,并且持久化保存,甚至是断电。memtable是一种回写cache,cassandra通过key可以在memtbale里查询数据。memtable的大小是有限制的,当到达一个限制就会被刷新。 从memtable刷新数据。 当memtable的内存超过了配置的阈值,memtable里的数据包括索引,就会进入一个刷新到磁盘的队列里。你可以通过修改cassandra.yaml里的 memtable_heap_space_in_mb配置项来控制这个队列的大小。当要刷新的数据超过了队列大小,cassandra就会阻止写入直到下一个刷新成功。你可以使用nodetool flush 手动触发一个刷新,通常在重启节点之前,建议刷新一次memtable,这样可以减少重放commitlog的时间。为了刷新数据cassandra会吧memetables根据token排序,然后顺序写到磁盘上。 磁盘上数据存储到sstables中 对于在commitlog里的数据,当在memtable里的对应的数据被刷新到一个sstable中之后会被清除。 Memtables和SStables都是分表存储的,SStables是不可以改变的,当从memtbale中刷新到磁盘上后就不会再写入。因此一个分区可以通常会保存到多个sstable文件中。对于每个sstable,cassandra会创建如下结构化数据: 1、分区key索引:一个分区key的列表和对应的在data文件中的起始位置。 2、分区key汇总(在内存里):一个分区key索引的抽样 3、布隆过滤器 压缩 周期性的压缩是cassandra作为一个健康数据库所必须的,因为cassandra不会把数据插入或者更新到具体的位置。当插入或者更新发生了,并不会去覆盖原来的数据,而是重新写入一个新的时间戳版本的数据到另外一个sstable中。cassandra管理在磁盘上不断累积的sstable,就是使用压缩。 cassandra也不会去实际删除数据,因为sstable是不可以修改的。而是用墓碑的方式标记数据被删除了,墓碑存在一个可配置的周期,是表的一个参数 gc_grace_seconds。 在压缩的过程中,会有一个磁盘使用空间以及IO的临时飙升,因为老的和新的sstable会并存,这个图描述了压缩的过程: 压缩会根据分区key合并多个sstable中的数据,选择具有最新时间戳的进行存储。Cassandra可以高性能的合并数据,而不会产生随机IO,因为在sstable里的row都是根据分区key排序存储的。在删除了墓碑和要删除的数据,列和行数据后,压缩的过程会把这些sstable压缩成一个文件。老的sstable文件会在堆积到该文件上的查询请求结束后尽快的删除。这样老的sstable占用的磁盘空间又可以重复使用了。 cassandra2.1改进了压缩后的读性能,通过一种增量式的替换压缩过的sstables。而不是等到整个压缩完才去删除老的sstable。cassandra可以直接从新的sstable中读取,甚至在它完成写入之前。 当数据写到新的sstable,读请求就会访问新的sstable,在老的sstable中相应的数据不会再被访问,并且从系统的page cache中剔除掉。因此当缓存新的sstable的增量过程开始的时候,读取就不会从老的读,相应的cache也会消失。因此可以预见cassandra提供了一种高的性能甚至是在高负载下。 原文地址:https://docs.datastax.com/en/cassandra/2.1/cassandra/dml/dml_write_path_c.html

2016年4月24日 · 1 分钟

[新闻]华为发布P9 & 荣耀4月13日预发布新品

华为于4月6日在伦敦发布华为新旗舰华为P9和P9 Plus: 1、手机摄像的再一次次突破 P9采用徕卡SUMMARIT系列镜头,无论是镜头设计,还是筛选标准均出自徕卡之手,再加上华为的双摄像头成像技术,排除的照片边缘锋利无畸变,细节清晰且丰富,满足徕卡对镜头及图像质量的严苛要求,而且相机自动选择激光对焦,反差对焦等多种对焦方式,表现非同寻常。 2、P系列首款指纹识别机型。 P9引入后背指纹识别,在解锁场景下比普通指纹识别,识别率提升30%。 新加入3D指纹信息提取技术,能有效防止2D假指纹进行支付操作,更安全。 3、外观简约,芯片再升级,麒麟955芯片。 琥珀金、陶瓷白多种精工细琢的外观设计,厚度只有6.95mm,电池有3000MA 麒麟955新片,提升了CPU主频到2.5GHZ,让游戏、视频更流畅。P9自研新的文件系统,可以有效改善手机越来越慢的问题。 华为荣耀 官方微博@荣耀手机,在P9发布第二天,也发布宣传海报: 海报内容是“怕手机慢如蜗牛”,预告4月13日有一个不再怕的开始: 很可能4月13日,荣耀要发布2016年以来首款新品,从手机发布周期看,这款手机很可能是荣耀5C。4月13日,让我们拭目以待。

2016年4月9日 · 1 分钟

Cassandra解决单个磁盘损坏的情况

Cassandra一个节点的磁盘坏了,分两种情况,一种是节点还可以正常启动。另外一种是节点无法启动。 第一种情况:节点还可以正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、启动cassandra,如果启动的过程中报错,说找不到keyspace之类的,那你应该使用第二种情况的解决方案。 3、使用nodetool repair修复该节点丢失的数据。 第二种情况:节点无法正常启动 1、把坏的盘换掉,如果你没有新的盘去更换,你可以在cassandra.yaml里直接把坏的盘注释掉 2、在正常的节点上执行: $ nodetool ring | grep ip_address_of_node | awk ’ {print $NF “,”}’ | xargs 从而获取到坏掉节点的tokens,把它们(用逗号分割)配置到cassandra.yaml的initial_token 选项中。 3、在cassandra.yaml设置配置项: auto_bootstrap: false 这一步官方文档漏掉了,参考 https://issues.apache.org/jira/browse/CASSANDRA-11365 4、删除你所有数据盘下面的system目录。 rm -fr /mnt1/cassandra/data/system rm -fr /mnt2/cassandra/data/system 。。。。 5、启动cassandra,如果启动的过程中报错,说schema不存在之类的属于正常情况,system库会自动重建,只要节点可以正常加入集群就算正常。 6、同样使用nodetool repair修复该节点丢失的数据。

2016年3月26日 · 1 分钟

[新闻]梅西成为华为全球品牌形象代言人

无论从各大媒体新闻,还是从华为各层主管的微博里,都可以准确得到这个消息:来自巴萨的足球明星梅西正式成为华为全球品牌影响代言人。 一直以来,华为提高赞助和代言人还是比较慎重的,华为喜欢赞助体育运动,特别是足球。这是华为在认真经营自己的品牌形象,宣传自己的企业文化。一个公司的气质是长久积淀下来的。 华为一直秉承的企业文化是“以用户为中心,以奋斗者为本,长期坚持艰苦奋斗" 8 梅西是一个奋斗者的形象,所以华为选择了梅西,同时梅西在全世界的影响力,对于华为全球品牌宣传是有益的。

2016年3月20日 · 1 分钟

slf4j(简单日志门面)日志框架介绍(二)

日志门面的出现,目的就是在任何日志实现框架之间随意切换,而不需要改动一行代码。 所以如果你的代码中使用了slf4j-api打印日志。你可以通过更换适配包实现,更好不同的日志框架。 但是如果你的业务代码,或者依赖的sdk,使用了其它日志框架打印日志,例如commons-logging. 甚至直接使用了log4j等打印日志。怎么样切换到统一的日志框架呢? Slf4j还提供了另外一系列的包:叫做桥接(Bridging)包,原理就是替换log4j,jul,jcl等日志框架的包,把日志导向slf4j。桥接包的原理,就是重写对应日志框架的api和实现,内部使用slf4j打印日志。 下图是slf4j官方提供的: 桥接到slf4j 1、jcl/log4j->slf4j 把对应的commons-logging、log4j包删除。 增加jcl-over-slf4j-1.7.xx.jar和log4j-over-slf4j-1.7.xx.jar包 2、jul->slf4j 因为jdk的logging是无法删除的,所以jul-to-slf4j-1.7.xx.jar是无法通过替换api的方式,实现对jul的替换。它是提供了一个jdk的扩展org.slf4j.bridge.SLF4JBridgeHandler 需要配置到jdk的logger.properties中 handlers = org.slf4j.bridge.SLF4JBridgeHandler 3、log4j2->slf4j Log4j2到slf4j的桥接包,是log4j2官方提供的。叫做: log4j-to-slf4j-2.x.jar 但是log4j2也提供了占位符的形式的日志,所以日志消息也可能会在传递给slf4j之前要先对日志进行格式化,官方文档说这个过程可能存在一定的性能损失。所以不建议这么做。 日志框架切换举例 这样,通过slf4j,我们可以实现任何日志框架之间的切换,而不需要修改代码。举例说明: 1、之前是commons-logging+log4j 打日志,现在想用slf4j+logback打日志。 删除 commons-logging-1.x.jar log4j-1.2.xx.jar 增加 jcl-over-slf4j-1.7.xx.jar slf4j-api-1.7.xx.jar logback-classic-1.1.x.jar logback-core-1.1.x.jar 即可完成切换 2、之前直接用log4j打日志,现在想用log4j2打日志 删除 log4j-1.2.xx.jar 增加 log4j-over-slf4j-1.7.xx.jar slf4j-api-1.7.xx.jar log4j2-api-2.x.jar log4j2-core-2.x.jar 即可完成切换

2016年3月5日 · 1 分钟

JAVA日志框架分类简介

JAVA的日志框架分两类: 一类是日志门面,它定义了一组日志的接口规范,并未提供底层实现。例如slf4j 另外一类是日志实现,它实现日志具体实现,包括日志级别控制,日志格式,打印日志到文件,到屏幕,甚至到数据库等日志的种种具体功能,例如log4j。 日志门面是不能单独使用的,它必须和一种具体的日志实现框架相结合使用。日志门面和日志实现的分离,可以让业务使用不同的日志实现框架之间切换,而不需要改动任何代码,只要掌握日志门面的接口文档,也不需要新的日志实现的接口学习代价。 也就是编码模式里所谓的“门面模式”。 日志实现框架可以直接用于打印日志,但是一般不会这样做,因为这样回带来一定的麻烦,例如一个SDK包使用log4j打日志,而一个业务引用了这个SDK,但是业务开发者喜欢使用logback打日志。那么就会出现一个业务使用两款甚至多款日志框架并存,而且要维护多个日志配置文件的局面。 所以,我们都是用日志门面打日志。

2016年2月21日 · 1 分钟

slf4j(简单日志门面)日志框架介绍(一)

Slf4j的原理 值得一提的是slf4j的作者,同时也是log4j和logback的开发者,名叫Ceki Gülcü。 slf4j和commons-logging的作用和基本原理是一样的,在slf4j-api中提供了两个接口: org.slf4j.Logger org.slf4j.ILoggerFactory 但是相比commons-logging, slf4j有两个不同之处,也可以说为优点: 第一:slf4j对ILoggerFactory的寻找上,是静态绑定,它必须存在一个类org.slf4j.impl.StaticLoggerBinder,指明使用的哪个日志框架,loggerfactory是那个。 为此,slf4j对几乎所有的日志框架都提供一个适配(adaptation)包,里面包含loggerfactory和logger的实现。以及一个org.slf4j.impl.StaticLoggerBinder类 使用slf4j和其它日志框架,只要引入slf4j-api包,以及对应的适配包即可。 下图是官方提供的一张图,slf4j绑定不同的日志实现: 第二:slf4j提供了一种占位符的接口形式,从而避免对字符串不必要的拼接。 举例: 如果用commons-logging打日志: log.info(“my name is” + name +”,my age is ”+ age); 如果log的日志级别配置的是ERROR,那么这句日志就不会输出,但是代码中的字符串拼接操作还是会执行。 为此,我们必须这样写: If ( log. isInfoEnabled() ) { log.info(“my name is” + name +”,my age is ”+ age); } 如果你使用slf4j, 你就可以优雅的这样写: log.info(“my name is {}, my age is {}.”, name, age);

2016年2月21日 · 1 分钟

java通用日志框架commons-logging介绍

commons-logging简称jcl。是apache较早提供的日志通用框架,它规定了一系列的接口, 它可以自动寻找到你的工程里使用的日志框架进行打日志。前提是你要为它提供: org.apache.commons.logging.Log org.apache.commons.logging.LogFactory 两个接口或者是抽象类的实现。 其它日志框架,如果能让commons-logging识别,只能去实现它的接口 org.apache.commons.logging.Log org.apache.commons.logging.LogFactory 并且告诉commons-logging你的LogFactory。 让commons-logging加载你的LogFactory,有两种途径: 第一:设置环境变量 -Dorg.apache.commons.logging.LogFactory=com.huawei.myLogFactory 第二:把com.huawei.myLogFactory写入META-INF/services/org.apache.commons.logging.LogFactory文件中 第三:在classpath下创建一个commons-logging.properties文件写入: org.apache.commons.logging.LogFactory=com.huawei.myLogFactory 其它日志框架,一般使用第二种方式支持commons-logging。Commons-logging对logFactory的寻找过程,可以查阅org.apache.commons.logging.LogFactory类源码. 因为commons-logging是在运行时,通过类查找的方式找到logFactory的实现,并且通过反射的形式获得其实例。所以commons-logging和日志实现框架的绑定是一种动态绑定。 1、commons-logging->log4j/jul 其中:jdk log 和log4j的log和logfactory。commons-logging自己已经提供: Logfactory: org.apache.commons.logging.impl.LogFactoryImpl log: org.apache.commons.logging.impl.Log4JLogger org.apache.commons.logging.impl.Jdk14Logger 所以如果你打算用log4j打日志,只要把log4j的包引入,commons-logging就可以使用log4j打日志了。 如果你不提供log4j的包,commons-logging就默认使用JDK的java.util.logging打日志。 2、commons-logging->log4j2 log4j2 官方提供了commons-logging的Log和LogFactory的实现包。 如果使用commons-logging+log4j2打日志,需要额外引入 log4j-jcl-2.x.jar 包 org.apache.logging.log4j log4j-jcl 2.x 3、commons-logging->logback 很遗憾logback没有提供对commons-logging的支持,因为当logback出现的时候,已经有一个更好的日志门面框架出现了,就是slf4j。

2016年2月20日 · 1 分钟

华为可能要出Matebook手写平板

2月15日 余承东发布一篇微博,内容如下: #今年我要换新的# 北京时间2月21日21点,巴塞罗那MWC2016,为大家带来新品![酷] @华为消费者BG 并附有一张照片: 让人猜测中中,最靠谱的就是盛传已久的华为笔记本,因为很早之前华为就注册了MateBook。根据其注册的信息表示,“MateBook”将被用于便携式计算机用套、计算机键盘、计算机程序(可下载软件)、平板电脑、计算机硬件、数据处理设备、智能手机、调制解调器等等产品,从商标名称及用途来看,“MateBook”无疑就是为其PC产品准备的。 从这幅照片上看,这应该不是一款传统意义上的笔记本。估计是一款平板电脑两用,并且带手写笔的产品。 参考苹果,应该是和ipad对齐的一款产品。因为苹果在去年九月发布了ipad pro,同时为其配备了专业的Apple Pencil。那么MateBook应该是一款类似的产品。据悉华为将和PC端最牛逼的Intel合作,搭载Intel处理器。可能会支持Windows和Andriod双系统。 总之这是一款让人期待的产品。此外已知MWC2015,华为发布了荣耀2X,这一次还有可能要发布荣耀3X.让我们静静的等待华为带给我们的科技惊喜。

2016年2月16日 · 1 分钟

如何安全升级wordpress

第一步:备份 如果真到了升级后一团糟的底部,有了备份的数据,还可以重头再来。 备份分两部分: 第一部分是代码备份,对整个根目录打包存放到安全的位置 tar zcvf backup_dir/backup_20160124.tar.gz /home/wordpress/html 第二部分是数据库备份 mysqldump -u username -ppassword yourdatabase > backup_20160124.sql 第二步:本地环境搭建 在本地机器上搭建一套apache+php+mysql系统。在windows机器上,可以直接安装个省事的WAMP(Windows+APACHE+MYSQL+PHP)。 然后把备份的数据库导入到本地的机器,把备份的代码解压到apache的工作目录。 设置本地hosts,举例: 127.0.0.1 zhaoyanblog.com 浏览器访问http://zhaoyanblog.com 就是访问的本地环境。 第三步:wordpress升级演练 wordpress升级有两种形式: 一种是通过wordpress的管理后台进行升级。 另外一种是把wordpress最新安装包下载下来,把其中的wp-content删除,然后用其覆盖当前的代码。 然后访问http://zhaoyanblog.com/wp-admin/upgrade.php进行其它升级(比如数据库数据)。 最后访问本地http://zhaoyanblog.com,确认升级是否有问题。 第四步:正式环境升级 当本地升级没有问题之后,把在本地的升级步骤,再实施到正式的环境即可。 最后说一句 wordpress好多版本是为了解决老版本中的安全问题,所以时间长了wordpress的版本升级还是很有必要的。

2016年1月24日 · 1 分钟

博客适配移动浏览器

博客使用了wordpress,虽然大部分wordpress的主题都是响应式布局,也就是随着客户端屏幕大小,语言进行自由适配,但是总是不完美的。 用wordpress,首先想到的就是用插件解决这个问题。发现wptouch这款插件的页面是最舒服的一款适配移动的插件。 wptouch是专门用来解决wordpress的移动端浏览的问题,它有自己专门的主题。功能强大。 wptouch只提供基础的功能,强大的主题功能需要付费升级到pro版本。 当然wordpress适配移动端,还有其它方式,举例说: 安装专门的移动主题,然后使用wordpress-mobile-theme-switcher等插件,根据User-agent进行动态主题切换。

2016年1月17日 · 1 分钟