第 11 页的文章列表

java反射机制以及在android开发中的应用

java中的反射机制:只要给定类的名字就可以得到所有类的信息。因为这个类的名字是可以在代码运行时动态指定的,所以利用java的反射机制比通过new的方式要灵活的多 在java中,通过new的方式创建的对象称为静态加载(编译时加载类),通过反射机制创建对象称为动态加载(运行时加载类) java反射机制的使用方式 这里有个Human类如下 package com.myway5; public class Human { private String name; private int age; public String word;

public Human() {
    // TODO Auto-generated constructor stub
}

public Human(String name) {
    this.name = name;
}

public Human(String name, int age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public int getAge() {
    return age;
}

public void setAge(int age) {
    this.age = age;
}
public void speak(String word) {
     System.out.println(word);
 }

} 我们使用反射机制获取Human类所有的信息 package com.myway5; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; public class Client { public static void main(String[] args) { // 获取类名等信息 Class class1 = Human.class; System.out.println(class1.getName()); System.out.println(class1.getSimpleName());

    System.out.println("***********构造方法**********");

    Constructor[] cs = class1.getDeclaredConstructors();
    for (Constructor constructor : cs) {
        System.out.print(constructor.getName() + "(");
        Class[] paramsType = constructor.getParameterTypes();
        for (Class class2 : paramsType) {
            System.out.print(class2.getName() + ",");
        }
        System.out.println(")");
    }

    System.out.println("**********公共成员变量************");
    Field[] fields = class1.getFields();
    for (Field field : fields) {
        System.out.println(field.getType().getName() + ":" + field.getName());
    }

    System.out.println("**********公共方法**************");
    Method[] methods = class1.getMethods();
    for (Method method : methods) {
        System.out.print(method.getName() + "(");
        Class[] params = method.getParameterTypes();
        for (Class class3 : params) {
            System.out.print(class3.getName() + ",");
        }
        System.out.println(method.getReturnType().getName() + ")");
    }

}

} 输出结果如下: com.myway5.Human Human ***********构造方法********** com.myway5.Human(java.lang.String,int,) com.myway5.Human(java.lang.String,) com.myway5.Human() **********公共成员变量************ java.lang.String:word **********公共方法************** getName(java.lang.String) setName(java.lang.String,void) getAge(int) setAge(int,void) wait(long,int,void) wait(long,void) wait(void) equals(java.lang.Object,boolean) toString(java.lang.String) hashCode(int) getClass(java.lang.Class) notify(void) notifyAll(void)
可以看到,所有公共的成员变量,方法都可以通过这个方式获取到,那么怎么调用其中的方法呢 public static void useMethod() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, InstantiationException, NoSuchMethodException, SecurityException { Class class1 = Human.class; Human man = (Human) class1.newInstance();//通过newInstance创建实例 Method method = class1.getMethod(“speak”, String.class); Object object = method.invoke(man, new Object[] { “hello reflect” }); } android开发中的使用后续更新 继上文更新: android开发中常常会使用java的反射机制来更改一些系统底层无法更改的代码逻辑。比如说在AlertDialog的使用中,通过自带的setPositiveButton或者setNegativeButton时,一旦点击按钮都会退出dialog,有时候我们不希望他退出,比如用户登录时登录失败再次登录。那么一种解决办法 就是通过java的反射机制。 package com.myway5.java_reflect; import android.app.AlertDialog; import android.content.DialogInterface; import android.os.Handler; import android.os.Message; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import java.lang.ref.WeakReference; import java.lang.reflect.Field; public class MainActivity extends AppCompatActivity{

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    AlertDialog.Builder builder=new AlertDialog.Builder(this);

    builder.setMessage("Hello Dialog")
             .setTitle("对话框")
                .setView(getLayoutInflater().inflate(R.layout.dialog_signin,null));
    builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    });
    builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
        @Override
        public void onClick(DialogInterface dialog, int which) {

        }
    });
    AlertDialog dialog=builder.create();
    try {
        Field field = dialog.getClass().getDeclaredField("mAlert");
        field.setAccessible(true);
        Object obj=field.get(dialog);
        field=obj.getClass().getDeclaredField("mHandler");
        field.setAccessible(true);
        field.set(obj,new ButtonHandler(dialog));
    }catch (Exception e){
        e.printStackTrace();
    }
    dialog.show();
}
private static final class ButtonHandler extends Handler {
    // Button clicks have Message.what as the BUTTON{1,2,3} constant
    private static final int MSG_DISMISS_DIALOG = 1;

