2013/6/25
最近研究ubuntu,用apt-get命令安装一些软件包时,总报错:E:could not get lock /var/lib/dpkg/lock -open等
出现这个问题的原因可能是有另外一个程序正在运行,导致资源被锁不可用。而导致资源被锁的原因,可能是上次安装时没正常完成,而导致出现此状况。
解决方法:输入以下命令
sudo rm /var/cache/apt/archives/lock
sudo rm /var/lib/dpkg/lock
之后再安装想装的包,即可解决
2013/6/25
现在的软件越来越好安装,尤其是在ubuntu下安装软件,更是没有技巧,只需要在联网的情况下使用apt-get inatll 即可。在决定安装mysql之前,要先确定系统是否已经安装mysql。如下图:
由此可以看出系统中并没有安装mysql.下面执行sudo apt-get install mysql-server my-client进行安装。下图:
输入Y进入到安装界面,在安装过程中,会弹出一个界面要求输入mysql的root的密码,这里一定输入,省得安装后再设密码了。如下图
然后会要求确认,再输一遍,然后系统会自动安装mysql直到完成。
mysql安装完成后,我们可以通过netstat -tap|grep mysql来查看系统是否已经有了mysql服务,如下图,
出现上面的信息,说明我们安装mysql成功。
下面进行简单的配置
安装完成后通过修改/etc/mysql/my.cnf(此文件为mysql的配置文件)。将文件中的binding-address=127.0.0.1注释掉。其它配置根据需要更改。
登录数据库命令:mysql -u root -p 回车后,输入我们前面所设的密码,就可以登录成功。如图
如果要查看数据库使用的字符集,可以输入show variables like 'character%';(注意分号不可省略)如图
如果要更改这些,在my.cnf里更改即可。
至此安装mysql成功。
介绍mysql的几个常用命令
一、库操作
1、、创建数据库
命令:create database <数据库名>
例如:建立一个名为test的数据库
mysql> create database test;
2、显示所有的数据库
命令:show databases
mysql> show databases;
3、删除数据库
命令:drop database <数据库名>
例如:删除名为 test的数据库
mysql> drop database test;
4、连接数据库
命令: use <数据库名>
例如:如果test数据库存在,尝试存取它:
mysql> use test;
屏幕提示:Database changed
5、查看当前使用的数据库
mysql> select database();
6、当前数据库包含的表信息:
mysql> show tables;
mysql的退出命令为quit或者是exit。刚才退出的时候,我输入exit还要我再加个;,真他妈贱。
其它的没有时间再写了。就写到这儿算完,所有的东西都要自己经过手后才能知道是怎么回事,没有事多尝试。
2013/6/25
利用Crontab为Linux(ubuntu)定时备份Mysql数据库
利用系统crontab来定时执行备份文件,按日期对备份结果进行保存,达到备份的目的。
1、创建保存备份文件的路径/mysqldata (挂载到根目录下)
#mkdir /mysqldata
2、创建/usr/sbin/bakmysql文件
#vi /usr/sbin/bakmysql
输入
rq=` date +%Y%m%d `
tar zcvf /mysqldata/mysql$rq.tar.gz /var/lib/mysql
或者写成
rq=` date +%Y%m%d `
mysqldump ——all-databases -u root -p密码 > /mysqldata/mysql$rq.sql
/var/lib/mysql是你数据库文件的目录,部分用户是/usr/local/mysql/data,每个人可能不同
/mysqldata/表示保存备份文件的目录,这个每个人也可以根据自己的要求来做。
3、修改文件属性,使其可执行
# chmod +x /usr/sbin/bakmysql 中国网管联盟www.bitscn.com
4、修改/etc/crontab 网管网bitsCN.com
#vi /etc/crontab
在下面添加
01 3 * * * root /usr/sbin/bakmysql
表示每天3点钟执行备份
5、重新启动crond 中国网管论坛bbs.bitsCN.com
# /etc/rc.d/init.d/crond restart 中国网管联盟www.bitscn.com
或利用# sudo /etc/init.d/cron restart
完成。
这样每天你在/mysqldata可以看到这样的文件
mysql20040619.tar.gz
你直接下载就可以了。
2013、6、26
mysql.h: No such file or directory出现这个错误是因为系统没有安装mysql安装包
sudo aptitude install libmysql++-dev即可
编译时需要加连接-lmysqlclient
2013、6、26
1、alarm
-------------------------------------------
如果不要求很精确的话,用alarm()和signal()就够了
unsigned int alarm(unsigned int seconds)
函数说明: alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程。如果参数seconds为0,则之前设置的闹钟会被取消,并将剩下的时间返回。
返回值: 返回之前闹钟的剩余秒数,如果之前未设闹钟则返回0。
alarm()执行后,进程将继续执行,在后期(alarm以后)的执行过程中将会在seconds秒后收到信号SIGALRM并执行其处理函数。
#include <stdio.h>
#include <unistd.h>
#include <signal.h>
void sigalrm_fn(int sig)
{
printf("alarm!/n");
alarm(2);
return;
}
int main(void)
{
signal(SIGALRM, sigalrm_fn);
alarm(1);
while(1) pause();
}
2、setitimer()
-------------------------------------------
int setitimer(int which, const struct itimerval *value, struct itimerval *ovalue));
setitimer()比alarm功能强大,支持3种类型的定时器:
ITIMER_REAL : 以系统真实的时间来计算,它送出SIGALRM信号。
ITIMER_VIRTUAL : -以该进程在用户态下花费的时间来计算,它送出SIGVTALRM信号。
ITIMER_PROF : 以该进程在用户态下和内核态下所费的时间来计算,它送出SIGPROF信号。
setitimer()第一个参数which指定定时器类型(上面三种之一);第二个参数是结构itimerval的一个实例;第三个参数可不做处理。
setitimer()调用成功返回0,否则返回-1。
下面是关于setitimer调用的一个简单示范,在该例子中,每隔一秒发出一个SIGALRM,每隔0.5秒发出一个SIGVTALRM信号:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
int sec;
void sigroutine(int signo){
switch (signo){
case SIGALRM:
printf("Catch a signal -- SIGALRM /n");
signal(SIGALRM, sigroutine);
break;
case SIGVTALRM:
printf("Catch a signal -- SIGVTALRM /n");
signal(SIGVTALRM, sigroutine);
break;
}
return;
}
int main()
{
struct itimerval value, ovalue, value2; //(1)
sec = 5;
printf("process id is %d/n", getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine);
value.it_value.tv_sec = 1;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 1;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue); //(2)
value2.it_value.tv_sec = 0;
value2.it_value.tv_usec = 500000;
value2.it_interval.tv_sec = 0;
value2.it_interval.tv_usec = 500000;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
for(;;)
;
}
(1)
struct itimerval
struct itimerval {
struct
timevalit_interval;
struct timeval it_value;
};
itimer
val: i --> interval
val --> value
itimerval结构中的it_value是减少的时间,当这个值为0的时候就发出相应的信号了. 然后再将it_value设置为it_interval值.
(2) setitimer()
setitimer()为其所在进程设置一个定时器,如果itimerval.
it_interval不为0(it_interval的两个域都不为0),则该定时器将持续有效(每隔一段时间就会发送一个信号)
注意:Linux信号机制基本上是从Unix系统中继承过来的。早期Unix系统中的信号机制比较简单和原始,后来在实践中暴露出一些问题,因此,把那些建立在早期机制上的信号叫做"不可靠信号",信号值小于SIGRTMIN(SIGRTMIN=32,SIGRTMAX=63)的信号都是不可靠信号。这就是"不可靠信号"的来源。它的主要问题是:进程每次处理信号后,就将对信号的响应设置为默认动作。在某些情况下,将导致对信号的错误处理;因此,用户如果不希望这样的操作,那么就要在信号处理函数结尾再一次调用signal(),重新安装该信号。
linux延时函数(转载)
应用层:
#include
1、unsigned int sleep(unsigned int seconds); 秒级
2、int usleep(useconds_t usec); 微秒级:1/10^-6
补:
以前对于Linux下的延时函数只用过Sleep,不过最近发现还有其他的函数:
延时可以采用如下函数:
unsigned int sleep(unsigned int seconds);
sleep()会使目前程式陷入「
冬眠
」seconds秒,除非收到「
不可抵
」的信号。
如果sleep()没睡饱,它将会返回还需要补眠的时间,否则一般返回零。
void usleep(unsigned long usec);
usleep与sleep()类同,不同之处在於秒的单位为10E-6秒。
int select(0,NULL,NULL,NULL,struct timeval *tv);
可以利用select的实作sleep()的功能,它将不会等待任何事件发生。
int nanosleep(struct timespec *req,struct timespec *rem);
nanosleep会沉睡req所指定的时间,若rem为non-null,而且没睡饱,将会把要补眠的时间放在rem上。
#include
3、int nanosleep(const struct timespec *req, struct timespec *rem);
struct timespec {
time_t tv_sec;
long tv_nsec;
};
// The value of the nanoseconds field must be in the range 0 to 999999999.
#include
#include
void Sleep(int iSec,int iUsec)
{
struct timeval tv;
tv.tv_sec=iSec;
tv.tv_usec=iUsec;
select(0,NULL,NULL,NULL,&tv);
}
iSec 为延时秒数,Usec为延时微秒数.
注:1秒=1000毫秒=1000000微秒=1000000000纳秒=1000000000000皮秒=1000000000000000飞秒
1s=1000ms=1000000us=1000000000ns=1000000000000ps=1000000000000000fs
内核层:
include
1、void ndelay(unsigned long nsecs); 纳秒级:1/10^-10
2、void udelay(unsigned long usecs); 微秒级: 1/10^-6
3、void mdelay(unsigned long msecs); 毫秒级:1/10^-3
***********************************
Linux下如何实现秒以下精确定时与休眠
Linux中提供的休眠函数是sleep和alarm,但是他们仅仅提供以秒为单位的休眠,这中休眠有些进程显然太长了,那么怎样才能使进程以更小的时间分辨率休眠呢?
我知道的方法有2种,下面就做分别介绍。
第一种方法是使用定时器,Linux提供的定时器函数是:
int setitimer(int which, const struct itimerval *value, struct
itimerval *ovalue);
which指定那种定时器。Linux提供3种定时器:
TIMER_REAL: 准确定时器,超时会发出SIGALRM信号;
TIMER_VIRTUAL: 虚拟定时器,只记进程时间,所以会根据进程执行时间而变化,不能实现准确定时,超时发出SIGVTALRM信号;
TIMER_PROF: 梗概计时器,它会根据进程时间和系统时间而变化,不能实现准确定时,超时发出SIGPROF信号;
在进程中应该捕捉所设定时器会发出的信号,因为进程收到定时器超时发出的信号后,默认动作是终止。
value是设置定时器时间,相关结构如下:
struct itimerval {
struct timeval it_interval;
struct timeval it_value;
};
struct timeval {
long tv_sec;
long tv_usec;
};
it_interval指定间隔时间,it_value指定初始定时时间。如果只指定it_value,就是实现一次定时;如果同时指定 it_interval,则超时后,系统会重新初始化it_value为it_interval,实现重复定时;两者都清零,则会清除定时器。
tv_sec提供秒级精度,tv_usec提供微秒级精度,以值大的为先,注意1s = 1000000ms。
ovalue用来保存先前的值,常设为NULL。
如果是以setitimer提供的定时器来休眠,只需阻塞等待定时器信号就可以了。
第二种方法是使用select来提供精确定时和休眠:
int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *timeout);
n指监
视的文件描述符范围,通常设为所要select的fd+1,readfds,writefds和exceptfds分别是读,写和异常文件描述符集,timeout为超时时间。
可能用到的关于文件描述符集操作的宏有:
FD_CLR(int fd, fd_set *set); 清除fd
FD_ISSET(int fd, fd_set *set); 测试fd是否设置
FD_SET(int fd, fd_set *set); 设置fd
FD_ZERO(fd_set *set); 清空描述符集
我们此时用不到这些宏,因为我们并不关心文件描述符的状态,我们关心的是select超时。所以我们需要把readfds,writefds和exceptfds都设为NULL,只指定timeout时间就行了。至于n我们可以不关心,所以你可以把它设为任何非负值。实现代码如下:
int msSleep(long ms) {
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = ms;
return select(0, NULL, NULL, NULL, &tv);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
void sigroutine(int signo)
{
static int count1=0,count2=0;
switch (signo)
{
case SIGALRM:
count1++;
printf("Catch a signal -- SIGALRM \n");
printf("count1 = %d\n\n", count1);
signal(SIGALRM, sigroutine);
break;
case SIGVTALRM:
count2++;
printf("Catch a signal -- SIGVTALRM \n");
printf("count2 = %d\n\n", count2);
signal(SIGVTALRM, sigroutine);
break;
}
return;
}
int main()
{
struct itimerval value, ovalue, value2;
printf("process id is %d\n", getpid());
signal(SIGALRM, sigroutine);
signal(SIGVTALRM, sigroutine);
value.it_value.tv_sec = 2;
value.it_value.tv_usec = 0;
value.it_interval.tv_sec = 3;
value.it_interval.tv_usec = 0;
setitimer(ITIMER_REAL, &value, &ovalue);
value2.it_value.tv_sec = 1;
value2.it_value.tv_usec = 0;
value2.it_interval.tv_sec = 3;
value2.it_interval.tv_usec = 0;
setitimer(ITIMER_VIRTUAL, &value2, &ovalue);
while(1);
}
2013、6、27
进入终端
1.sudo apt-get install ibus #可以调出在桌面上显示的键盘,输入法框架,ibus可能提示已经安装,不影响,继续...
2.sudo apt-get install ibus-pinyin #安装ibus拼音输入法
3.英语环境下默认输入法不启动,启动方法:SystemSettings->Language Support->Keyboard input methodsystem,点击下拉项,选择ibus,重启
4.点击右上角的小键盘,Prenferences->InputMethod->select an input method->Chinese->pinyin,然后点击右侧add
5.Ctrl+space切换输入法
**************************************************************************
// 2013/6/27
// 潘风云
// 更改订单提交状态
// 编译: gcc updatedata.c -o updatedata -lmysqlclient
#include <stdio.h>
#include <stdlib.h>
#include <mysql/mysql.h> //数据库头文件
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h> //系统时间头文件
#include <stdbool.h> //布尔类型头文件
time_t rawtime;
struct tm *timeinfo; //时间信息结构体
void sigroutine(int signo); //修改状态值功能函数申明
bool judge(char *ch); //判断时间是否过期函数申明
void error_quit(const char *str, MYSQL *connection); //遇到错误信息推出函数申明
int main()
{
struct itimerval value, ovalue;
time ( &rawtime );
timeinfo = localtime ( &rawtime ); //获取当前时间
signal(SIGALRM, sigroutine); //设置信号处理函数指向
//当前运行时间值
value.it_value.tv_sec = 5; //设置秒数
value.it_value.tv_usec = 0; //设置微秒数
value.it_interval.tv_sec = 5;
value.it_interval.tv_usec = 0; //设置参数的时间段
setitimer(ITIMER_REAL, &value, &ovalue); //选择us级的ITIMER_REAL类型定时器
while(1) //循环
{
if(value.it_value.tv_sec==0)
{
printf("time over!");
}
else{
printf("value.it_value.tv_sec is %d",value.it_value.tv_sec);
printf ( "%4d-%02d-%02d %02d:%02d:%02d\n",1900+timeinfo->tm_year,
1+timeinfo->tm_mon,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);
}
}
}
void error_quit(const char *str, MYSQL *connection) //遇到错误信息推出函数
{
fprintf(stderr, "%s : %s: %s\n", str, mysql_error(connection), mysql_error(connection)); //输出错误信息
if( connection != NULL )
mysql_close(connection); //关闭数据库
exit(1);
}
void sigroutine(int signo)
{
MYSQL *my_con = malloc( sizeof(MYSQL) );
MYSQL_RES *my_res;
MYSQL_FIELD *my_field;
MYSQL_ROW my_row;
int rows, i;
int res;
mysql_init(my_con);
my_con = mysql_real_connect(my_con, "localhost", "root", "pfy",
"test", 0, NULL, CLIENT_FOUND_ROWS); //连接数据库并返回到my_con
if( NULL == my_con )
error_quit("Connection fail", my_con);//连接失败退出当前函数
res = mysql_query(my_con, "select * from mall_m_order where orderstate=0"); //查找未付款的交易记录
if( res != 0 )
error_quit("Select fail", my_con); //查询失败退出
my_res = mysql_store_result(my_con); //将查询结果返回
if( NULL == my_res )
error_quit("Get result fail", my_con);//获得结果失败
// rows = mysql_num_fields(my_res); //得到记录信息的列数
// my_field = mysql_fetch_fields(my_res); //获取记录的信息
// for(i=0; i<rows; i++)
// printf("%s\t", my_field[i].name); //输出列表名
while( 1 ) //循环输出各列表的信息
{
my_row = mysql_fetch_row(my_res); //获取一行状态信息
if( NULL == my_row )
break;
//if( my_row[0] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[0]); //输出 id
//if( my_row[12] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[12]); //输出提交订单时间
//if( my_row[13] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[13]); //输出订单状态
char *time=(char *)my_row[12];
if(judge(time))
{
//update 相应的信息
char ch[100];
sprintf(ch,"update mall_m_order set orderstate = 4 where id = %s",(char*)my_row[0]);
res = mysql_query(my_con, ch);
if( res != 0 )
error_quit("updated fail", my_con);
res = mysql_affected_rows(my_con);
printf("updated %d rows\n", res);
}
printf("\n");
}
mysql_free_result(my_res); //释放my_res占用空间
mysql_close(my_con); //关闭数据库
free(my_con); //free my_con
}
bool judge(char *ch) //判断时间是否过期函数定义 返回值:true:过期 false:未过期
{
bool flag=false; //初始订单状态为假,即未过期
timeinfo->tm_year+=1900; //当前时间的年份
timeinfo->tm_mon+=1; //当前时间的月份
int year=(ch[0]-'0')*1000+(ch[1]-'0')*100+(ch[2]-'0')*10+(ch[3]-'0');//提取提交订单的年份
int mon=(ch[5]-'0')*10+(ch[6]-'0'); //提取提交订单的月份
int day=(ch[8]-'0')*10+(ch[9]-'0'); //提取提交订单的日期
if(timeinfo->tm_year < year) flag = true; //过去年份的订单
if(timeinfo->tm_mon != mon) flag = true; //月份不同的订单,肯定超过24小时
if(timeinfo->tm_mday < day) flag = true; //日期不同的订单,也是过期
return flag; //返回订单时间判断状态
}
****************************************************************************
Ubuntu 12.04安装QQ2012,下载后请根据自己的机器类型,按照下面的32位或64位安装说明安装
新版本更新说明:
1.qq版本升级到官方最新qq2012Beta1
2.点击密码框不会崩溃
3.不会自动离线
4.支持全局热键(比如:Ctrl+Alt+A截图)
5.语音视频接受正常,本地视频无法使用
6.文件传输大小正常
已知问题:
1.窗口放到桌面边缘无法自动隐藏。
2.如果qq2012使用时发现没有声音或者遇到接收消息时qq僵死的情况,请手动安装更高版本的alsa-lib.(见常见问题一)
3.使用linux的显示桌面,或者使用Ctrl+Alt+z快捷键后切换了桌面的话,可能会导致qq面板无法唤出。
这时可以右键点击任务栏qq图标,选择锁定qq,就可以唤出主面板了。
4.关闭qq窗口可能会有残影,不过不影响使用。
1、到以下网址下载deb安装包,http://www.longene.org/download/qq2011-for-wine_20120220.deb,已经打包好的deb包,大小为150M左右;
最新发布 6-1 号更新的 :http://www.longene.org/download/WineQQ2012-20120531-Longene.deb 有几个bug 已经修补啦 !
2、打开终端输入到目录中运行命令安装:
sudo dpkg -i *.deb
3、64位系统还需要运行以下命令:
sudo apt-get install ia32-libs
4、卸载的话运行以下命令:
dpkg -r qq-for-wine
在Ubuntu 12.04下运行QQ2012截图如下:
一.如果qq使用时发现没有声音或者遇到接收消息时qq僵死的情况,按照下面安装高版本的slsa。
由于wine-1.4-rc2需要高版本的alsa-lib(>=1.0.22)版本,而Ubuntu自带的alsa-lib库版本太低,导致使用音频时可能会出现问题。
安装步骤:
1. 下载源码:
你可以去官网ftp://ftp.alsa-project.org/pub/lib/ 下载源码,下载高于1.0.22版本的alsa-lib。
注意:我们只测试过alsa-lib-1.0.24.1的版本,能正常运行(ftp://ftp.alsa-project.org/pub/lib/alsa-lib-1.0.24.1.tar.bz2)。 其他版本未作测试。
2.然后解压
tar -jxvf alsa-lib-1.0.24.1.tar.bz2
3.最后编译安装:
cd alsa-lib-1.0.24.1
./configure
make && make install
如果觉得麻烦,那可以试试我们已经编译好的alsa-lib。
下载:http://www.longene.org/download/alsa-lib-1.0.24.1.tar.bz2
安装方法很简单:
解压(tar -jxvf alsa-lib-1.0.24.1.tar.bz2),然后cd到解压开的文件夹,然后运行命令make install
由于桌面环境不一样,我们编译好的alsa-lib不一定所有机器都能用,如果不行请参考上面的方法去官网下载源码手动安装。
二.如果菜单无法前台显示,去掉qq设置 '始终保持在其他窗口前端' 前面的勾。
三.如果QQ无法使用ibus中文输入法,按修改下面文件后重启。
1).在/etc/profile文件最后添加
XMODIFIERS="@im=ibus"
XIM="ibus"
GTK_IM_MODULE="xim"
QT_IM_MODULE="xim"
ibus-daemon -d -x
2).把/etc/X11/xinit/xinput.d/ibus文件中的 XIM_ARGS="--xim" 改成 XIM_ARGS="-d -x"
更多Ubuntu相关信息见Ubuntu 专题页面 http://www.linuxidc.com/topicnews.aspx?tid=2
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2012-05/59564.htm
本篇文章来源于 Linux公社网站(www.linuxidc.com) 原文链接:http://www.linuxidc.com/Linux/2012-05/59564.htm
2013、6、28
在 MySQL 中,有三种主要的类型:文本、数字和日期/时间类型。
Text 类型:
数据类型 |
描述 |
CHAR(size) |
保存固定长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的长度。最多 255 个字符。 |
VARCHAR(size) |
保存可变长度的字符串(可包含字母、数字以及特殊字符)。在括号中指定字符串的最大长度。最多 255 个字符。 注释:如果值的长度大于 255,则被转换为 TEXT 类型。 |
TINYTEXT |
存放最大长度为 255 个字符的字符串。 |
TEXT |
存放最大长度为 65,535 个字符的字符串。 |
BLOB |
用于 BLOBs (Binary Large OBjects)。存放最多 65,535 字节的数据。 |
MEDIUMTEXT |
存放最大长度为 16,777,215 个字符的字符串。 |
MEDIUMBLOB |
用于 BLOBs (Binary Large OBjects)。存放最多 16,777,215 字节的数据。 |
LONGTEXT |
存放最大长度为 4,294,967,295 个字符的字符串。 |
LONGBLOB |
用于 BLOBs (Binary Large OBjects)。存放最多 4,294,967,295 字节的数据。 |
ENUM(x,y,z,etc.) |
允许你输入可能值的列表。可以在 ENUM 列表中列出最大 65535 个值。如果列表中不存在插入的值,则插入空值。 注释:这些值是按照你输入的顺序存储的。 可以按照此格式输入可能的值:ENUM('X','Y','Z') |
SET |
与 ENUM 类似,SET 最多只能包含 64 个列表项,不过 SET 可存储一个以上的值。 |
Number 类型:
数据类型 |
描述 |
TINYINT(size) |
-128 到 127 常规。0 到 255 无符号*。在括号中规定最大位数。 |
SMALLINT(size) |
-32768 到 32767 常规。0 到 65535 无符号*。在括号中规定最大位数。 |
MEDIUMINT(size) |
-8388608 到 8388607 普通。0 to 16777215 无符号*。在括号中规定最大位数。 |
INT(size) |
-2147483648 到 2147483647 常规。0 到 4294967295 无符号*。在括号中规定最大位数。 |
BIGINT(size) |
-9223372036854775808 到 9223372036854775807 常规。0 到 18446744073709551615 无符号*。在括号中规定最大位数。 |
FLOAT(size,d) |
带有浮动小数点的小数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DOUBLE(size,d) |
带有浮动小数点的大数字。在括号中规定最大位数。在 d 参数中规定小数点右侧的最大位数。 |
DECIMAL(size,d) |
作为字符串存储的 DOUBLE 类型,允许固定的小数点。 |
* 这些整数类型拥有额外的选项 UNSIGNED。通常,整数可以是负数或正数。如果添加 UNSIGNED 属性,那么范围将从 0 开始,而不是某个负数。
Date 类型:
数据类型 |
描述 |
DATE() |
日期。格式:YYYY-MM-DD 注释:支持的范围是从 '1000-01-01' 到 '9999-12-31' |
DATETIME() |
*日期和时间的组合。格式:YYYY-MM-DD HH:MM:SS 注释:支持的范围是从 '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59' |
TIMESTAMP() |
*时间戳。TIMESTAMP 值使用 Unix 纪元('1970-01-01 00:00:00' UTC) 至今的描述来存储。格式:YYYY-MM-DD HH:MM:SS 注释:支持的范围是从 '1970-01-01 00:00:01' UTC 到 '2038-01-09 03:14:07' UTC |
TIME() |
时间。格式:HH:MM:SS 注释:支持的范围是从 '-838:59:59' 到 '838:59:59' |
YEAR() |
2 位或 4 位格式的年。 注释:4 位格式所允许的值:1901 到 2155。2 位格式所允许的值:70 到 69,表示从 1970 到 2069。 |
* 即便 DATETIME 和 TIMESTAMP 返回相同的格式,它们的工作方式很不同。在 INSERT 或 UPDATE 查询中,TIMESTAMP 自动把自身设置为当前的日期和时间。TIMESTAMP 也接受不同的格式,比如 YYYYMMDDHHMMSS、YYMMDDHHMMSS、YYYYMMDD 或 YYMMDD。
/***********************************************************************************************************/
// 2013/6/29
// 潘风云
// 更改订单提交状态
// 编译: gcc updatedata.c -o updatedata -lmysqlclient
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <mysql/mysql.h> //数据库头文件
#include <unistd.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h> //系统时间头文件
#include <stdbool.h> //布尔类型头文件
typedef struct LIST{
char key_id[10]; //key的值代表产品id
char values[10]; //value代表订单中产品数量
struct LIST *next;
}List;
List *head; //结构体头结点
time_t rawtime;
struct tm *timeinfo; //时间信息结构体
List * jiequ(char *ch); //提取text变量中的数据
void error_quit(const char *str, MYSQL *connection); //遇到错误信息推出函数申明
void sigroutine(int signo); //修改状态值功能函数申明
bool judge(char *ch); //判断时间是否过期函数申明
void update_orderstate(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row); //将提交的订单状态设为取消订单
void returnjifen(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row); //返还积分
void returnyhq(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row); //返还优惠券
void returnlpk(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row); //返还礼品卡
void returnkc(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row); //返还库存
//void output(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row);
int main()
{
struct itimerval value, ovalue;
time ( &rawtime );
timeinfo = localtime ( &rawtime ); //获取当前时间
signal(SIGALRM, sigroutine); //设置信号处理函数指向
//当前运行时间值
value.it_value.tv_sec = 5; //设置秒数
value.it_value.tv_usec = 0; //设置微秒数
value.it_interval.tv_sec = 5;
value.it_interval.tv_usec = 0; //设置参数的时间段
setitimer(ITIMER_REAL, &value, &ovalue); //选择us级的ITIMER_REAL类型定时器
while(1) //循环
{
/*printf("value.it_value.tv_sec is %d",value.it_value.tv_sec);
printf ( "%4d-%02d-%02d %02d:%02d:%02d\n",1900+timeinfo->tm_year,
1+timeinfo->tm_mon,timeinfo->tm_mday,timeinfo->tm_hour,timeinfo->tm_min,timeinfo->tm_sec);*/
}
}
void error_quit(const char *str, MYSQL *connection) //遇到错误信息推出函数
{
fprintf(stderr, "%s : %s: %s\n", str, mysql_error(connection), mysql_error(connection)); //输出错误信息
if( connection != NULL )
mysql_close(connection); //关闭数据库
exit(1);
}
void sigroutine(int signo)
{
MYSQL *my_con = malloc( sizeof(MYSQL) ); //数据库
MYSQL_RES *my_res; //影响的记录数
MYSQL_FIELD *my_field; //数据库列名
MYSQL_ROW my_row; //数据库一行信息
int rows, i;
int res;
mysql_init(my_con);
my_con = mysql_real_connect(my_con, "localhost", "root", "pfy",
"test", 0, NULL, CLIENT_FOUND_ROWS); //连接数据库并返回到my_con
if( NULL == my_con )
error_quit("Connection fail", my_con);//连接失败退出当前函数
res = mysql_query(my_con, "select * from mall_m_order where orderstate=0"); //查找未付款的交易记录
if( res != 0 )
error_quit("Select fail", my_con); //查询失败退出
my_res = mysql_store_result(my_con); //将查询结果返回
if( NULL == my_res )
error_quit("Get result fail", my_con);//获得结果失败
// rows = mysql_num_fields(my_res); //得到记录信息的列数
// my_field = mysql_fetch_fields(my_res); //获取记录的信息
// for(i=0; i<rows; i++)
// printf("%s\t", my_field[i].name); //输出列表名
while( 1 ) //循环输出各列表的信息
{
my_row = mysql_fetch_row(my_res); //获取一行状态信息
if( NULL == my_row )
break;
//if( my_row[0] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[0]); //输出 id
//if( my_row[12] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[12]); //输出提交订单时间
//if( my_row[13] == NULL )
// printf("NULL\t");
//else
// printf("%s\t", (char*)my_row[13]); //输出订单状态
char *time=(char *)my_row[12];
if(judge(time))
{
//update 相应的信息
update_orderstate(my_con, my_res, my_row);//设置订单状态
if(NULL!=my_row[11])
{
returnjifen(my_con, my_res, my_row); //积分卡
//usejifen = NULL;
}
if(NULL!=my_row[26])
{
returnyhq(my_con, my_res, my_row); //优惠券
//card = NULL;
}
if(NULL!=my_row[27])
{
returnlpk(my_con, my_res, my_row); //礼品卡
//gfcard = NULL;
}
returnkc(my_con, my_res, my_row); //库存
}
printf("\n");
}
mysql_free_result(my_res); //释放my_res占用空间
mysql_close(my_con); //关闭数据库
free(my_con); //free my_con
}
bool judge(char *ch) //判断时间是否过期函数定义 返回值:true:过期 false:未过期
{
bool flag=false; //初始订单状态为假,即未过期
timeinfo->tm_year+=1900; //当前时间的年份
timeinfo->tm_mon+=1; //当前时间的月份
int year=(ch[0]-'0')*1000+(ch[1]-'0')*100+(ch[2]-'0')*10+(ch[3]-'0');//提取提交订单的年份
int mon=(ch[5]-'0')*10+(ch[6]-'0'); //提取提交订单的月份
int day=(ch[8]-'0')*10+(ch[9]-'0'); //提取提交订单的日期
if(timeinfo->tm_year < year) flag = true; //过去年份的订单
if(timeinfo->tm_mon != mon) flag = true; //月份不同的订单,肯定超过24小时
if(timeinfo->tm_mday > day) flag = true; //日期不同的订单,也是过期
return flag; //返回订单时间判断状态
}
void update_orderstate(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)//将提交的订单状态设为取消订单
{
char ch[100];
sprintf(ch,"update mall_m_order set orderstate = 4 where id = %s",(char*)my_row[0]);
int res = mysql_query(my_con, ch);
if( res != 0 )
error_quit("updated fail", my_con);
res = mysql_affected_rows(my_con);
printf("updated %d rows\n", res);
}
void returnjifen(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)//返还积分
{
char ch[100];
sprintf(ch,"select * from mall_jifenlog where id = %s",(char*)my_row[11]);
int res = mysql_query(my_con,ch); //查找要返还积分的记录
if( res != 0 )
error_quit("Select fail", my_con); //查询失败退出
my_res = mysql_store_result(my_con); //将查询结果返回
if( NULL == my_res )
error_quit("Get result fail", my_con);//获得结果失败
my_row = mysql_fetch_row(my_res); //获取一行状态信息
if( NULL == my_row )
return;
char *PFY_uid=(char *)my_row[1]; //得到记录的uid
char *PFY_expendjifen=(char *)my_row[3]; //得到要返还的积分数
sprintf(ch,"delete mall_jifenlog where id = %s",(char*)my_row[0]);
res = mysql_query(my_con,ch); //删除取消订单的积分记录
if( res != 0 )
error_quit("delete fail", my_con); //删除失败退出
sprintf(ch,"update mall_m_member set jifen + %ld where id = %s",atol(PFY_expendjifen),PFY_uid);
res = mysql_query(my_con,ch); //修改客户的积分数
if( res != 0 )
error_quit("Select fail", my_con); //修改失败退出
res = mysql_affected_rows(my_con);
printf("updated mall_jifenlog %d rows\n", res);
}
void returnyhq(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)//返还优惠券
{
char ch[100];
sprintf(ch,"update mall_m_card set state=0,usedtime=NULL,orderid=NULL,ip=NULL where id = %s",(char*)my_row[26]);
int res = mysql_query(my_con, ch);
if( res != 0 )
error_quit("updated fail", my_con);
res = mysql_affected_rows(my_con);
printf("updated %d rows\n", res);
/*MYSQL_RES *my_res = mysql_store_result(my_con);
int rows = mysql_num_fields(my_res);
my_field = mysql_fetch_fields(my_res);*/
}
void returnlpk(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)//返还礼品卡
{
char ch[100];
sprintf(ch,"update mall_gift_card set state=0,usedtime=NULL,orderid=NULL where id = %s",(char*)my_row[27]);
int res = mysql_query(my_con, ch);
if( res != 0 )
error_quit("updated fail", my_con);
res = mysql_affected_rows(my_con);
printf("updated %d rows\n", res);
}
List * jiequ(char *ch) //截取test变量中有用的数据
{
int index,num=0;
head=(List *)malloc(sizeof(List));
strcpy(head->key_id,"");
strcpy(head->values,"");
head->next = NULL;
List *q=head;
index=2;
do{
num=num*10+(ch[index]-'0');
index++;
}while(ch[index] >= '0'&&ch[index] <= '9');
printf("num=%d\n",num);
char temp[2]="";
int i=0;
while(i<num)
{
List *p=(List *)malloc(sizeof(List));
strcpy(p->key_id,"");
strcpy(p->values,"");
p->next=NULL;
while(ch[index]!='|')
index++;
index++;
while(ch[index] >= '0'&&ch[index] <= '9')
{
temp[0]=ch[index];
strcat(p->key_id,temp);
index++;
}
index+=2;
if(ch[index]=='i')
{
index+=2;
while(ch[index] >= '0'&&ch[index] <= '9')
{
temp[0]=ch[index];
strcat(p->values,temp);
index++;
}
}
else if(ch[index]=='s')
{
while(ch[index]!='\"')
index++;
index++;
while(ch[index] >= '0'&&ch[index] <= '9')
{
temp[0]=ch[index];
strcat(p->values,temp);
index++;
}
}
else{
//p->values=NULL;
printf("it have no number");
}
while(ch[index]!=';')index++;
q->next = p;
q=p;
i++;
}
return head;
}
void returnkc(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)//返还库存
{
int res;
char ch[100];
char *text=(char *)my_row[8];
printf("text: %s\n",text);
List *list=jiequ(text);
List *p=list->next;
while(p!=NULL)
{
sprintf(ch,"update mall_jm_gg set kc=kc+%s where id = %s",p->values,p->key_id);
printf("sql: %s\n",ch);
res = mysql_query(my_con, ch);
if( res != 0 )
error_quit("updated fail", my_con);
res = mysql_affected_rows(my_con);
printf("updated %d rows\n", res);
p=p->next;
}
}
/*
void output(MYSQL *my_con,MYSQL_RES *my_res,MYSQL_ROW my_row)
{
for(i=0; i<rows; i++)
printf("%s\t", my_field[i].name);
printf("\n-------------------------------------\n\n");
while( 1 )
{
my_row = mysql_fetch_row(my_res);
if( NULL == my_row )
break;
for(i=0; i<rows; i++)
{
if( my_row[i] == NULL )
printf("NULL\t");
else
printf("%s\t", (char*)my_row[i]);
}
printf("\n");
}
printf("\n-------------------------------------\n");
}
*/
/***********************************************************************************************/
每个开发人员都应该知道的8个Linux命令
每个开发人员到了他们职业人生的某个阶段的时候,将会发现自己要寻找有关Linux的信息。我并不是这方面的专家。但是掌握了以下8个命令,我几乎可以得到我任何需要的东西。
注意:以下的命令都有很多扩展的文档,博客里提出的知识我最常用的命令,用法。如果你不了解Linux命令,这个帖子会给你一点指导。
我们以一些文本举例。假设我们有2个文件,里面有订单关于第三方的放置地点和发送回应。
order.out.log
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:23:45 112, 1, Joy of Clojure, Hardcover, 29.99
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
order.in.log
8:22:20 111, Order Complete
8:23:50 112, Order sent to fulfillment
8:24:20 113, Refund sent to processing
cat
–追加文件并在标准输出上打印
jfields$ cat order.out.log
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:23:45 112, 1, Joy of Clojure, Hardcover, 29.99
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
正如他的名字所说的,你可以串联多个文件39鼻炎网http://www.39byw.com
jfields$ cat order.*
8:22:20 111, Order Complete
8:23:50 112, Order sent to fulfillment
8:24:20 113, Refund sent to processing
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:23:45 112, 1, Joy of Clojure, Hardcover, 29.99
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
看到效果了,但我们可以提高其可读性。
sort
–对文本文件进行行排序,这里使用排序是不错的选择
jfields$ cat order.* | sort
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:22:20 111, Order Complete
8:23:45 112, 1, Joy of Clojure, Hardcover, 29.99
8:23:50 112, Order sent to fulfillment
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:24:20 113, Refund sent to processing
上面显示了我们想要看到的效果,但是这只是小文件。而真实的数据是很大的,有些是你不想要的数据怎么办?
grep
grep, egrep, fgrep–进行匹配输出
假设我只关心给PofEAA的订单,使用grep就可以做到。
jfields$ cat order.* | sort | grep Patterns
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
假设订单113里面发生了一些问题,你想看到关于113的所有订单信息。没错,grep能帮你。
jfields$ cat order.* | sort | grep ":\d\d 113,"
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:24:20 113, Refund sent to processing39鼻炎网http://www.39byw.com
你会发现在表达式里面不止有113,这是因为113也可能出现在价格里面,或者产品里面,这样做是严格限制其查找结果。
现在我们已经发出退货订单的信息,我们每日也要给会计发送销售统计。他们要求每个PofEAA的项目,但他们只关心数量和价格,我们要把
不需要的部分删减掉。
cut
–从文件的每一行删除一部分
还是要先使用grep。
jfields$ cat order.* | sort | grep Patterns
8:22:19 111, 1, Patterns of Enterprise Architecture, Kindle edition, 39.99
8:24:19 113, -1, Patterns of Enterprise Architecture, Kindle edition, 39.99
jfields$ cat order.* | sort | grep Patterns | cut -d"," -f2,5
1, 39.99
-1, 39.99
我们已经减少了数据,让会计一目了然。
假设会计想要把订单ID做为参考,把它放在每一行的最后,并用单引号。
sed
–流编辑器。用来处理文本转换。
下面的示例演示怎样使用它来做到我们想要的数据。
jfields$ cat order.* | sort | grep Patterns \
>| sed s/"[0-9\:]* \([0-9]*\)\, \(.*\)"/"\2, '\1'"/
1, Patterns of Enterprise Architecture, Kindle edition, 39.99, '111'
-1, Patterns of Enterprise Architecture, Kindle edition, 39.99, '113'
lmp-jfields01:~ jfields$ cat order.* | sort | grep Patterns \
>| sed s/"[0-9\:]* \([0-9]*\)\, \(.*\)"/"\2,'\1'"/ | cut -d"," -f1,4,5
1, 39.99,'111'
-1, 39.99, '113'
这是一个正则表达式,但没什么复杂的。做以下事情
1.删除时间
2.捕获订单号
3.删除逗号和订单号后面的空格
4.捕获此行的其余部分
一旦我们看到了我们需要的数据,可以使用\1&\2让输出数据符合我们的格式要求。
uniq
–去除重复行
下面的示例演示如何grep的唯一相关的交易,削减不必要的信息,并获得计数。
jfields$ cat order.out.log | grep "\(Kindle\|Hardcover\)" | cut -d"," -f3 | sort | uniq -c
1 Joy of Clojure
2 Patterns of Enterprise Architecture
jfields$ cat order.out.log | grep "\(Kindle\|Hardcover\)" | cut -d"," -f3 | sort | uniq
Joy of Clojure
Patterns of Enterprise Architecture
find
–在目录里找文件
假设这2个文本文件存在于我们的主目录,我们不必知道他们的全名。
jfields$ find /Users -name "order*"
Users/jfields/order.in.log
Users/jfields/order.out.log
当然还有很多选项,但99%的情况下我这么做。
less
–在一个文件里面向前向后移动
让我们回到最简单的cat|sort的例子。你可以向前搜索使用”/”,向后使用”?”,2者都可以使用正则表达式。
jfields$ cat order* | sort | less39鼻炎网http://www.39byw.com
你可以试试/113.*,这将突出显示订单113。你可以使用?.*112,也将突出显示订单112,你可以用’q‘退出。
Linux命令很丰富,有些人很头疼。这几个命令应该能帮你完成大部分的文本工作,不用交到你的脚本语言手里。
在开始之前我说一下我的环境,eclipse版本eclipse-java-indigo-SR2-win32-x86_64,操作系统Win7,但是这个基本上没有影响。红字的那个注意一下,在下面需要根据这个选择地址
打开地址http://www.eclipse.org/babel/downloads.php
根据你所下载的Eclipse版本选择下面的地址,复制备用
打开Eclipse—>Help—>Install New Software…
把刚刚复制的地址粘贴进去
点击 Add… ,给Name,起个名字
点击OK,你会发现,程序没有反应了,不并不是会发现Eclipse右下角有这么个情况,
这个是在加载语言列表,根据网速而定,我4M的带宽,不到十分钟。完成后会出现下面的对话框
选择…in Chinese (Simplified) 也就是简体中文,下面挨着的那个是繁体的,英语好的就不用我说……
接着点击 Next>
继续 Next>
这个不用说,你必须得点击那个 I accept the……, 然后点击Finish,接着会出来下面的的对话框,等着就是了
不一会儿,当然得看你的网速情况了,这个就好了,中间会让你点击一次OK,我忘记截图了,然后重启Eclipse就好了,再次打开,你也许会感觉到亲切了,中文啊……
好了,到此结束,祝你好运!有什么疏漏之处请大家多多指教。
2013、7、6
2011-07-18 06:05
Android中Handler的作用
* Handler的定义:
* 主要接受子线程发送的数据, 并用此数据配合主线程更新UI。当应用程序启动时,
* Android首先会开启一个主线程 (也就是UI线程) , 主线程为管理界面中的UI控件,进行事件分发, 比如说,
* 你要是点击一个 Button ,Android会分发事件到Button上,来响应你的操作。
* 如果此时需要一个耗时的操作,例如: 联网读取数据,或者读取本地较大的一个文件的时候,你不能把这些操作放在主线程中,
* 如果你放在主线程中的话,界面会出现假死现象, 如果5秒钟还没有完成的话,会收到Android系统的一个错误提示 "强制关闭"。
* 这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是线程不安全的,
* 也就是说,更新UI只能在主线程中更新,子线程中操作是危险的。这个时候,Handler就出现了,来解决这个复杂的问题 ,
* 由于Handler运行在主线程中(UI线程中),它与子线程可以通过Message对象来传递数据,
* 这个时候,Handler就承担着接受子线程传过来的(子线程用sedMessage()方法传弟)Message对象(里面包含数据),把这些消息放入主线程队列中,配合主线程进行更新UI。* Handler一些特点:
* Handler可以分发Message对象和Runnable对象到主线程中, 每个Handler实例,都会绑定到创建他的线程中(一般是位于主线程),
* 它有两个作用: (1): 安排消息或Runnable 在某个主线程中某个地方执行, (2)安排一个动作在不同的线程中执行
* Handler中分发消息的一些方法
* post(Runnable)
* postAtTime(Runnable,long)
* postDelayed(Runnable,long)
* sendEmptyMessage(int)
* sendMessage(Message)
* sendMessageAtTime(Message,long)
* sendMessageDelayed(Message,long)
* 以上post类方法允许你排列一个Runnable对象到主线程队列中,当需要在不同于主UI线程中执行则需要配合HandlerThread进行使用:
* HandlerThread handlerThread = new HandlerThread("myHandlerThread");
* handlerThread.start();
* handler = new Handler(handlerThread.getLooper());
* sendMessage类方法, 允许你安排一个带数据的Message对象到队列中,等待更新.
* @author xiaoshuang
*
*/
public class HandlerActivity extends Activity {
private TextView textView;
private MyHandler myHandler;
private Button button;
private ProgressBar progressBar;
private MyThread m=new MyThread();
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textView=(TextView)findViewById(R.id.text);
button=(Button)findViewById(R.id.startButton);
progressBar=(ProgressBar)findViewById(R.id.bar);
progressBar.setMax(100);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
myHandler=new MyHandler();
new Thread(m).start();
System.out.println("onCreate--The Thread is: "+Thread.currentThread().getId());
}
});
}
//在对UI进行更新时,执行时所在的线程为主UI线程
class MyHandler extends Handler{//继承Handler类时,必须重写handleMessage方法
public MyHandler(){
}
public MyHandler(Looper l){
super(l);
}
@Override
public void handleMessage(Message msg) {//执行接收到的通知,此时执行的顺序是按照队列进行,即先进先出
System.out.println("Handler--The ThreadId is: "+Thread.currentThread().getId());
super.handleMessage(msg);
Bundle b=msg.getData();
String textStr0=textView.getText().toString();
String textStr1=b.getString("textStr");
HandlerActivity.this.textView.setText(textStr0+" "+textStr1);//更改TextView中的值
int barValue=b.getInt("barValue");
HandlerActivity.this.progressBar.setProgress(barValue);//更改进度条当中的值
}
}
//该线程将会在单独的线程中运行
class MyThread implements Runnable{
int i=1;
@Override
public void run() {
while(i<11){
System.out.println("Thread--The ThreadId is: "+Thread.currentThread().getId());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Message msg=new Message();
Bundle b=new Bundle();
b.putString("textStr", "线程运行"+i+"次");
b.putInt("barValue", i*10);
i++;
msg.setData(b);
HandlerActivity.this.myHandler.sendMessage(msg);//通过sendMessage向Handler发送更新UI的消息
}
}
}
}
2013、7、8
01 public Bitmap convertToBitmap(String path, int w, int h) {
02 BitmapFactory.Options opts = new BitmapFactory.Options();
03 // 设置为ture只获取图片大小
04 opts.inJustDecodeBounds = true;
05 opts.inPreferredConfig = Bitmap.Config.ARGB_8888;
06 // 返回为空
07 BitmapFactory.decodeFile(path, opts);
08 int width = opts.outWidth;
09 int height = opts.outHeight;
10 float scaleWidth = 0.f, scaleHeight = 0.f;
11 if (width > w || height > h) {
12 // 缩放
13 scaleWidth = ((float) width) / w;
14 scaleHeight = ((float) height) / h;
15 }
16 opts.inJustDecodeBounds = false;
17 float scale = Math.max(scaleWidth, scaleHeight);
18 opts.inSampleSize = (int)scale;
19 WeakReference<Bitmap> weak = new WeakReference<Bitmap>(BitmapFactory.decodeFile(path, opts));
20 return Bitmap.createScaledBitmap(weak.get(), w, h, true);
21 }
其中w和h你需要转换的大小
path转换为bitmap:上面方法即可;
imageview获取drawable并转换为 bitmap :Bitmap bt= ((BitmapDrawable) mImageview.getDrawable()).getBitmap();
resourceid转换为bitmap:Bitmap bt = BitmapFactory.decodeResource(getResources(), R.drawable.resourceid);
Drawable转换为bitmap:Bitmap bt= ((BitmapDrawable) Drawable).getBitmap();
因为BitmapDrawable是继承Drawable,所以可以灵活的转换
2013、7、9
Android gallery实现图片的左右循环旋转源码分享
gallery
三步走:第一步初始化gallery时设置较大的初始化位置 Gallery gallery = ((Gallery) findViewById(R.id.myGallery1)); gallery.setAdapter(new ImageAdapter(this)); gallery.setSelection(200); 第二步:重写 BaseAdapter方法中的getCount时返回一个较大的值: // 为了使资源循环使用 public int getCount() { return Integer.MAX_VALUE; } 第三步:重写BaseAdapter时使用用position对集合大小取余的值,如下: /* 取得目前欲显示的图像View,传入数组ID值使之读取与成像 */ public View getView(int position, View convertView, ViewGroup parent) { /* 创建一个ImageView对象 */ ImageView i = new ImageView(this.myContext); i.setPadding(10, 10, 10, 10); i.setAlpha(80); // i.setImageResource(this.myImageIds[position]); if(position<0){ position =position+myImageIds.length; } i.setImageResource(this.myImageIds[position% myImageIds.length]); i.setScaleType(ImageView.ScaleType.FIT_XY); i.setBackgroundResource(mGalleryItemBackground); /* 设置这个ImageView对象的宽高,单位为dip */ i.setLayoutParams(new Gallery.LayoutParams(85, 72)); return i; } 以下是该类的完整代码: /* 依据距离中央的位移量 利用getScale返回views的大小(0.0f to 1.0f) */
- package irdc.ex03_15;
- import android.app.Activity;
- import android.content.Context;
- import android.content.res.TypedArray;
- import android.os.Bundle;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.BaseAdapter;
- import android.widget.Gallery;
- import android.widget.ImageView;
- import android.widget.TextView;
- import android.widget.Toast;
- import android.widget.AdapterView.OnItemSelectedListener;
- public class EX03_15 extends Activity
- {
- private TextView mTextView01;
- @Override
- public void onCreate(Bundle savedInstanceState)
- {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- Gallery gallery = ((Gallery) findViewById(R.id.myGallery1));
- gallery.setAdapter(new ImageAdapter(this));
- gallery.setSelection(200);
-
- gallery.setOnItemSelectedListener(new OnItemSelectedListener()
- {
- public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2,
- long arg3)
- {
- Toast.makeText(EX03_15.this, "当前位置:" + arg2, Toast.LENGTH_SHORT).show();
- }
- public void onNothingSelected(AdapterView<?> arg0)
- {
- }
- });
- }
- public class ImageAdapter extends BaseAdapter
- {
- /* 类成员 myContext为Context父类 */
- private Context myContext;
- /*声明GalleryItemBackground*/
- int mGalleryItemBackground;
- /* 使用android.R.drawable里的图片作为图库来源,类型为整数数组 */
- private int[] myImageIds =
- { R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4,
- R.drawable.a5, R.drawable.a27 };
- /* 构造器只有一个参数,即要存储的Context */
- public ImageAdapter(Context c)
- {
- myContext = c;
- /*
- * 使用在res/values/attrs.xml中的<declare-styleable>定义 的Gallery属性.
- */
- TypedArray a = obtainStyledAttributes(R.styleable.Gallery);
- /* 取得Gallery属性的Index id */
- mGalleryItemBackground = a.getResourceId(
- R.styleable.Gallery_android_galleryItemBackground, 0);
- /* 让对象的styleable属性能够反复使用 */
- a.recycle();
- }
- /* 返回所有已定义的图片总数量 */
- // public int getCount() { return this.myImageIds.length; }
- // 为了使资源循环使用
- public int getCount()
- {
- return Integer.MAX_VALUE;
- }
- /* 利用getItem方法,取得目前容器中图像的数组ID */
- public Object getItem(int position)
- {
- return position;
- }
- public long getItemId(int position)
- {
- return position;
- }
- /* 取得目前欲显示的图像View,传入数组ID值使之读取与成像 */
- public View getView(int position, View convertView, ViewGroup parent)
- {
- /* 创建一个ImageView对象 */
- ImageView i = new ImageView(this.myContext);
- i.setPadding(10, 10, 10, 10);
- i.setAlpha(80);
- // i.setImageResource(this.myImageIds[position]);
- if(position<0){
- position =position+myImageIds.length;
- }
- i.setImageResource(this.myImageIds[position% myImageIds.length]);
- i.setScaleType(ImageView.ScaleType.FIT_XY);
- i.setBackgroundResource(mGalleryItemBackground);
- /* 设置这个ImageView对象的宽高,单位为dip */
- i.setLayoutParams(new Gallery.LayoutParams(85, 72));
- return i;
- }
- /* 依据距离中央的位移量 利用getScale返回views的大小(0.0f to 1.0f) */
- public float getScale(boolean focused, int offset)
- {
- return Math.max(0, 1.0f / (float) Math.pow(2, Math.abs(offset)));
- }
- }
- }
|
android评分条RatingBar自定义设置
RatingBar 自定义风格 评分条
RatingBar为评分条控件,默认效果为若干个绿色的星星,如果想将其换成其他自定义图片就要自定义它的style。首先是布局文件:
- <RatingBar android:id="@+id/app_ratingbar" style="@style/MyRatingBar"
- android:layout_marginTop="4dip" android:layout_width="wrap_content"
- android:layout_height="wrap_content" android:numStars="5"
- android:isIndicator="true" android:rating="5" />
<RatingBar android:id="@+id/app_ratingbar" style="@style/MyRatingBar"
android:layout_marginTop="4dip" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:numStars="5"
android:isIndicator="true" android:rating="5" />
其中android:numStars="5"设置显示的星星数量为5; android:rating="5"设置选中的数量为5,也就是全部选中
android:isIndicator="true"设置评分条只显示结果无法通过点击改变选中状态。
然后在res/values目录下建立styles.xml文件 代码:
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <style name="MyRatingBar" parent="@android:style/Widget.RatingBar">
- <item name="android:progressDrawable">@drawable/food_rating_bar_full</item>
- <item name="android:minHeight">15dip</item>
- <item name="android:maxHeight">15dip</item>
- </style>
- </resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="MyRatingBar" parent="@android:style/Widget.RatingBar">
<item name="android:progressDrawable">@drawable/food_rating_bar_full</item>
<item name="android:minHeight">15dip</item>
<item name="android:maxHeight">15dip</item>
</style>
</resources>
android:progressDrawable为评分条图案。接下来在res/drawable目录下建立food_rating_bar_full.xml文件
代码:
- <?xml version="1.0" encoding="utf-8"?>
- <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
- <item android:id="@+android:id/background"
- android:drawable="@drawable/rating" />
- <item android:id="@+android:id/secondaryProgress"
- android:drawable="@drawable/rating" />
- <item android:id="@+android:id/progress"
- android:drawable="@drawable/rating_show" />
- </layer-list>
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+android:id/background"
android:drawable="@drawable/rating" />
<item android:id="@+android:id/secondaryProgress"
android:drawable="@drawable/rating" />
<item android:id="@+android:id/progress"
android:drawable="@drawable/rating_show" />
</layer-list>
<item android:id="@+android:id/progress" android:drawable="@drawable/rating_show" />为设置评分图案为 rating_show.png,也就是选中时的图案;
<item android:id="@+android:id/background" android:drawable="@drawable/rating" /> 为设置背景图案为 rating.png,也就是为选中时的图案。
2013、7、10
0
从中间删除确实会有问题,我的解法是这样:将所有标签放到一个数组中mytabviewlist,每次删除一个标签的时候,先删除所有标签clearAllTabs,然后在数组中remove真正要删除的那个标签,最后对for循环数组addTab重新生成标签:
- if (tabwidget.getChildCount() > 0)
- {
- int location = tabhost.getCurrentTab();
- tabhost.setCurrentTab(0);
- tabhost.clearAllTabs();
-
- mytabviewlist.remove(location);
-
- for (int j =0; j < mytabviewlist.size(); j++)
- {
- tabhost.addTab(tabhost.newTabSpec("tab" + j).setIndicator(mytabviewlist.get(j)).setContent(Mytabfirst.this));
- tabhost.setCurrentTab(j);
- }
- }
if (tabwidget.getChildCount() > 0)
{
int location = tabhost.getCurrentTab();
tabhost.setCurrentTab(0);
tabhost.clearAllTabs();
// 找到删除的tab从数组中删除
mytabviewlist.remove(location);
// 重新生成tabhost
for (int j = 0; j < mytabviewlist.size(); j++)
{
tabhost.addTab(tabhost.newTabSpec("tab" + j).setIndicator(mytabviewlist.get(j)).setContent(Mytabfirst.this));
tabhost.setCurrentTab(j);
}
}
Android 动态添加textview组件和imageview组件 [复制链接] |
gzxk
当前离线
-
在线时间
-
0 小时
-
e望
-
0 点
-
最后登录
-
2011-12-9
-
注册时间
-
2011-5-30
-
积分
-
339
-
阅读权限
-
30
-
UID
-
507796
升级 9.75%
-
精华
-
0
-
帖子
-
69
-
e币
-
153 元
|
电梯直达
楼主
发表于 2011-10-11 15:55:43
| 只看该作者
| 倒序浏览
java代码:
- import android.app.Activity;
- import android.os.Bundle;
- import android.view.Gravity;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.AdapterView;
- import android.widget.BaseAdapter;
- import android.widget.Gallery;
- import android.widget.ImageView;
- import android.widget.LinearLayout;
- import android.widget.ListView;
- import android.widget.TextView;
- import android.widget.AdapterView.OnItemClickListener;
- import android.widget.AdapterView.OnItemSelectedListener;
- public class Sample_5_4 extends Activity {
- //所有资源图片(andy、bill、edgar、torvalds、turing)id的数组
- int[] drawableIds=
- {R.drawable.andy,R.drawable.bill,R.drawable.edgar,R.drawable.torvalds,R.drawable.turing};
- //所有资源字符串(andy、bill、edgar、torvalds、turing)id的数组
- int[] msgIds={R.string.andy,R.string.bill,R.string.edgar,R.string.torvalds,R.string.turing};
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- ListView lv=(ListView)this.findViewById(R.id.ListView01);//初始化ListView
- BaseAdapter ba=new BaseAdapter(){//为ListView准备内容适配器
- public int getCount() {return 5;}//总共5个选项
- public Object getItem(int arg0) { return null; }
- public long getItemId(int arg0) { return 0; }
- public View getView(int arg0, View arg1, ViewGroup arg2) {
- //动态生成每个下拉项对应的View,每个下拉项View由LinearLayout
- //中包含一个ImageView及一个TextView构成
- LinearLayout ll=new LinearLayout(Sample_5_4.this);//初始化LinearLayout
- ll.setOrientation(LinearLayout.HORIZONTAL); //设置朝向
- ll.setPadding(5,5,5,5);//设置四周留白
- ImageView ii=new ImageView(Sample_5_4.this);//初始化ImageView
- ii.setImageDrawable(getResources().getDrawable(drawableIds[arg0]));//设置图片
- ii.setScaleType(ImageView.ScaleType.FIT_XY);
- ii.setLayoutParams(new Gallery.LayoutParams(100,98));
- ll.addView(ii);//添加到LinearLayout中
- TextView tv=new TextView(Sample_5_4.this);//初始化TextView
- tv.setText(getResources().getText(msgIds[arg0]));//设置内容
- tv.setTextSize(24);//设置字体大小
- tv.setTextColor(Sample_5_4.this.getResources().getColor(R.color.white));//设置字体颜色
- tv.setPadding(5,5,5,5);//设置四周留白
- tv.setGravity(Gravity.LEFT);
- ll.addView(tv);//添加到LinearLayout中
- return ll;
- }
- };
- lv.setAdapter(ba);//为ListView设置内容适配器
- lv.setOnItemSelectedListener(//设置选项选中的监听器
- new OnItemSelectedListener(){
- public void onItemSelected(AdapterView<?> arg0, View arg1,
- int arg2, long arg3) {//重写选项被选中事件的处理方法
- TextView tv=(TextView)findViewById(R.id.TextView01);//获取主界面TextView
- LinearLayout ll=(LinearLayout)arg1;//获取当前选中选项对应的LinearLayout
- TextView tvn=(TextView)ll.getChildAt(1);//获取其中的TextView
- StringBuilder sb=new StringBuilder();//用StringBuilder动态生成信息
- sb.append(getResources().getText(R.string.ys));
- sb.append(":");
- sb.append(tvn.getText());
- String stemp=sb.toString();
- tv.setText(stemp.split("\\n")[0]);//信息设置进主界面TextView
- }
- public void onNothingSelected(AdapterView<?> arg0){}
- }
- );
- lv.setOnItemClickListener(//设置选项被单击的监听器
- new OnItemClickListener(){
- public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
- long arg3) {//重写选项被单击事件的处理方法
- TextView tv=(TextView)findViewById(R.id.TextView01);//获取主界面TextView
- LinearLayout ll=(LinearLayout)arg1;//获取当前选中选项对应的LinearLayout
- TextView tvn=(TextView)ll.getChildAt(1);//获取其中的TextView
- StringBuilder sb=new StringBuilder();//用StringBuilder动态生成信息
- sb.append(getResources().getText(R.string.ys));
- sb.append(":");
- sb.append(tvn.getText());
- String stemp=sb.toString();
- tv.setText(stemp.split("\\n")[0]);//信息设置进主界面TextView
- }
- }
- );
- }
- }
复制代码
java代码:
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <TextView
- android:id="@+id/TextView01"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:textSize="24dip"
- android:textColor="@color/white"
- android:text="@string/hello"/>
- <ListView
- android:id="@+id/ListView01"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:choiceMode="singleChoice"/>
- </LinearLayout>
|
|
2013、7、19
google-gson使用及GsonBuilder设置
阅读10次 2013/7/3 10:34:27
Json是一种类似于 XML的通用 数据交换格式,具有比XML更高的传输效率.
从结构上看,所有的数据(data)最终都可以分解成三种类型:
第一种类型是标量(scalar),也就是一个单独的字符串(string)或数字(numbers),比如"北京"这个单独的词。
第二种类型是序列(sequence),也就是若干个相关的数据按照一定顺序并列在一起,又叫做数组(array)或列表(List),比如"北京,上海"。
第三种类型是映射(map ping),也就是一个名/值对(Name/value),即数据有一个名称,还有一个与之相对应的值,这又称作散列(hash)或字典(dictionary),比如"首都:北京"。
Json的规格非常简单,只用一个页面几百个字就能说清楚,而且Douglas Crockford声称这个规格永远不必升级,因为该规定的都规定了。
1) 并列的数据之间用逗号(",")分隔。
2) 映射用冒号(":")表示。
3) 并列数据的集合(数组)用方括号("[]")表示。
4) 映射的集合(对象)用大括号("{}")表示。
-----------------------------------------------------------------
最快速入门贴:
1. 对象的序列化和反序列化
Type listType = new TypeToken<List<String>>() {}.getType();
List<String> target = new LinkedList<String>();
target.add("blah");
Gson gson = new Gson();
String json = gson.toJson(target, listType);
List<String> target2 = gson.fromJson(json, listType);
OK,最简方案打完收工.
2.使用GsonBuilder.
GsonBuilder用来生成Gson对象. 规定Gson的序列化和返序列化时的格式等内容.
如:
Gson gson = new GsonBuilder()
.registerTypeAdapter(Id.class, new IdTypeAdapter())
.enable ComplexMapKeySerialization()
.serializeNulls()
.setDateFormat(DateFormat.LONG)
.setFieldNamingPolicy(FieldNamingPolicy.UPPER_CAMEL_CASE)//会把字段首字母大写
.setPrettyPrinting()
.setVersion(1.0)
.create();
3. 使用注解,定制序列化字段.
默认情况下@Expose注解是不起作用的,除非你用GsonBuilder创建Gson的时候调用了GsonBuilder.excludeFieldsWithoutExposeAnnotation()方法
来个例子:
public class User {
@Expose private String firstName;
@Expose(serialize = false) private String lastName;
@Expose (serialize = false, deserialize = false)
private String emailAddress;
private String password;
}
如果你创建Gson对象的时候使用的是new Gson(),toJson()和fromJson()方法将会对全部的字段生效.但是如果你使用的是GsonBuilder并且调用了excludeFieldsWithoutExposeAnnotation()方法.那么:toJson()和fromJson()将不会包括password.因为password没有包含@Expose注解.
序列化的时候将不包括 lastName和emailAddress,因为注解中标明不进行序列化.同样的道理,反序列化时将不包括emailAddress.
注:如果仅仅是想把某些特定的字段包含在外和话,可以使用transient 关键字声明字段.
4. 使用注解对序列化名称进行声明
这个简单,上例子都能懂,不解释:
public class SomeClassWithFields {
@SerializedName("name")
private final String someField;
private final String someOtherField;
public SomeClassWithFields(String a, String b) {
this.someField = a;
this.someOtherField = b;
}
}
===== OUTPUT =====
{"name":"a","someOtherField":"b"}
5. 例用注解,根据版本进行序列化
有的字段不是一开始就有的,会随着版本的升级添加进来,那么在进行序列化和返序列化的时候就会根据版本号来选择是否要序列化.
@Since(版本号)能完美地实现这个功能.
当然,GsonBuilder.setVersion(double)方法需要调用.
例程如下:
public class User {
private String firstName;
private String lastName;
@Since(1.0) private String emailAddress;
@Since(1.0) private String password;
@Since(1.1) private Address address;
}
还的字段可能,随着版本的升级而删除,那么
@Until(版本号)也能实现这个功能,GsonBuilder.setVersion(double)方法需要调用.
public class User {
private String firstName;
private String lastName;
@Until(1.1) private String emailAddress;
@Until(1.1) private String password;
}
maven pom.xml 设置
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.1</version>
</dependency>
2013、7、22
项目是2.2开发 测试手机是android4.0时候提示 android.os.NetworkOnMainThreadException异常,原来在4.0中,访问网络不能在主程序中进行,有两个方法可以解决,一个是在主程序中增加:
new Thread(){ @Override public void run(){ //你要执行的方法 //执行完毕后给handler发送一个空消息 handler.sendEmptyMessage(0); } }.start(); //定义Handler对象 private Handler handler =new Handler(){ @Override //当有消息发送出来的时候就执行Handler的这个方法 public void handleMessage(Message msg){ super.handleMessage(msg); //处理UI } };
2013、7、22
背景知识:
以前不明白为什么要Handler,现在明白了,Handler的作用是线程Thread与Activity之间的桥梁。因为在Android中,线程Thread是不能访问Activity里的Widget的,举个简单的例子,你不能在线程中写如下代码:
- title = (TextView) findViewById(R.id.title);
复制代码
所以就需要Handler来实现,其作用也就是将值从Thread->Activity,或者Activity->Thread。最终操作Widget还是在Activity。
缘由:
因为我在开发的过程中遇到了一问题,就是我在android 2.3版本中使用了HttpClient类来获取网络资源,但是到了android 4.0下就报错了。百思不得其解,网上还有大把人说要加StrictMode,请参考:http://www.dengyukeji.com/thread-429-1-1.html
原来是写法不对!
实现:
- public class GetDataThread extends Thread{
- HoroscopeDetailMainActivity activity;
- public GetDataThread(HoroscopeDetailMainActivity activity){
- this.activity = activity;
- }
- @Override
- public void run() {
- returnData = HttpUtil.queryStringForGet(horoscopeDataUrl); //
- returnData 是全局变量
- activity.getDataHandler.sendEmptyMessage(0); //传递消息给Activity,其实这里只是意思一下,告诉Activity,我已经执行完毕了,你可以做其他的事儿了。
- }
- }
复制代码
接下来就是Handler出场啦!
- Handler getDataHandler = new Handler(){
- @Override
- public void handleMessage(Message msg){
- SetVal(); //在接收到Thread传递过来的消息后,做其他的事情
- }
- };
复制代码
Activity调用:
- //启动获取数据线程
- new GetDataThread(this).start();
复制代码
17 down vote
accepted
|
There are two Solution of this Problem.
1) Don't write network call in Main UI Thread, Use Async Task for that.
2) Write below code into your MainActivity file after setContentView(R.layout.activity_main);
if (android.os.Build.VERSION.SDK_INT > 9) { StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); }
And below import statement into your java file.
import android.os.StrictMode;
|
2013、 7、23
[转]Vim插件FencView-自动识别编码 2011-12-16 12:39:10| 分类: vi/vim | 标签: |字号大
中
小 订阅
把插件放到plugin目录,然后自动生效,命令模式输入:
FencAutoDetect :自动识别文件编码
FencView:打开一个编码列表窗口,用户选择编码reload文件
在Gvim下可以通过tools-》encoding菜单选择编码,类似firefox
非常有用的选项:
let g:fencview_autodetect = 1 #打开文件时自动识别编码
let g:fencview_checklines = 10 #检查前后10行来判断编码
还可以指定识别编码的工具--$FENCVIEW_TELLENC。
luther@gliethttp:~$ sudo cp fencview.vim /usr/share/vim/vim72/plugin/
首先输入:FencAutoDectect自动检测,然后就可以:FencView查看自动检测到的字符集是什么了.
:F然后直接tab按键就可以了,不用全部输入
:FencAutoDectect
:FencView
重复输入:FencView世视窗在'关闭/打开'之间切换
这时高亮显示的字符集就是当前文件使用的字符集了
如果mount的iso文件夹里面出现了乱码,怎么来判断iso的编码呢,
可以这样
luther@gliethttp:~$ ls /mnt/iso > ~/gliethtp
luther@gliethttp:~$ vim ~/gliethttp
然后
:F输入tab按键
:FencAutoDectect
:FencView
就可以看到iso的编码方案了,我的是cp936
对于vim打开文件时如何自动识别,可以有如下2个方法:
1. 在.vimrc中加入如下一行
set fileencodings=utf-8,gb2312,ucs-bom,euc-cn,euc-tw,gb18030,gbk,cp936
2. 在.vimrc中加入上面安装的fencview插件指令
let g:fencview_autodetect=1
let g:fencview_auto_patterns='*'
对于方法2因为每次打开都将执行检测运算,所以效率比较低,使用方法1效率最高的(推荐),
当方法1不能识别时,可以使用:FencAutoDectect自动检测,然后追加encoding到方法1中.
文章出处:飞诺网(www.diybl.com):http://www.diybl.com/course/6_system/linux/Linuxjs/20100522/203904.html
2013、7、29
//==========================用了两种方法======================
1.------------用流方式
try {
//实例化url
URL
url = new URL(imgurl);
//载入图片到输入流
java.io.BufferedInputStream bis = new BufferedInputStream(url.openStream());
//实例化存储字节数组
byte[] bytes = new byte[100];
//设置写入路径以及图片名称
OutputStream bos = new
FileOutputStream(new File( "C:\\thetempimg.gif"));
int len;
while ((len = bis.read(bytes)) > 0) {
bos.write(bytes, 0, len);
}
bis.close();
bos.flush();
bos.close();
//关闭输出流
b=true;
} catch (Exception e) {
//如果图片未找到
b=false;
}
int[] a
= new int[2];
if(b){ //图片存在
//得到文件
java.io.File file = new java.io.File("C:\\thetempimg.gif");
BufferedImage bi = null;
try {
//读取图片
bi = javax.imageio.ImageIO.read(file);
} catch (IOException ex) {
ex.printStackTrace();
}
a[0] = bi.getWidth();
//获得 宽度
a[1] = bi.getHeight(); //获得 高度
//删除文件
file.delete();
}else{ //图片不存在
a=null;
}
return a;
}
// 显示网络上的图片
public static Bitmap returnBitMap(String
url) {
Log.i("returnBitMap","url="+url);
URL myFileUrl = null;
Bitmap bitmap = null;
try {
myFileUrl = new URL(url);
} catch
(MalformedURLException e) {
e.printStackTrace();
}
try {
HttpURLConnection conn = (HttpURLConnection) myFileUrl
.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap =
BitmapFactory.decodeStream(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
估计楼主要的sdk比较新,NetworkOnMainThreadException 这个错误是说你在main线程里面执行网络操作。最新sdk版本是不允许的。(为了避免anr异常出现)。
所以,解决的话,只要另外开个线程,把网络操作放到新线程里面就好啦。 ... 版主就是版主,一下就搞定了,刚刚玩安卓,还是没经验,非常感谢您!
临时接到一个任务,要给一个activity做成子线程的模式,但之前对线程的概念一无所知,于是乎查查查……用了几行代码把问题解决了,给临时需要却又不了解的朋友提供一个帮助吧.
废话不说了,上代码:
第一种:直接创建子线程并启动
private Thread newThread;
//声明一个子线程
new Thread() {
@Override
public void run() {
//这里写入子线程需要做的工作
}
}.start();
完毕。
第二种:先创建子线程,然后启动
private Thread newThread; //声明一个子线程
newThread = new Thread(new Runnable() {
@Override
public void run() {
//这里写入子线程需要做的工作
}
});
newThread.start(); //启动线程
2013731
昨天遇到这个问题就是从一个输入流里调用BitmapFactory.decodeStream(this.getContentResolver().openInputStream(uri))得到一个bitmap报的错。第一次调用都没问题,第二次再次调用就会报上面那个内存溢出的问题。而且有的手机报有的手机不报。研究了半天终于解决。首先分析了下原因,应该是图片占用的内存超过了系统虚拟机可分配的最大限制。不同手机可能分配的最大值不一样。后来找到解决办法主要是设置BitmapFactory.Options。
- BitmapFactory.Options bitmapOptions = new BitmapFactory.Options();
- bitmapOptions.inSampleSize = 4;
- bitmap = BitmapFactory.decodeStream(this.getContentResolver()..openInputStream(uri), null , bitmapOptions);
复制代码
有的说要加上bitmapOptions.inJustDecodeBounds = true;但是我加上后得到的bitmap就为null。去掉之后就可以。按照上面的方法就解决问题了。最好把bitmap在不用的时候回收一下:
- if (bitmap != null && !bitmap.isRecycled())
- bitmap.recycle();
复制代码
某位大神的图片占用内存的算法:
介绍一下图片占用进程的内存算法吧。
android中处理图片的基础类是Bitmap,顾名思义,就是位图。占用内存的算法如下:
图片的width*height*Config。
如果Config设置为ARGB_8888,那么上面的Config就是4。一张480*320的图片占用的内存就是480*320*4 byte。
前面有人说了一下8M的概念,其实是在默认情况下android进程的内存占用量为16M,因为Bitmap他除了java中持有数据外,底层C++的skia图形库还会持有一个SKBitmap对象,因此一般图片占用内存推荐大小应该不超过8M。这个可以调整,编译源代码时可以设置参数。