广点通广告集成问题之android 7.0以上版本抛出异常

一个app集成广点通广告的问题,在

Build.VERSION.SDK_INT <23

下面正常,在之等于或之上运行一小会马上出现:

Fatal signal 11 (SIGSEGV), code 1******

断断续续研究许久,最终还是找到了这个奇葩的答案

eclipse 在libs必须要有 cpu 处理器的 存放so文件的目录

armeabi、X86、mips

androidstudio 在jniLibs 下面也要有 cpu 处理器的 存放so文件的目录

armeabi、X86、mips

 

在运行没有出现此问题了,成功解决此问题!

代理模式原理及实例讲解(转自IBM)

设计模式是前人工作的总结和提炼。通常,被人们广泛流传的设计模式都是对某一特定问题的成熟的解决方案。如果能合理地使用设计模式,不仅能使系统更容易地被他人理解,同时也能使系统拥有更加合理的结构。本文对代理模式的 4 种角色、延迟加载、动态代理等做了一些介绍,希望能够帮助读者对代理模式有进一步的了解。

东汉末年,大将军何进引董卓入京,想借西北王的军队对抗阉党,无奈自己先被阉党做掉,而后造成巨变,导致诸侯并起,最终形成三国鼎立局面。汉献帝即位后,初平三年(公元 192 年),治中从事毛玠向曹操建议“奉天子以令不臣”,曹操采纳了他的建议,迎接汉献帝来到许昌。汉献帝刘协在许都没有实际的权利,曹操不断地诛除公卿大臣,不断地集军政大权于一身。建安元年八月,曹操进驻洛阳,立刻趁张杨、杨奉兵众在外,赶跑了韩暹,接着做了三件事:杀侍中台崇、尚书冯硕等,谓“讨有罪”;封董承、伏完等,谓“赏有功”;追赐射声校尉沮俊,谓“矜死节”。然后在第九天趁他人尚未来得及反应的情况下,迁帝都许,使皇帝摆脱其他势力的控制。此后,他还加紧步伐剪除异己,提高自己的权势。他首先向最有影响力的三公发难,罢免太尉杨彪、司空张喜;其次诛杀议郎赵彦;再次是发兵征讨杨奉,解除近兵之忧;最后是一方面以天子名义谴责袁绍,打击其气焰,另一方面将大将军让予袁绍,稳定大敌。这就是历史上著名的“挟天子以令诸侯”。汉献帝与曹操的关系,是历史上两位伟大的政治家的联手,稳定了东汉政权,最终平稳交接给曹魏政权,也间接映射了我们本文要讲解的“代理模式”。

代理模式

代理模式使用代理对象完成用户请求,屏蔽用户对真实对象的访问。现实世界的代理人被授权执行当事人的一些事宜,无需当事人出面,从第三方的角度看,似乎当事人并不存在,因为他只和代理人通信。而事实上代理人是要有当事人的授权,并且在核心问题上还需要请示当事人。

在软件设计中,使用代理模式的意图也很多,比如因为安全原因需要屏蔽客户端直接访问真实对象,或者在远程调用中需要使用代理类处理远程方法调用的技术细节 (如 RMI),也可能为了提升系统性能,对真实对象进行封装,从而达到延迟加载的目的。

代理模式角色分为 4 种:

  1. 主题接口:定义代理类和真实主题的公共对外方法,也是代理类代理真实主题的方法;
  2. 真实主题:真正实现业务逻辑的类;
  3. 代理类:用来代理和封装真实主题;
  4. Main:客户端,使用代理类和主题接口完成一些工作。

延迟加载

以一个简单的示例来阐述使用代理模式实现延迟加载的方法及其意义。假设某客户端软件有根据用户请求去数据库查询数据的功能。在查询数据前,需要获得数据库连接,软件开启时初始化系统的所有类,此时尝试获得数据库连接。当系统有大量的类似操作存在时 (比如 XML 解析等),所有这些初始化操作的叠加会使得系统的启动速度变得非常缓慢。为此,使用代理模式的代理类封装对数据库查询中的初始化操作,当系统启动时,初始化这个代理类,而非真实的数据库查询类,而代理类什么都没有做。因此,它的构造是相当迅速的。