    private WeakReference<DialogInterface> mDialog;

    public ButtonHandler(DialogInterface dialog) {
        mDialog = new WeakReference<DialogInterface>(dialog);
    }

    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {

            case DialogInterface.BUTTON_POSITIVE:
            case DialogInterface.BUTTON_NEGATIVE:
            case DialogInterface.BUTTON_NEUTRAL:
                ((DialogInterface.OnClickListener) msg.obj).onClick(mDialog.get(), msg.what);
                break;

            case MSG_DISMISS_DIALOG:
                //这里是点击后的逻辑,因为注释掉了dismiss(),dialog不会退出了
                //((DialogInterface) msg.obj).dismiss();
        }
    }
}

} 其中 try { Field field = dialog.getClass().getDeclaredField(“mAlert”); field.setAccessible(true); Object obj=field.get(dialog); field=obj.getClass().getDeclaredField(“mHandler”); field.setAccessible(true); field.set(obj,new ButtonHandler(dialog)); }catch (Exception e){ e.printStackTrace(); } 这个部分就是通过反射获取AlertDialog的私有变量mAlert,然后获取mAlert的成员变量mHandler,将这个Handler设置成我们自己的ButtonHandler,这样就解决了点击后退出的问题 代码地址:https://github.com/joyme123/java\_reflect 参考文章:http://www.oschina.net/question/163910\_27112

分类:java

android studio导入项目出现Gradle version 1.10 is required. Current version is 2.0的解决办法

1.首先在项目下找到gradlew.bat这个文件,单击运行。它会下载Gradle 1.10 。等待任务完成 2.在项目的报错的控制台中选择setting这个选项。然后设置本地的Gradle。我的是默认放在 C:\Users\joyme.gradle\wrapper\dists\gradle-1.10-all\bif7dlrky2i400uf9zsz2c0my\gradle-1.10

分类:问题

vitamio使用出现找不到文件的解决方法

首先我遇到这个问题肯定不是一般的找不到文件的错误。使用vitamio的VideoView的时候,出现一部分视频会找不到文件。 分析很久问题出现的原因,最后得出是因为这部分视频名都是URLEncode过的,可能是这个原因导致字符串在解析的过程中出现问题。然后跟踪代码到VideoView的setVideoPath处,发现他的实现如下 public void setVideoPath(String path) { setVideoURI(Uri.parse(path)); } 很明显这里就是导致错误所在,所以解决办法就是将string 类型的path先编码一下 videoView.setVideoPath(URLEncoder.encode(path, “UTF-8”));

分类:问题

java常量池

package 测试常量; public class Test { public static void main(String[] args){ String s1 = “hello world”; String s2 = “hello world”; System.out.println(s1==s2); String s4 = new String(“你好”); String s3 = “你好”; System.out.println(s3==s4); Integer i1 = 10; Integer i2 = 10; System.out.println(i1 == i2); Integer i3 = 2000; Integer i4 = 2000; System.out.println(i3 == i4); Integer i5 = new Integer(10); Integer i6 = new Integer(10); System.out.println(i5 == i6); int i7 = 2000; int i8 = 2000; System.out.println(i7 == i8); Double f1 = new Double(1.01); Double f2 = new Double(1.01); System.out.println(f1 == f2); Double f3 = 1000.01; Double f4 = 1000.01; System.out.println(f3 == f4); double f5 = 1000.01; double f6 = 1000.01; System.out.println(f5 == f6); } }


输出结果是 true false true false false true false false true

分类:java

ubuntu下linux创建桌面启动器以及菜单栏点击失效的解决方法

创建桌面启动器 进入/usr/share/applications vi eclipse.desktop 输入一下内容 [Desktop Entry] Encoding=UTF-8 Name=eclipse Comment=Eclipse IDE Exec=/home/jiang/eclipse/eclipse Icon=/home/jiang/eclipse/icon.xpm Terminal=false StartupNotify=true Type=Application Categories=Application;Development; Exec=env UBUNTU_MENUPROXY=0 /home/jiang/eclipse/eclipse 保存后,将这个文件复制到桌面文件夹 cp /usr/share/applications/eclipse.desktop /home/jiang/桌面 对于eclipse打不开菜单的情况,可以修改eclipase文件夹下的eclipse.ini为 -startup plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar –launcher.GTK_version 2 –launcher.library plugins/org.eclipse.equinox.launcher.gtk.linux.x86_64_1.1.300.v20150602-1417 -product org.eclipse.epp.package.jee.product –launcher.defaultAction openFile -showsplash org.eclipse.platform –launcher.XXMaxPermSize 256m –launcher.defaultAction openFile –launcher.appendVmargs -vmargs -Dosgi.requiredJavaVersion=1.7 -XX:MaxPermSize=256m -Xms256m -Xmx2048m ———————————— –launcher.GTK_version 2 这一部分是新增的部分

分类:linux

linux下编译安装mysql-connector-cpp

首先在github上下载mysql-connector-cpp git clone https://github.com/mysql/mysql-connector-cpp.git git上面有两个分支,2.0版本是支持mysql作为文档存储的接口,1.1版本是支持正常的关系数据库存储接口 首先我们编译安装2.0版本,进入代码目录执行 cmake . cmake –build . –config CCC cmake –build . –target install –config CCC 到这里已经安装完毕. 然后到testapp下编译测试样例 cmake . 提示出错,WITH-CONCPP没有设置,我试了编辑/etc/profile文件,设置这个变量为/usr/local/mysql/connector-c++-2.0/,但是仍然提示没有设置,于是我将CMakeLists中的 set(WITH_CONCPP $ENV{WITH_CONCPP} CACHE PATH “MySQL Connector/C++ 2.0 install location”) 改为 set(WITH_CONCPP “/usr/local/mysql/connector-c++-2.0/” CACHE PATH “MySQL Connector/C++ 2.0 install location”) 继续cmake . 提示出错,在/usr/local/mysql/connector-c++-2.0/lib64下找不到依赖库 那么将目录下生成的 libmysqlcppconn2.so libmysqlcppconn2.so.1 libmysqlcppconn2.so.1.0 拷贝到/usr/local/mysql/connector-c++-2.0/lib64中,没有的创建一个即可。 cmake . make 在run文件夹下面生成了两个可执行文件 devapi_test xapi_test 这两个文件的区别在于,xapi_test实现了c的接口,是通过mysql的一个叫做x plugin的插件连接mysql的,而devapi则是使用了c++的接口。所以如果使用xapi接口的话,mysql安装时必须安装x plugin 接下来编译安装1.1版本,先将当前的改动都commit了,然后 git checkout 1.1, cmake . 如果出错。 报缺少boost库错误,可以 sudo apt-get install libboost-all-dev 报缺少mysql.h等错误,可以通过sudo apt-get install libmysql++-dev 然后make sudo make install 然后将生成的动态库拷贝的/usr/local/lib下 sudo cp libmysqlcppconn.so* /usr/local/lib/

分类:linux

c++中的中文字符分割

在utf-8编码的前提下,一个字符可能占用的空间为1~4个char,由于这种不确定的字符长度导致在utf-8编码的string中,无法直接使用substr进行字符串分割。 解决的方案的关键在于利用utf-8编码的特点,utf-8的第一个字符的前缀连续为1的个数代表这个”字“占用的字符数量,当只有一个字符时,第一个字符的第一位为0。具体的说明可以参考这篇文章。http://www.ruanyifeng.com/blog/2007/10/ascii\_unicode\_and\_utf-8.html 这里主要说明怎么利用代码解决这个问题

int getUtf8CharLength(char c){
    int len = 0;
    if(c > 0){              //利用计算机中数字的存储特点,第一位为1为负,第一位为0为正,很容易判断
        return len + 1;     //第一位为0时为特殊情况,需要加1
    }
    while(c < 0){
        len++;
        c = c << 1;
    }
    return len;
}

std::string substrWithChinese(std::string str,unsigned int start,unsigned int length){
    unsigned int i = 0;             //标识前进的几个“字符”
    unsigned int cursor = 0;        //标识前进了几个“字”
    unsigned int save = 0;          //保存的字符标识
    unsigned int len = str.length();
    char* c = new char[len + 1];
    while(str[i] != '\0'&&length > 0){
        unsigned int l = getUtf8CharLength(str[i]); //获取字符长度
        if(cursor >= start){
            unsigned int m = l;
            while(m--){
                c[save++] = str[i++];
            }
            length--;
        }else{
            i+=l;
        }
        cursor++;
    }
    c[i] = '\0';
    return std::string(c);
}
分类:c++

ubuntu eclipse mars.2Bug修复

ubuntu eclipse mars.2Bug的bug具体表现为图标异常,菜单无法正常点击切换等等,问题是因为GTK方面,将eclipse的启动方式eclipse.desktop改为一下代码

   [Desktop Entry]
   Name=eclipse
   Comment=develop java app
   Exec=env SWT_GTK3=0 /home/jiang/software/eclipse/eclipse
   Icon=/home/jiang/software/eclipse/icon.xpm
   Terminal=false
   Type=Application
   Categories=devtool