在系统启动时,将消耗资源最多的方法都使用代理模式分离,可以加快系统的启动速度,减少用户的等待时间。而在用户真正做查询操作时再由代理类单独去加载真实的数据库查询类,完成用户的请求。这个过程就是使用代理模式实现了延迟加载。

延迟加载的核心思想是:如果当前并没有使用这个组件,则不需要真正地初始化它,使用一个代理对象替代它的原有的位置,只要在真正需要的时候才对它进行加载。使用代理模式的延迟加载是非常有意义的,首先,它可以在时间轴上分散系统压力,尤其在系统启动时,不必完成所有的初始化工作,从而加速启动时间;其次,对很多真实主题而言,在软件启动直到被关闭的整个过程中,可能根本不会被调用,初始化这些数据无疑是一种资源浪费。例如使用代理类封装数据库查询类后,系统的启动过程这个例子。若系统不使用代理模式,则在启动时就要初始化 DBQuery 对象,而使用代理模式后,启动时只需要初始化一个轻量级的对象 DBQueryProxy。

下面代码 IDBQuery 是主题接口,定义代理类和真实类需要对外提供的服务,定义了实现数据库查询的公共方法 request() 函数。DBQuery 是真实主题,负责实际的业务操作,DBQueryProxy 是 DBQuery 的代理类。

清单 1. 延迟加载代理
public interface IDBQuery {
 String request();
}
 public class DBQuery implements IDBQuery{
 public DBQuery(){
 try{
 Thread.sleep(1000);//假设数据库连接等耗时操作
 }catch(InterruptedException ex){
 ex.printStackTrace();
 }
 }

@Override
public String request() {
// TODO Auto-generated method stub
return "request string";
}
 
 
}
 public class DBQueryProxy implements IDBQuery{
 private DBQuery real = null;
 
@Override
public String request() {
// TODO Auto-generated method stub
//在真正需要的时候才能创建真实对象,创建过程可能很慢
if(real==null){
real = new DBQuery();
}//在多线程环境下,这里返回一个虚假类,类似于 Future 模式
return real.request();
}
 
}
 public class Main {
 public static void main(String[] args){
 IDBQuery q = new DBQueryProxy(); //使用代里
 q.request(); //在真正使用时才创建真实对象
 }
}

动态代理

动态代理是指在运行时动态生成代理类。即,代理类的字节码将在运行时生成并载入当前代理的 ClassLoader。与静态处理类相比,动态类有诸多好处。首先,不需要为真实主题写一个形式上完全一样的封装类,假如主题接口中的方法很多,为每一个接口写一个代理方法也很麻烦。如果接口有变动,则真实主题和代理类都要修改,不利于系统维护;其次,使用一些动态代理的生成方法甚至可以在运行时制定代理类的执行逻辑,从而大大提升系统的灵活性。

动态代理类使用字节码动态生成加载技术,在运行时生成加载类。生成动态代理类的方法很多,如,JDK 自带的动态处理、CGLIB、Javassist 或者 ASM 库。JDK 的动态代理使用简单,它内置在 JDK 中,因此不需要引入第三方 Jar 包,但相对功能比较弱。CGLIB 和 Javassist 都是高级的字节码生成库,总体性能比 JDK 自带的动态代理好,而且功能十分强大。ASM 是低级的字节码生成工具,使用 ASM 已经近乎于在使用 Java bytecode 编程,对开发人员要求最高,当然,也是性能最好的一种动态代理生成工具。但 ASM 的使用很繁琐,而且性能也没有数量级的提升,与 CGLIB 等高级字节码生成工具相比,ASM 程序的维护性较差,如果不是在对性能有苛刻要求的场合,还是推荐 CGLIB 或者 Javassist。

以清单 1 所示代码中的 DBQueryProxy 为例,使用动态代理生成动态类,替换上例中的 DBQueryProxy。首先,使用 JDK 的动态代理生成代理对象。JDK 的动态代理需要实现一个处理方法调用的 Handler,用于实现代理方法的内部逻辑。

清单 2. 动态代理
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;


public class DBQueryHandler implements InvocationHandler{
IDBQuery realQuery = null;//定义主题接口

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
//如果第一次调用,生成真实主题
if(realQuery == null){
realQuery = new DBQuery();
}
//返回真实主题完成实际的操作
return realQuery.request();
}
 
}

以上代码实现了一个 Handler,可以看到,它的内部逻辑和 DBQueryProxy 是类似的。在调用真实主题的方法前,先尝试生成真实主题对象。接着,需要使用这个 Handler 生成动态代理对象。代码如清单 3 所示。

清单 3. 生成动态代理对象
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class DBQueryHandler implements InvocationHandler{
IDBQuery realQuery = null;//定义主题接口

@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
//如果第一次调用,生成真实主题
if(realQuery == null){
realQuery = new DBQuery();
}
//返回真实主题完成实际的操作
return realQuery.request();
}

public static IDBQuery createProxy(){
IDBQuery proxy = (IDBQuery)Proxy.newProxyInstance(
ClassLoader.getSystemClassLoader(), new Class[]{IDBQuery.class}, new DBQueryHandler()
);
return proxy;
}
 
}

以上代码生成了一个实现了 IDBQuery 接口的代理类,代理类的内部逻辑由 DBQueryHandler 决定。生成代理类后,由 newProxyInstance() 方法返回该代理类的一个实例。至此,一个完整的动态代理完成了。

在 Java 中,动态代理类的生成主要涉及对 ClassLoader 的使用。以 CGLIB 为例,使用 CGLIB 生成动态代理,首先需要生成 Enhancer 类实例,并指定用于处理代理业务的回调类。在 Enhancer.create() 方法中,会使用 DefaultGeneratorStrategy.Generate() 方法生成动态代理类的字节码,并保存在 byte 数组中。接着使用 ReflectUtils.defineClass() 方法,通过反射,调用 ClassLoader.defineClass() 方法,将字节码装载到 ClassLoader 中,完成类的加载。最后使用 ReflectUtils.newInstance() 方法,通过反射,生成动态类的实例,并返回该实例。基本流程是根据指定的回调类生成 Class 字节码—通过 defineClass() 将字节码定义为类—使用反射机制生成该类的实例。从清单 4 到清单 7 所示是使用 CGLIB 动态反射生成类的完整过程。

清单 4. 定义接口
public interface BookProxy {
public void addBook();
}
清单 5. 定义实现类
//该类并没有申明 BookProxy 接口
 public class BookProxyImpl {
public void addBook() { 
System.out.println("增加图书的普通方法..."); 
 } 
}
清单 6. 定义反射类及重载方法
import java.lang.reflect.Method; 

import net.sf.cglib.proxy.Enhancer; 
import net.sf.cglib.proxy.MethodInterceptor; 
import net.sf.cglib.proxy.MethodProxy; 

public class BookProxyLib implements MethodInterceptor {
private Object target; 
/** 
 * 创建代理对象 
 * 
 * @param target 
 * @return 
*/ 
public Object getInstance(Object target) { 
 this.target = target; 
 Enhancer enhancer = new Enhancer(); 
 enhancer.setSuperclass(this.target.getClass()); 
 // 回调方法 
 enhancer.setCallback(this); 
 // 创建代理对象 
 return enhancer.create(); 
} 
 
@Override 
// 回调方法 
public Object intercept(Object obj, Method method, Object[] args, 
 MethodProxy proxy) throws Throwable { 
 System.out.println("事物开始"); 
 proxy.invokeSuper(obj, args); 
 System.out.println("事物结束"); 
 return null; 
} 
}
清单 7. 运行程序
public class TestCglib { 
 public static void main(String[] args) { 
 BookProxyLib cglib=new BookProxyLib(); 
 BookProxyImpl bookCglib=(BookProxyImpl)cglib.getInstance(new BookProxyImpl()); 
 bookCglib.addBook(); 
 } 
}
清单 8. 运行输出
事物开始
增加图书的普通方法...
事物结束

代理模式的应用场合