分类:问题

网站登录系统设计

一、前言 一个网站的登录系统可以算作是一个网站的大门,如何让这个大门足够的安全,并且又不用太复杂是一个很考验经验的工作。作为一个没有经验的新手,简单记下一点自己在做网站登录系统设计时做法。 二、前提 首先假设我们设计的网站是一个单服务器的应用,并且他有多种登录方式(邮箱,手机,用户名),以及多种登录途径(web,app)。 三、正文 1.会话状态 因为是单服务器的应用,所以不用担心多台服务器之间的会话状态转移的问题,所以为了简单,我们采用的是cookie方式,这样既不用在用户关闭浏览器后再次访问就要重新登录,也可以通过设定cookie的失效时间,来让浏览器自动在一定时间后让用户重新登录,保护用户设备丢失带来的风险。 2.登录方式 考虑到需要支持邮箱,手机或者是用户名的登录,也就是用户随意输入其中的一种以及密码都要可以登录,所以要对用户名有一定的限制,首先用户名不能重复,并且用户不能是手机或者邮箱,因此要对用户名做一些简单的限制——用户名不能为纯数字,也不能包含@符号。 3.密码存储 密码的存储是一定要足够安全的。因此对密码的存储一定要够安全。我采用的是密码+salt的方式,使用sha-256加密。 4.身份验证 身份验证上,我在cookie中填入用户id和token连接而成的字符串(称为id_token),例如24|dashdiuasdhgiuagsduigaiusdg这种形式,|符号前面是Id,后面是token,token是登录时随机生成的,在登录时会讲登录记录插入到数据库中,这条记录包括用户id,登录名(用户名,邮箱或手机中的任一种)、登录途径(web还是app)、登录时生成的token、登录时间等等,然后之后用户提交请求时都会验证cookie,将cookie中的id和token截取出来,与最新的一条该用户id的登录成功的记录的token对比,如果一致,则表示身份是对的。这种做法可以很好的防止伪造cookie。对于app来说,将这个cookie保存下来就可以一直作为登录凭证。如果遇到手机丢失,想使手机上的登录失效,重新用新手机登录一次即可。 5.多端登录的冲突解决 在4.身份验证中说到,登录的身份验证是根据最新的该用户的登录记录来判断的,所以如果用户在app上登录了,再在网站上登录则会使app的登录失效,为了解决这个问题,可以在登录时附带上登录方式的字段,那么就可以解决web端和app端的冲突问题。

分类:架构设计

linux下使用crontab进行网站内容和数据库定期备份

crontab有几个常用的命令 crontab -l 列举crontab的任务 crontab -e 编辑crontab的任务 crontab -r 删除crontab的任务 crontab -h crontab的帮助 crontab -i 删除crontab前进行提示 crontab -e进行编辑任务时会使用nano进行编辑,编辑命令如下示例。 分 时 每月的第几天 每周的周几 命令 前5个参数可以使用通配符 *

m h dom mon dow command

设置每两分钟扫描一次,清理过期记录

*/2 * * * * /usr/bin/php /var/www/poker/scan.php >> /$

设置每周二23:29分备份一次

59 23 * * 2 /bin/bash /home/back.sh 59 23 * * 2 /bin/bash /home/back.sh就是我用来定期备份的指令,主要就是配合一个shell脚本 #!/bin/bash cd /home mv backup/* oldbackup/ echo “old backup file has been moved to oldbackup folder”; cd /home/backup Now=date "+%Y-%m-%d-%H-%M-%S" File_emlog=“backup-emlog-”${Now}“.sql” mysqldump -u me -ppassword emlog > $File_emlog File_java=backup-java-$Now.sql mysqldump -u me -ppassword java > $File_java File_plan=backup-plan-$Now.sql mysqldump -u me -ppassword plan > $File_plan File_sms=backup-sms-$Now.sql mysqldump -u me -ppassword sms > $File_sms File_tu=backup-tu-$Now.sql mysqldump -u me -ppassword tu > $File_tu File_wordpress=backup-wordpress-$Now.sql mysqldump -u me -ppassword wordpress > $File_wordpress echo “your databases backup successfully completed”; #数据文件到这里备份完毕 #下面备份网站的文件 tar -czf /home/backup/back_www.tar.gz /var/www

分类:linux