代理模式有多种应用场合,如下所述:

  1. 远程代理,也就是为一个对象在不同的地址空间提供局部代表,这样可以隐藏一个对象存在于不同地址空间的事实。比如说 WebService,当我们在应用程序的项目中加入一个 Web 引用,引用一个 WebService,此时会在项目中声称一个 WebReference 的文件夹和一些文件,这个就是起代理作用的,这样可以让那个客户端程序调用代理解决远程访问的问题;
  2. 虚拟代理,是根据需要创建开销很大的对象,通过它来存放实例化需要很长时间的真实对象。这样就可以达到性能的最优化,比如打开一个网页,这个网页里面包含了大量的文字和图片,但我们可以很快看到文字,但是图片却是一张一张地下载后才能看到,那些未打开的图片框,就是通过虚拟代里来替换了真实的图片,此时代理存储了真实图片的路径和尺寸;
  3. 安全代理,用来控制真实对象访问时的权限。一般用于对象应该有不同的访问权限的时候;
  4. 指针引用,是指当调用真实的对象时,代理处理另外一些事。比如计算真实对象的引用次数,这样当该对象没有引用时,可以自动释放它,或当第一次引用一个持久对象时,将它装入内存,或是在访问一个实际对象前,检查是否已经释放它,以确保其他对象不能改变它。这些都是通过代理在访问一个对象时附加一些内务处理;
  5. 延迟加载,用代理模式实现延迟加载的一个经典应用就在 Hibernate 框架里面。当 Hibernate 加载实体 bean 时,并不会一次性将数据库所有的数据都装载。默认情况下,它会采取延迟加载的机制,以提高系统的性能。Hibernate 中的延迟加载主要分为属性的延迟加载和关联表的延时加载两类。实现原理是使用代理拦截原有的 getter 方法,在真正使用对象数据时才去数据库或者其他第三方组件加载实际的数据,从而提升系统性能。
结束语

设计模式是前人工作的总结和提炼。通常,被人们广泛流传的设计模式都是对某一特定问题的成熟的解决方案。如果能合理地使用设计模式,不仅能使系统更容易地被他人理解,同时也能使系统拥有更加合理的结构。本文对代理模式的 4 种角色、延迟加载、动态代理等做了一些介绍,希望能够帮助读者对代理模式有进一步的了解。

链接地址:https://www.ibm.com/developerworks/cn/java/j-lo-proxy-pattern/index.html#icomments

java多线程编程核心技术和java并发编程的艺术

《java多线程编程核心技术》:

这本书非常不错,里面多多线编程的讲解还是比较透彻的,对于理解多线程编程,线程通信等概念还是很有帮助,书中举例了大量的实例,可以边看书边学习书中的代码,之前用PDF下载看了,没有仔细的精读,读过之后还是对多线,线程锁等概念还是比较模糊,还是打算买本纸制的书来看看,下面书的购买链接,希望提升自己的同学可以买来看看!

https://s.click.taobao.com/OPByWqw  购买》

《java并发编程的艺术》:

并发编程领域的扛鼎之作,作者是阿里和1号店的资深Java技术专家,对并发编程有非常深入的研究,《Java并发编程的艺术》是他们多年一线开发经验的结晶。本书的部分内容在出版早期发表在Java并发编程网和InfoQ等技术社区,得到了非常高的评价。它选取了Java并发编程中最核心的技术进行讲解,从JDK源码、JVM、CPU等多角度全面剖析和讲解了Java并发编程的框架、工具、原理和方法,对Java并发编程进行了最为深入和透彻的阐述。

《Java并发编程的艺术》内容涵盖Java并发编程机制的底层实现原理、Java内存模型、Java并发编程基础、Java中的锁、并发容器和框架、原子类、并发工具类、线程池、Executor框架等主题,每个主题都做了深入的讲解,同时通过实例介绍了如何应用这些技术。

https://s.click.taobao.com/NqjwWqw 购买》

Java中数组、List、Set互相转换

java中常见的list、set、array的相互转换,下面举例几个实例参考代码如下: 数组转List

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
List staffsList = Arrays.asList(staffs);

需要注意的是, Arrays.asList() 返回一个受指定数组决定的固定大小的列表。所以不能做 add 、 remove 等操作,否则会报错。

List staffsList = Arrays.asList(staffs);
staffsList.add("Mary"); // UnsupportedOperationException
staffsList.remove(0); // UnsupportedOperationException

如果想再做增删操作呢?将数组中的元素一个一个添加到列表,这样列表的长度就不固定了,可以进行增删操作。

List staffsList = new ArrayList<String>();
for(String temp: staffs){
  staffsList.add(temp);
}
staffsList.add("Mary"); // ok
staffsList.remove(0); // ok

数组转Set

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
Set<String> staffsSet = new HashSet<>(Arrays.asList(staffs));
staffsSet.add("Mary"); // ok
staffsSet.remove("Tom"); // ok

List转数组

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
List<String> staffsList = Arrays.asList(staffs);

Object[] result = staffsList.toArray();
//或
String[] result = staffsList.toArray(new String[1] );

List转Set

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
List staffsList = Arrays.asList(staffs);

Set result = new HashSet(staffsList);

Set转数组

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
Set<String> staffsSet = new HashSet<>(Arrays.asList(staffs));

Object[] result = staffsSet.toArray();
//或
String[] result = staffsSet.toArray(new String[1] );

Set转List

String[] staffs = new String[]{"Tom", "Bob", "Jane"};
Set<String> staffsSet = new HashSet<>(Arrays.asList(staffs));

List<String> result = new ArrayList<>(staffsSet);

java数组去重的实例

public static void main(String[] args) {

      int[] name = new int[] { 1, 2, 3, 4, 1, 2, 3 };

      Set<Integer> names = new HashSet<Integer>();

      for (int i = 0; i < name.length; i++) {

           if (!names.contains(name[i])) {

                names.add(name[i]);

           }

      }

      Integer[] names_new = names.toArray(new Integer[1]);

      for (int name : names_new) {

           System.out.println(name + ” “);

      }

}

O(nlogn)、O(logn)、O(1)、O(n)、O(n^2)区别

今天看到文章中有这些符号,混淆了不是很理解,查阅了资料分享记录一下

这是算法的时空复杂度的表示。不仅仅用于表示时间复杂度,也用于表示空间复杂度。

O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。

比如时间复杂度为O(n),就代表数据量增大几倍,耗时也增大几倍。比如常见的遍历算法。
再比如时间复杂度O(n^2),就代表数据量增大n倍时,耗时增大n的平方倍,这是比线性更高的时间复杂度。比如冒泡排序,就是典型的O(n^2)的算法,对n个数排序,需要扫描n×n次。

再比如O(logn),当数据增大n倍时,耗时增大logn倍(这里的log是以2为底的,比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度)。二分查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中查找只要找8次就可以找到目标。

O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8=2048倍。这个复杂度高于线性低于平方。归并排序就是O(nlogn)的时间复杂度。

O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)

php实现扫描附件的功能,并判断是否是目录,递归访问目录,返回上一层目录功能的实现

功能描述:
我们在做选择附件上传的时候,可能选择在项目中已经上传过的附件,这样我们就需要扫描文件,选择指定文件并上传。
demo入口代码如下:
~~ <!DOCTYPE html PUBLIC “-//W3C//DTD HTML 4.01 Transitional//EN” “http://www.w3.org/TR/html4/loose.dtd”>
~~ <html>
~~ <head>
~~ <meta http-equiv=”Content-Type” content=”text/html; charset=UTF-8″>
~~ <title>文件列表的扫描</title>
~~ <script type=”text/javascript” src=”./jquery-1.7.1.js”></script>
~~ </head>
~~ <body>
~~
~~ <p>上传文件</p>
~~ <input name=’filepath’ value=” id=’filepath’  size=’50’/><a href=’javascript:;’ onclick=’selectImage(this)’>浏览</a>
~~ <script type=”text/javascript”>
~~ function selectImage(e){
~~ var xx = e.pageX || 0;
~~ var yy = e.pageY || 0;
~~ if(xx !=0 && yy !=0 ){
~~ posLeft = xx-100;
~~ posTop = yy;
~~ }else{ var posLeft = 100; var posTop = 100; }
~~ //if(!fname) fname = ‘form1.picname’;
~~ //if(!stype) stype = ”;
~~ window.open(“./select_images.php”, “popUpImagesWin”, “scrollbars=yes,resizable=yes,statebar=no,width=600,height=400,left=”+posLeft+”, top=”+posTop);
~~ }
~~ </script>
~~ </body>
~~ </html>
核心代码的实现代码如下:
~~ <?php
~~ /**
~~  * 文件的扫描
~~  *
~~  */
~~ //文件的存放地址
~~ $uploadPath = dirname(__FILE__) . DIRECTORY_SEPARATOR;
~~ //请求的目录地址
~~ $_GET[‘activepath’] = isset( $_GET[‘activepath’] ) ? urldecode($_GET[‘activepath’]) : “”;
~~ $activepath = ( isset( $_GET[‘activepath’] ) && ( trim($_GET[‘activepath’]) ) ) ? trim( $_GET[‘activepath’] ) : ‘upload’;
~~
~~ $fileList = scanDirList($uploadPath,$activepath );
~~
~~ //上一级目录
~~ if( $activepath != “” && $activepath != “upload” ){
~~ $preDir = substr( dirname( $uploadPath.$activepath ),strlen( $uploadPath ) );
~~ }else{
~~ $preDir = $activepath;
~~ }
~~ $preDir = urlencode( $preDir );
~~
~~
~~ //文件列表的输出
~~ $fileTrHtml = ”;
~~
~~ foreach( $fileList as $k=>$v ){
~~
~~ $fileTrHtml .= “<tr><td>”.($v[‘isdir’]==1 ? ‘【目录】’ : ‘【文件】’ );
~~
~~ if( $v[‘isdir’]== 1){
~~ $v[‘path’] = urlencode( $v[‘path’] );
~~ $fileTrHtml .= “<a href=’./select_images.php?activepath={$v[‘path’]}’>{$v[‘name’]}</a>”;
~~
~~ }else{
~~
~~ $fileTrHtml .= “<a href=’javascript:;’ onclick=\”setImageUrl(‘{$v[‘path’]}’)\”>{$v[‘name’]}</a>”;
~~
~~ }
~~
~~
~~ $fileTrHtml .= “</td></tr>”;
~~ }
~~
~~
~~
~~ $html = <<<EOT
~~ <html>
~~ <head></head>
~~ <body>
~~
~~ <div>
~~ <table>
~~ <tr>
~~ <td><a href=”./select_images.php?activepath={$preDir}”>返回上一级目录</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;当前目录{$activepath}</td>
~~ </tr>
~~ {$fileTrHtml}
~~ </table>
~~ </div>
~~ <script type=’text/javascript’>
~~ function setImageUrl( imgurl ){
~~ window.opener.document.getElementById(‘filepath’).value = imgurl;
~~ if(document.all) window.opener=true;
~~   window.close();
~~ }
~~ </script>
~~ </body>
~~ </html>
~~ EOT;
~~
~~ echo $html;
~~
~~
~~ /**
~~  *
~~  * @param  $uploadPath 文件存储根目录
~~  * @param  $activepath 需要扫描的问了名称
~~  */
~~ function scanDirList($uploadPath,$activepath){
~~ $file_array = array();
~~ $path = $uploadPath.$activepath;
~~ if ($handle = @opendir($path)) {
~~ while (false !== ($file = @readdir($handle))) {
~~ if($file==’.’ || $file==’..’){
~~ continue;
~~ }
~~ $filePath = $activepath.”/”.$file;
~~ $temp[‘name’] = $file;
~~ $temp[‘path’] = $filePath;
~~ if(is_dir($filePath)){
~~ $temp[‘isdir’] = 1;
~~ }else{
~~ $temp[‘isdir’] = 0;
~~ }
~~ $file_array[] = $temp;
~~ }
~~ @closedir($handle);
~~ }
~~ return $file_array;
~~ }
~~
~~
~~ ?>
demo托管地址:[https://github.com/abaiweb/file]

android的fragment使用中static静态fragment实例遇到的坑

android的fragment使用中static静态fragment实例遇到的坑
场景描述:
FragmentActivity + viewpager + fragment
问题描述:
FragmentActivity finish过后 由于static的类变量还存在 没有销毁 导致多次启动应用 fragment 多次运行
代码片段:
宿主片段:
TabFragmentAdapter  tfa = new TabFragmentAdapter( getSupportFragmentManager(), this, new GezitechFragment[]{FragmentBookShelf_.newIntent(),FragmentBookShop_.newIntent()}, getResources().getStringArray(R.array.tab_arr) ) ;
pager.setOffscreenPageLimit(2);
pager.setAdapter( tfa );
// 定义 SlidingTabLayout
stl.setDistributeEvenly(true);
stl.setSelectedIndicatorColors(getResources().getColor(R.color.white));
stl.setBackgroundColor(getResources().getColor(R.color.c_title_bg));
stl.setCustomTabView(R.layout.read_tab_item_view, R.id.tv_tab_item_des);
stl.setViewPager( pager ); // 加载ViewPager
fragment 片段:
static FragmentBookShelf_ _this = null;
public static FragmentBookShelf_ newIntent() {
if (_this == null) {
_this = new FragmentBookShelf_();
}
return (FragmentBookShelf_) _this;
}
解决办法:
在fragment中 ondestroty 销毁时 将 _this的值赋值为NULL 即可解决 finish 没有销毁的情况。。。
void onDestroty(){
_this = null;_
super.onDestroty();
}

java保留2位小数的方法

java中双精度的小数相乘可能会失去精度,导致结果和预期的结果不一样,在比较敏感的数字运算中,会造成不一样的麻烦,下面介绍相关的处理方法,代码如下:

public class Test {

public static void main(String[] args) {

double coin = coinFigure(); //获取2个double类型的乘积

//对结果保留两位小数方法一:

System.out.println(“保留2位数字:”+ new java.text.DecimalFormat(“0.00”).format( coin )  );

//对结果保留两位小数方法二:

DecimalFormat df=new DecimalFormat(“0.##”);

String st = df.format( coin );

System.out.println(“保留2位数字:”+ st );

}

//获取乘集

static double coinFigure() {

        BigDecimal b1 = new BigDecimal( 10.00 );

        BigDecimal b2 = new BigDecimal( 13.98899 );

        return b1.multiply(b2).doubleValue();

    }

}

运行效果如图:

node.js的简单例子

本实例摘抄 : http://blog.csdn.net/u014595019/article/details/50845726

按照本篇文章的例子会出现以下错误。

错误是因为缺少包,按照解决办法依次解决即可!

Error: Cannot find module ‘express’

    at Function.Module._resolveFilename (module.js:469:15)

    at Function.Module._load (module.js:417:25)

    at Module.require (module.js:497:17)

    at require (internal/module.js:20:19)

    at Object.<anonymous> (/Users/abai/nodewww/tests/test.js:2:27)

    at Module._compile (module.js:570:32)

    at Object.Module._extensions..js (module.js:579:10)

    at Module.load (module.js:487:32)

    at tryModuleLoad (module.js:446:12)

    at Function.Module._load (module.js:438:3)

解决办法:

sudo npm install express

Error: Cannot find module ‘body-parser’

    at Function.Module._resolveFilename (module.js:469:15)

    at Function.Module._load (module.js:417:25)

    at Module.require (module.js:497:17)

    at require (internal/module.js:20:19)

    at Object.<anonymous> (/Users/abai/nodewww/tests/test.js:4:27)

    at Module._compile (module.js:570:32)

    at Object.Module._extensions..js (module.js:579:10)

    at Module.load (module.js:487:32)

    at tryModuleLoad (module.js:446:12)

    at Function.Module._load (module.js:438:3)

解决办法: sudo npm install body-parser

Error: Cannot find module ‘cookie-parser’

    at Function.Module._resolveFilename (module.js:469:15)

    at Function.Module._load (module.js:417:25)

    at Module.require (module.js:497:17)

    at require (internal/module.js:20:19)

    at Object.<anonymous> (/Users/abai/nodewww/tests/test.js:5:27)

    at Module._compile (module.js:570:32)

    at Object.Module._extensions..js (module.js:579:10)

    at Module.load (module.js:487:32)

    at tryModuleLoad (module.js:446:12)

    at Function.Module._load (module.js:438:3)

解决办法:sudo npm install cookie-parser

运行项目  node test.js

浏览器输入:http://127.0.0.1:3000/  即可体验node.js 带来的乐趣了

github地址:https://github.com/abaiweb/tests.git