linux gdb自动打印 |
|
|
启动脚本增加:
1.ulimit -c unlimited
2. echo "voice_core_dump">/proc/sys/kernel/core_pattern
3. gdb voice voice_core_dump 0<gdb_sh
gdb_sh内容:exit
|
多版本打包gradle |
|
|
sourceSets {
unisoundv2{
jniLibs.srcDirs = ['src/main/jniLibs']
}
unisoundv3{
jniLibs.srcDirs = ['src/main/jniLibs_v3']
}
}
productFlavors {
unisoundv2 {
resValue "string", "SDK_UNISOUND_VER", "unisoundv2"
}
unisoundv3 {
resValue "string", "SDK_UNISOUND_VER", "unisoundv3"
}
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
unisoundv2Compile files('libs_other/usc.jar')
unisoundv3Compile files('libs_other/usc_v3.jar')
}
|
android手势Demo |
|
|
package com.example.testandroid;
import android.R.integer;
import android.app.Activity;
import android.os.Bundle;
import android.os.Vibrator;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.VideoView;
public class MainActivity extends Activity {
private VideoView myVideoView;
private String path = "/mnt/sdcard/video/Wonder Girls_Nobody(英文版).mp4";
private String TAG = "MainActivity";
private GestureDetector mGestureDetector;
private Vibrator vibrator;
private final int MAX_BRIGHTNESS = 1;
private final float BRIGHTNESS_INTERVAL = 0.01f;
private Button mBrightness;
private Button mVolume;
private static int mCurBrightness = -1;
// private int mSysteBrightness;
private float mIntervalUnit;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBrightness = (Button) findViewById(R.id.button1);
mVolume = (Button) findViewById(R.id.button2);
mIntervalUnit = getScrollUtil();
if(mCurBrightness == -1){
mCurBrightness = BrightnessUtils.getScreenBrightness(MainActivity.this);;
}
mBrightness.setText(""+mCurBrightness);
BrightnessUtils.setBrightness(MainActivity.this, mCurBrightness);
}
private float getScrollUtil() {
DisplayMetrics dm = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(dm);
return (dm.widthPixels/2)/100f;
}
private boolean isLeft(float y){
return true;
}
private boolean isRight(float y){
return false;
}
@SuppressWarnings("deprecation")
@Override
protected void onResume() {
mGestureDetector = new GestureDetector(
new GestureDetector.OnGestureListener() {
public boolean onSingleTapUp(MotionEvent e) {
return false;
}
public boolean onDown(MotionEvent e) {
return false;
}
public void onLongPress(MotionEvent e) {
}
public boolean onFling(MotionEvent e1, MotionEvent e2,
float velocityX, float velocityY) {
return true;
}
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.d("kang", "kang:"+",xd="+distanceX+",yd="+distanceY+"y1="+e1.getY()+",y2="+e2.getY()+",interval="+mIntervalUnit);
if(Math.abs(e1.getY()-e2.getY()) > Math.abs(e1.getX()-e2.getX())){
//srcoll right or left
return false;
}else if(Math.abs(distanceX) > mIntervalUnit){
//scroll up or down
if(distanceX > 0){
//up
mCurBrightness = mCurBrightness +(int)(Math.abs(distanceX)/mIntervalUnit);
Log.d("kang", "up brightness="+mCurBrightness+","+mIntervalUnit);
if(mCurBrightness > 100){
mCurBrightness = 100;
}
BrightnessUtils.setBrightness(MainActivity.this,mCurBrightness);
mBrightness.setText(""+mCurBrightness);
return true;
}else {
//down
mCurBrightness = mCurBrightness -(int)(Math.abs(distanceX)/mIntervalUnit);
Log.d("kang", "down brightness="+mCurBrightness+","+mIntervalUnit);
if(mCurBrightness < 0){
mCurBrightness = 0;
}
BrightnessUtils.setBrightness(MainActivity.this,mCurBrightness);
mBrightness.setText(""+mCurBrightness);
return true;
}
}
return false;
}
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
});
super.onResume();
}
public boolean onTouchEvent(MotionEvent event) {
boolean result = mGestureDetector.onTouchEvent(event);
if (!result) {
result = super.onTouchEvent(event);
}
return result;
}
@Override
protected void onStop() {
super.onStop();
}
}
|
自定义 android Toast时间 |
|
|
oast result = new Toast(context) {
@Override
public void show() {
Field mTNField;
try {
mTNField = Toast.class.getDeclaredField("mTN");
mTNField.setAccessible(true);
Object mTN = mTNField.get(this);
try {
Field mNextViewField = mTN.getClass().getDeclaredField("mNextView");
mNextViewField.setAccessible(true);
mNextViewField.set(mTN, getView());
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
Method showMethod = mTN.getClass().getDeclaredMethod("show", null);
showMethod.setAccessible(true);
showMethod.invoke(mTN, null);
} catch (Exception e) {
e.printStackTrace();
}
}
};
LayoutInflater inflate = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(R.layout.ui_toast, null);
result.setView(v);
|
解压APK |
|
|
public class TestDecodeAPKActivity extends Activity {
private final String F_SOURCE = "C:\\Documents and Settings\\kangx.TCLKING\\桌面\\AppMarket2.apk";
private final String F_DEST = "C:\\Documents and Settings\\kangx.TCLKING\\桌面\\decodeApk";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
try {
upZipFile(new File(F_SOURCE), F_DEST);
} catch (ZipException e) {
Log.e("", "aaaaaaaaaa");
e.printStackTrace();
} catch (IOException e) {
Log.e("", "bbbbbbbbbbb");
e.printStackTrace();
}
}
}).start();
}
/**
* 解压缩功能.
* 将zipFile文件解压到folderPath目录下.
* @throws Exception
*/
public int upZipFile(File zipFile, String folderPath)throws ZipException,IOException {
//public static void upZipFile() throws Exception{
ZipFile zfile=new ZipFile(zipFile);
Enumeration zList=zfile.entries();
ZipEntry ze=null;
byte[] buf=new byte[1024];
while(zList.hasMoreElements()){
ze=(ZipEntry)zList.nextElement();
if(ze.isDirectory()){
Log.d("upZipFile", "ze.getName() = "+ze.getName());
String dirstr = folderPath + ze.getName();
//dirstr.trim();
dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
Log.d("upZipFile", "str = "+dirstr);
File f=new File(dirstr);
f.mkdir();
continue;
}
Log.d("upZipFile", "ze.getName() = "+ze.getName());
OutputStream os=new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath, ze.getName())));
InputStream is=new BufferedInputStream(zfile.getInputStream(ze));
int readLen=0;
while ((readLen=is.read(buf, 0, 1024))!=-1) {
os.write(buf, 0, readLen);
}
is.close();
os.close();
}
zfile.close();
Log.d("upZipFile", "finishssssssssssssssssssss");
return 0;
}
/**
* 给定根目录,返回一个相对路径所对应的实际文件名.
* @param baseDir 指定根目录
* @param absFileName 相对路径名,来自于ZipEntry中的name
* @return java.io.File 实际的文件
*/
public static File getRealFileName(String baseDir, String absFileName){
String[] dirs=absFileName.split("/");
File ret=new File(baseDir);
String substr = null;
if(dirs.length>1){
for (int i = 0; i < dirs.length-1;i++) {
substr = dirs[i];
try {
//substr.trim();
substr = new String(substr.getBytes("8859_1"), "GB2312");
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ret=new File(ret, substr);
}
Log.d("upZipFile", "1ret = "+ret);
if(!ret.exists())
ret.mkdirs();
substr = dirs[dirs.length-1];
try {
//substr.trim();
substr = new String(substr.getBytes("8859_1"), "GB2312");
Log.d("upZipFile", "substr = "+substr);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ret=new File(ret, substr);
Log.d("upZipFile", "2ret = "+ret);
return ret;
}
return ret;
}
/**
* 解压zip格式的压缩包
*
* @param filePath
* 压缩文件路径
* @param outPath
* 输出路径
* @return 解压成功或失败标志
*/
public static Boolean unZip(String filePath, String outPath) {
String unzipfile = filePath; // 解压缩的文件名
try {
ZipInputStream zin = new ZipInputStream(new FileInputStream(
unzipfile));
ZipEntry entry;
// 创建文件夹
while ((entry = zin.getNextEntry()) != null) {
if (entry.isDirectory()) {
System.out.println("dir="+entry.getName());
File directory = new File(outPath, entry.getName());
if (!directory.exists()) {
if (!directory.mkdirs()) {
System.exit(0);
}
}
zin.closeEntry();
} else {
File myFile = new File(entry.getName());
System.out.println("out path="+outPath+myFile.getPath());
File file = new File(outPath
+ myFile.getPath());
file.getParentFile().mkdirs();
file.createNewFile();
FileOutputStream fout = new FileOutputStream(outPath
+ myFile.getPath());
DataOutputStream dout = new DataOutputStream(fout);
byte[] b = new byte[1024];
int len = 0;
while ((len = zin.read(b)) != -1) {
dout.write(b, 0, len);
}
dout.close();
fout.close();
zin.closeEntry();
}
}
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
|
String.format用法 |
|
|
import java.math.BigDecimal;
/**
* 1.%[argument_index$][flags][width][.precision]conversion
*
* String.format("%1$s",1234,5678); 指向第一个参数转换为字符串
* String.format("%1$s%2$s",1234,5678);将两个参数格式化为字符串,并连接在一起
* String.format("%s",1234,5678); 指向第一个参数转换为字符串
* String.format("%s%06d",1234,5678); 将第一个格式化为“1234” 第二个格式化005678 w
*/
public class StringFormat {
/**
* 处理浮点型数据 应用范围float、Float、double、Double 和 BigDecimal
* %[argument_index$][flags][width][.precision]conversion
* %[index$][标识][最小宽度][保留精度]转换方式
* 标识:
* '-' 在最小宽度内左对齐,不可以与“用0填充”同时使用
* '+' 结果总是包括一个符号
* ' ' 正值前加空格,负值前加负号
* '0' 结果将用零来填充
* ',' 每3位数字之间用“,”分隔(只适用于fgG的转换)
* '(' 若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(只适用于eEfgG的转换)
* 最小宽度: 最终该整数转化的字符串最少包含多少位数字
* 保留精度:保留小数位后面个数
* 转换方式:
* 'e', 'E' -- 结果被格式化为用计算机科学记数法表示的十进制数
* 'f' -- 结果被格式化为十进制普通表示方式
* 'g', 'G' -- 根据具体情况,自动选择用普通表示方式还是科学计数法方式
* 'a', 'A' -- 结果被格式化为带有效位数和指数的十六进制浮点数
*
*/
public static void formatFloat() {
System.out.println(String.format("%1$e", 1234567890.123456789));//转换为科学记数法表示
System.out.println(String.format("%1$020e", 1234567890.123456789));//转换为科学记数法表示,长度为20,用0填充
System.out.println(String.format("%1$g", 12345.123456789));//根据结果制动识别使用转换器e或f
System.out.println(String.format("%1$a", 12345.123456789));//转换为16进制的浮点数
System.out.println(String.format("%1$,f", 1234567890.123456789));//转换结果保留默认小数位,3位数字用,隔开,转换为十进制表示
System.out.println(String.format("%1$,f", 1234567890.123456789));//转换结果保留默认小数位,3位数字用,隔开
System.out.println(String.format("%1$.10f", 1234567890.123456789));//转换结果是保留10位精度.转换成十进制表示方式
System.out.println(String.format("%1$,.100f", new BigDecimal("12345678909.1234567890123456789")));//转换结果是保留100位精度,没有精度丢失,整数位3个就用,隔开
System.out.println(String.format("%1$,.5f", 1234567890.123456789));//转换结果保留5位小数,3位数字用,隔开
}
/**
* 处理整数型数据 应用范围 byte、Byte、short、Short、int、Integer、long、Long 和 BigInteger
*
* %[argument_index$][flags][width]conversion
* %[index$][标识][最小宽度]转换方式
* 标识:
* '-' 在最小宽度内左对齐,不可以与“用0填充”同时使用
* '#' 只适用于8进制和16进制,8进制时在结果前面增加一个0,16进制时在结果前面增加0x
* '+' 结果总是包括一个符号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)
* ' ' 正值前加空格,负值前加负号(一般情况下只适用于10进制,若对象为BigInteger才可以用于8进制和16进制)
* '0' 结果将用零来填充
* ',' 只适用于10进制,每3位数字之间用“,”分隔
* '(' 若参数是负数,则结果中不添加负号而是用圆括号把数字括起来(同‘+’具有同样的限制)
* 最小宽度: 最终该整数转化的字符串最少包含多少位数字
* 转换方式:d-十进制 o-八进制 x或X-十六进制
*/
public static void formatNumber() {
System.out.println(String.format("%1$d", -31)); //格式化成数值表示使用十进制,结果"-31"
System.out.println(String.format("%1$o", -31)); //格式化成数值表示使用八进制,结果"37777777741"
System.out.println(String.format("%1$19d", -31));//格式化成数值表示使用十进制,总长度显示19位结果" -31"
System.out.println(String.format("%1$-19d", -31));//格式化成数值表示使用十进制,总长度显示19位,左靠齐结果"-31 "
System.out.println(String.format("%1$09d", -31));//格式化成数值表示,使用十进制,结果"-00000031"
System.out.println(String.format("%1$,9d", -3123));//每3位数字用,隔开,总长度9位,结果" -3,123"
System.out.println(String.format("%1$,09d", -3123));//每3位数字用,隔开,用0填充总长度9位,结果"-0003,123"
System.out.println(String.format("%1$(9d", -3123));//每3位数字用,用0填充总长度9位,结果" (3123)"
System.out.println(String.format("%1$ 9d", -31));
}
/**
* 处理字符型数据
* 对字符进行格式化是非常简单的,c C表示字符,标识中'-'表示左对齐,其他就没什么了
*/
public static void formatChar() {
System.out.println(String.format("%1$c", 97));//转换为字符
System.out.println(String.format("%1$10c", '鄒'));//转换为字符,十位
System.out.println(String.format("%1$-10c", '鸿'));//转换为字符,十位,靠左
}
/**
* 格式化百分比.%特殊字符。转义格式为 %%而不是/
*/
public static void formatBaiFenBi() {
System.out.println(String.format("%1$f%%", 12.123456));
System.out.println(String.format("%1$.4f%%", 12.123456));//留取4位小数,4舍5入
BigDecimal a = new BigDecimal("12.12"),b = new BigDecimal("13.13");
BigDecimal c = a.divide(b,28,BigDecimal.ROUND_HALF_UP);//保留28位小数
System.out.println(c + "");
System.out.println(String.format("%1$.28f", c));//格式为保留28位小数
}
/**
* 获取独立平台行分隔符
*/
public static void getSeparator() {
System.out.println(String.format("%n"));
System.out.println( System.getProperty("line.separator"));
}
/**
* 格式化日期 (可用范围long,Long,Calendar,java.util.Date)
* %[index$][标识][最小宽度]转换方式
* 标识:
* 日期和时间转换字符的前缀 t或者T
* 转换方式:
* 格式化日期转换字符
* 'B' 特定于语言环境的月份全称,例如 "January" 和 "February"。
* 'b' 特定于语言环境的月份简称,例如 "Jan" 和 "Feb"。
* 'h' 与 'b' 相同。
* 'A' 特定于语言环境的星期几全称,例如 "Sunday" 和 "Monday"
* 'a' 特定于语言环境的星期几简称,例如 "Sun" 和 "Mon"
* 'C' 除以 100 的四位数表示的年份,被格式化为必要时带前导零的两位数,即 00 - 99
* 'Y' 年份,被格式化为必要时带前导零的四位数(至少),例如,0092 等于格里高利历的 92 CE。
* 'y' 年份的最后两位数,被格式化为必要时带前导零的两位数,即 00 - 99。
* 'j' 一年中的天数,被格式化为必要时带前导零的三位数,例如,对于格里高利历是 001 - 366。
* 'm' 月份,被格式化为必要时带前导零的两位数,即 01 - 13。
* 'd' 一个月中的天数,被格式化为必要时带前导零两位数,即 01 - 31
* 'e' 一个月中的天数,被格式化为两位数,即 1 - 31。
*
* 格式化时间字符
* 'H' 24 小时制的小时,被格式化为必要时带前导零的两位数,即 00 - 23。
* 'I' 12 小时制的小时,被格式化为必要时带前导零的两位数,即 01 - 12。
* 'k' 24 小时制的小时,即 0 - 23。
* 'l' 12 小时制的小时,即 1 - 12。
* 'M' 小时中的分钟,被格式化为必要时带前导零的两位数,即 00 - 59。
* 'S' 分钟中的秒,被格式化为必要时带前导零的两位数,即 00 - 60 ("60" 是支持闰秒所需的一个特殊值)。
* 'L' 秒中的毫秒,被格式化为必要时带前导零的三位数,即 000 - 999。
* 'N' 秒中的毫微秒,被格式化为必要时带前导零的九位数,即 000000000 - 999999999。
* 'p' 特定于语言环境的 上午或下午 标记以小写形式表示,例如 "am" 或 "pm"。使用转换前缀 'T' 可以强行将此输出转换为大写形式。
* 'z' 相对于 GMT 的 RFC 822 格式的数字时区偏移量,例如 -0800。
* 'Z' 表示时区缩写形式的字符串。Formatter 的语言环境将取代参数的语言环境(如果有)。
* 's' 自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的秒数,即 Long.MIN_VALUE/1000 与 Long.MAX_VALUE/1000 之间的差值。
* 'Q' 自协调世界时 (UTC) 1970 年 1 月 1 日 00:00:00 至现在所经过的毫秒数,即 Long.MIN_VALUE 与 Long.MAX_VALUE 之间的差值
* 格式化时间组合字符
* 'R' 24 小时制的时间,被格式化为 "%tH:%tM"
* 'T' 24 小时制的时间,被格式化为 "%tH:%tM:%tS"。
* 'r' 12 小时制的时间,被格式化为 "%tI:%tM:%tS %Tp"。上午或下午标记 ('%Tp') 的位置可能与语言环境有关。
* 'D' 日期,被格式化为 "%tm/%td/%ty"。
* 'F' ISO 8601 格式的完整日期,被格式化为 "%tY-%tm-%td"。
* 'c' 日期和时间,被格式化为 "%ta %tb %td %tT %tZ %tY",例如 "Sun Jul 20 16:17:00 EDT 1969"。
*
*/
public static void formatDate() {
long c = System.currentTimeMillis();
System.out.println(String.format("%1$tY-%1$tm-%1$td %1$tH:%1$tM:%1$tS", c));
System.out.println(String.format("%1$ty-%1$tm-%1$td %1$tI:%1$tM:%1$tS %1$tp %1$tb %1$ta", c));
System.out.println(String.format("%1$tF %1$tT", 1244943575031l));
}
/**
* 规转换可应用于任何参数类型
* 'b或B' '/u0062' 将生成 "true" 或 "false", 如果参数为 null,则结果为 "false"。如果参数是一个 boolean 值或 Boolean,那么结果是由 String.valueOf() 返回的字符串。否则结果为 "true"。
* 'h或H' '/u0068' 生成一个表示对象的哈希码值的字符串。 如果参数 arg 为 null,则结果为 "null"。否则,结果为调用 Integer.toHexString(arg.hashCode()) 得到的结果。
* 's或S' '/u0073' 生成一个字符串。 如果参数为 null,则结果为 "null"。如果参数实现了 Formattable,则调用其 formatTo 方法。否则,结果为调用参数的 toString() 方法得到的结果。
*
*
*/
public static void formatAny() {
System.out.println(String.format("%b %b %b %b", null,"","true",true));
String pattern = "%1$s 在 %4$tF %4$tT 说了 /"%1$s 爱 %2$s %3$d 年/"";
System.out.println(String.format(pattern, "mingming","shuilian",10000,System.currentTimeMillis()));
}
public static void main(String[] args) {
formatAny();
}
}
|
如何在ubuntu下安装jdk1.5和jdk1.6,并相互切换 |
|
|
安装jdk1.5
sudo apt-get install sun-java5-jdk
安装jdk1.6
sudo apt-get install sun-java6-jdk
输入如下命令进行jdk1.5和jdk1.6之间的切换
sudo update-alternatives --config java
提示选择可用的java版本
sudo update-alternatives --config javac
提示选择可用的javac 版本
|
ubuntu获取android 2.2源码和编译 |
|
|
一、获取Android源代码
Git是Linux Torvalds(Linux之父)为了帮助管理Linux内核开发而开发的一个开放源码的分布式版本控制软件,它不同于Subversion、CVS这样的集中式版本控制系统。在集中式版本控制系统中只有一个仓库(Repository),许多个工作目录(Working Copy),而在Git这样的分布式版本控制系统中(其他主要的分布式版本控制系统还有BitKeeper、Mercurial、GNU Arch、Bazaar、Darcs、SVK、Monotone等),每一个工作目录都包含一个完整仓库,它们支持离线工作,本地提交可以稍后提交到服务器上。
因为Android是由Kernel、Dalvik、Bionic、Prebuilt、build等多个项目组成,如果我们分别使用Git来逐个获取显得很麻烦,所以Android项目编写了一个名为Repo的Python的脚本来统一管理这些项目的仓库,使得项目的获取更加简单。
在Ubuntu 8.04上安装Git只需要设定正确的更新源,然后使用apt-get就可以了,apt-get是一条Linux命令,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。
apt-get命令一般需要root权限执行,所以一般跟着sudo命令。
sudo apt-get install git-core curl
这条命令会从互联网的软件仓库中安装git-core和curl。
其中curl是一个利用URL语法在命令行方式下工作的文件传输工具,它支持很多协议,包括FTP、FTPS、HTTP、HTTPS、TELENT等,我们需要安装它从网络上获取Repo脚本文件。
curl http://android.git.kernel.org/repo >~/bin/repo
这句命令会下载repo脚本文件到当前主目录的/bin目录下,并保存在文件repo中。
最后我们需要给repo文件可执行权限
chmod a+x ~/bin/repo
接下来我们就可以利用repo脚本和Git、curl软件获取Android的源代码了:)
为repo命令修改环境变量,在.bashrc或/etc/profile 文件中加入如下:
sudo gedit /etc/profile
export PATH=$PTAH:~/bin/
首先建一个目录,比如~/myandroid。
然后使用下面命令获取源码:
mkdir myandroid
cd myandroid
repo init -u git://android.git.kernel.org/platform/manifest.git -b froyo
repo sync
这个过程会持续很长的时间(笔者下载了一天),下载完毕后会看到repo initialized in /android这样的提示,说明本地的版本库已经初始化完毕,并且包含了当前最新的sourcecode。
如果我们想拿某个分支版本的代码,而不是主线代码,需要使用-b参数指定branch的名字,比如:
repo init –u git://android.git.kernel.org/platform/manifest.git –b cupcake
如果我们只是想获取某一个project的代码,比如kernel/common,就不需要repo脚本了,直接使用Git工具即可,如果仔细研究repo脚本会发现,repo脚本其实就是组织Git工具去获取各个Project并把它们组织到同一个项目Android内。
git clone git://android.git.kernel.org/kernel/common.git
我们上面使用repo脚本获取了各个项目,那么接下来就需要把整个Android代码树同步到本地,如下:
repo sync project1 project2 …
笔者使用repo sync命令直接同步全部项目到本地。
二、源码编译
全部同步完毕后,进入到Android目录下,使用make命令编译,你会发现出现如下错误提示:
host C: libneo_cgi <= external/clearsilver/cgi/cgi.c
external/clearsilver/cgi/cgi.c:22:18: error: zlib.h: No such file or directory
这个错误是因为我们缺少zlib1g-dev,需要使用apt-get命令从软件仓库中安装,如下:
sudo apt-get install zlib1g-dev
同理,我们还需要依次安装如下软件
sudo apt-get install gcc g++ flex bison gperf libsdl-dev libesd0-dev libwxgtk2.8-dev build-essential zip valgrind zlib1g-dev libncurses5-dev libx11-dev
libsdl1.2-dev libsdl1.2debian
这是官方指引的包,还得增加一些包,要不然,之后还会报缺乏某些头文件之类的。
(/usr/include/gnu/stubs.h:9:27: error: gnu /stubs-64.h: 没有那个文件或目录)
sudo apt-get install lib64z1-dev libc6-dev-amd64 g++-multilib lib64stdc++6
以上软件全部安装完毕后,运行make命令再次编译Android源码。
这个时候你会发现出现很多java文件无法编译的错误,打开Android的源码我们可以看到在android/dalvik/libcore/dom/src/test/java/org/w3c/domts下有很多java源文件,这意味着编译Android之前需要先安装JDK。
首先从sun官方网站下载jdk-6u22-linux-i586.bin文件并安装它。
【安装 JDK 1.6】
1.下载jdk
下载连接http://java.sun.com/javase/downloads/index.jsp
选择jdk-6u22-linux-i586.bin下载,将jdk-6u22-linux-i586.bin放置于目录/home/h3/bin
(注意改目录)
2.解压文件
打开终端,进入放置jdk的目录[cd /home/h3/bin];
更改文件权限为可执行[sudo chmod u+x jdk-6u22-linux-i586.bin]
或者[sudo chmod 701 jdk-6u22-linux-i586.bin]
3. 执行 bin 文件
sudo ./jdk-6u22-linux-i586.bin 就可以开始安装了
设置JAVA环境
代码:
sudo gedit /etc/profile
在该文件中加入:
export JAVA_HOME=/home/h3/bin/java-1.6.0-22
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
export CLASSPATH=$CLASSPATH:.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
如果你安装JDK 的目录不同我的,只要将第一行“=”后的路径改成你的安装目录路径即可,第 二、三行都不用修改
然后要系配置生 效,执行
代码:
source /etc/profile
可以用下面的命令查看是否成功
代码:
java -version
如果出现:
java version "1.6.0_22"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.60_22-b05)
Java HotSpot(TM) Client VM (build 1.6.0_22-b05, mixed mode, sharing)
【Update】
采用 JDK 1.6,需修改以下文件,暂时处理编译问题:
把external/clearsilver/cgi/Android.mk, external/clearsilver/java-jni/Android.mk, external/clearsilver/util/Android.mk, external/clearsilver/cs/Android.mk.
下面脚本中的ifneq改为ifeq可暂时回避问题
# This forces a 64-bit build for Java6
ifneq ($(filter 1.6%,$(java_version)),)
LOCAL_CFLAGS += -m64
LOCAL_LDFLAGS += -m64
endif
【Update】
Android文件系统由于已经自带了经过优化的交叉编译工具,并且为所有的源码都提供了经过验证的makefile,所以系统的整体编译相对简单,官方 发布的版本中基本功能都已经包含进了makefile中。如果需要增加什么功能,可以到 build/target/product/ 修改相应的.mk文 件。例如
为了增加中文的输入法,可以按下面的方法做:
#cd /home/h3/myandroid/build/target/product/
#gedit generic.mk
打开这个文件后,在PRODUCT_PACKAGES中,加入PinyinIME,然后保存退出。这样在整体编译的时候就会把中文输入法也编译进 system中了。
三、开发工具 SDK 的编译
Android提供了完整的开发工具和交叉编译工具,这些都包含在了源码内,所以只要对源码正确编译,就可以获得丰富的开发工具,并且 Android的移 植工作也需要这些工具的支持。
编译Android开发工具的步奏如下:
#cd /home/h3/myandroid/
#make sdk
这次编译主要生成物件在out/host/下
#cd /out/host/linux-x86/sdk/
可以看到这里有了一个名叫android- sdk_eng.root_linux-x86的文件夹,这个文件夹基本包含了Android的模拟器 和所有的开发调试工具。打开这个文件夹,可以看到这里主要由以下几部分组成:
–add-ones –需要增加的新工具路径
–docs –关于模拟器和各种开发工具的说明等
–platform –模拟器和开发工具需要的文件
–tools –模拟器和开发工具的应用程序
四、测试编译结果
(方式:直接从 Android build system 环境下,测试;另,亦可通过 Android SDK 方式)
找到编译后android的列表文档out,我们发现在 $ANDROID_CODE/out/host/linux-x86/bin 下多了很多应用程序,这些应用程序就是android得以运行的入门,所以我们需要把这个列表也添加到PATH下,在 /etc/profile 文档中加入如下内容:
export ANDROID_CODE=directory of your Android source code
export ANDROID_PRODUCT_OUT=$ANDROID_CODE/out/target/product/generic
export PATH=$PATH:$ANDROID_CODE/out/host/linux-x86/bin
执行 source /etc/profile 启用环境变量
接下来我们需要把android的镜像文档加载到emulator中,使得emulator可以看到android运行的实际效果
下面就可以进入到模拟器列表中并开启模拟器
cd $ANDROID_CODE/out/target/product/generic
emulator -system system.img -data userdata.img -ramdisk ramdisk.img
五. 编译模块:
修改了android的相关源代码后,在源代码的目录下,执行: . build/envsetup.sh (. 后面有空格)
然后,进入到修改的源代码所属包的目录下,执行:mm
在源代码的目录下,执行: make snod
最后,在系统目录下,执行:emulator ,就可以在模拟器上看到修改后的结果。
android中的一个应用程序可以单独编译,编译后要重新生成system.img
在源码目录下执行
$ . build/envsetup.sh (. 后面有空格)
就多出一些命令:
- croot: Changes directory to the top of the tree.
- m: Makes from the top of the tree.
- mm: Builds all of the modules in the current directory.
- mmm: Builds all of the modules in the supplied directories.
- cgrep: Greps on all local C/C++ files.
- jgrep: Greps on all local Java files.
- resgrep: Greps on all local res/*.xml files.
- godir: Go to the directory containing a file.
可以加—help查看用法
我们可以使用mmm来编译指定目录的模块,如编译联系人:
$ mmm packages/apps/Contacts/
编完之后生成两个文件:
out/target/product/generic/data/app/ContactsTests.apk
out/target/product/generic/system/app/Contacts.apk
可以使用
$ make snod
重新生成system.img,再运行模拟器
|
源码编译工具链 |
|
|
a. sudo apt-get install bison
b. sudo apt-get install vim
c. 解决:安装JDK 5.0
1):根据官方文档里所说,源代码的编译必须使用JDK5才能编译的了,所以这里我们使用jdk5
2): 需要先更新源,在终端里执行 sudo vim /etc/apt/sources.list
3): 在source.list里把以下2行拷贝到文档最后面:
deb http://us.archive.ubuntu.com/ubuntu/ jaunty multiverse
deb http://us.archive.ubuntu.com/ubuntu/ jaunty-updates multiverse
保存退出。
4): 执行 sudo apt-get update 更新源.
5): 配置编译环境并下载JDK5:sudo apt-get install sun-java5-jdk
sudo apt-get install build-essential
sudo apt-get install zlib1g-dev
sudo apt-get install flex
sudo apt-get install libncurses-dev
sudo apt-get install libx11-dev
sudo apt-get install gperf
|
apt-get install sun-java6-jdk失败 |
|
|
ubuntu10.04 lucid 去掉了sun-java 6-jre,sun-java 6-jdk的源,所以如果是直接
apt-get install sun-java 6-jdk
提示是
现在没有可用的软件包 sun-java 6-jdk,但是它被其它的软件包引用了。
这可能意味着这个缺失的软件包可能已被废弃,
或者只能在其他发布源中找到
E: 软件包 sun-java 6-jdk 还没有可供安装的候选者
解决方法:
系统-->管理工具-->软件源中
“其他软件”,勾选第一项“http://archive.canonical.com/ubuntu lucid partner”
然后执行apt-get install sun-java 6-jdk
|
linux 命令源码查看 |
|
|
linux命令源码的查看
来源: ChinaUnix博客 日期: 2007.11.26 20:23 (共有0条评论) 我要评论
在平常的作业中,有时候老师让自己实现诸如cat等类的程序,有时候叫用shell实现,有时候用c实现,但是我经常一点头绪都没有,不过我想到 linux开源的,命令代码可以拿来参考下阿,所以我就想看看linux命令的源代码,于是就开始了摆渡狗狗的搜索过程。从结果来看,有两种情况,一种是给予rpm的包的形式;另一种是基于deb包的形式。具体我也不知道该怎么描述,总之就是一种redhat的源码查看,一种是debian的源码查看。我是用的ubuntu,基于debian的,所以先前按照rpm的方式怎么也不奏效。
下面我就总结了下:大概就是源码都存放在相应的包里面。
新利得里我搜了下coreutils,显示已经安装,不过这里安装的应该是软件,也就是命令的执行文件吧应该。但是我没有找到它是否安装了src,也就是源代码。
PS:
Coreutils软件包含有用于展示和设置基本系统特性的工具。
具体过程一(Linux rwind-ubuntu 2.6.22-14-generic):
1.首先找到你想查看的命令属于哪个包
rwind@rwind-ubuntu:~$ dpkg -S `which ls`
coreutils: /bin/ls
coreutils就是源码所在的包,下面就是要下载了。
同样:
rwind@rwind-ubuntu:~/source$ dpkg -S `which which`
debianutils: /usr/bin/which
debianutils就是which所在的包。
我第一次犯的错误:把``用成‘’了,这两种不一样阿,前一个是数字键1左边的引号,作用是在shell重组命令行时把``里面的内容当作命令来执行并替换为结果。
2.下载相应的源码包
rwind@rwind-ubuntu:~/source$ apt-get -d source "debianutils"正在读取软件包列表... 完成正在分析软件包的依赖关系树 读取状态信息... 完成 需要下载 134kB 的源代码包。获取:1 http://ubuntu.cn99.com feisty/main debianutils 2.17.4build1 (dsc) [479B]获取:2 http://ubuntu.cn99.com feisty/main debianutils 2.17.4build1 (tar) [133kB]下载 134kB,耗时 1s (90.7kB/s) 下载完毕,目前是“仅下载”模式
d选项是仅仅下载的选项。下载到你目前的工作目录当中。
3.把你下载的包解压缩,自己去里面找吧,文件挺多的,都什么作用我不清楚,留待以后慢慢研究慢慢发现。
另外:在网上还发现一些资料,但我都没验证,
原文如下:
apt-get install apt-file
apt-file update
apt-file search /bin/ls
这样可以知道ls是coreutils提供的
然后apt-get source coreutils就得到源码了
当然对于ls,还可以用dpkg -S /usr/ls 来查询它属于哪一个包,不过dpkg -S只对已安装的包有效
二:这是我在网上搜的rpm包格式的。
以find命令为例:
第一步,确定命令属于哪个rpm包:
#rpm -qf /usr/bin/find
findutils-4.1-34
第二步,查找findutils的源码包findutils-4.1-34.src.rpm,这个一般在发行版的网站上可以找到
第三步,安装源码包:
rpm -ivh findutils-4.1-34.src.rpm
安装好之后可以到/usr/src/RedHat/SOURCE下找到相关的源码包
大概就是这样了,以后发现有不足的地方还会补充,如果您有什么建议或发现错误,希望可以指点指点。谢谢。
|
线程池 |
|
|
线程池类为 java.util.concurrent.ThreadPoolExecutor,常用构造方法为:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize,
long keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue,
RejectedExecutionHandler handler)
corePoolSize: 线程池维护线程的最少数量
maximumPoolSize:线程池维护线程的最大数量
keepAliveTime: 线程池维护线程所允许的空闲时间
unit: 线程池维护线程所允许的空闲时间的单位
workQueue: 线程池所使用的缓冲队列
handler: 线程池对拒绝任务的处理策略
一个任务通过 execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法欲添加到线程池时:
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。
也就是:处理任务的优先级为:
核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。
unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS。
workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue
handler有四个选择:
ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
二、一般用法举例
//------------------------------------------------------------
//TestThreadPool.java
//package cn.simplelife.exercise;
import java.io.Serializable;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class TestThreadPool {
private static int produceTaskSleepTime = 2;
private static int consumeTaskSleepTime = 2000;
private static int produceTaskMaxNumber = 10;
public static void main(String[] args) {
//构造一个线程池
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, 4, 3,
TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3),
new ThreadPoolExecutor.DiscardOldestPolicy());
for(int i=1;i<=produceTaskMaxNumber;i++){
try {
//产生一个任务,并将其加入到线程池
String task = "task@ " + i;
System.out.println("put " + task);
threadPool.execute(new ThreadPoolTask(task));
//便于观察,等待一段时间
Thread.sleep(produceTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
}
}
*//*
public static class ThreadPoolTask implements Runnable,Serializable{
private static final long serialVersionUID = 0;
//保存任务所需要的数据
private Object threadPoolTaskData;
ThreadPoolTask(Object tasks){
this.threadPoolTaskData = tasks;
}
public void run(){
//处理一个任务,这里的处理方式太简单了,仅仅是一个打印语句
System.out.println("start .."+threadPoolTaskData);
try {
////便于观察,等待一段时间
Thread.sleep(consumeTaskSleepTime);
} catch (Exception e) {
e.printStackTrace();
}
threadPoolTaskData = null;
}
public Object getTask(){
return this.threadPoolTaskData;
}
}
}
//------------------------------------------------------------
说明:
1、在这段程序中,一个任务就是一个Runnable类型的对象,也就是一个ThreadPoolTask类型的对象。
2、一般来说任务除了处理方式外,还需要处理的数据,处理的数据通过构造方法传给任务。
3、在这段程序中,main()方法相当于一个残忍的领导,他派发出许多任务,丢给一个叫 threadPool的任劳任怨的小组来做。
这个小组里面队员至少有两个,如果他们两个忙不过来,任务就被放到任务列表里面。
如果积压的任务过多,多到任务列表都装不下(超过3个)的时候,就雇佣新的队员来帮忙。但是基于成本的考虑,不能雇佣太多的队员,至多只能雇佣 4个。
如果四个队员都在忙时,再有新的任务,这个小组就处理不了了,任务就会被通过一种策略来处理,我们的处理方式是不停的派发,直到接受这个任务为止(更残忍!呵呵)。
因为队员工作是需要成本的,如果工作很闲,闲到 3SECONDS都没有新的任务了,那么有的队员就会被解雇了,但是,为了小组的正常运转,即使工作再闲,小组的队员也不能少于两个。
4、通过调整 produceTaskSleepTime和 consumeTaskSleepTime的大小来实现对派发任务和处理任务的速度的控制,改变这两个值就可以观察不同速率下程序的工作情况。
5、通过调整4中所指的数据,再加上调整任务丢弃策略,换上其他三种策略,就可以看出不同策略下的不同处理方式。
6、对于其他的使用方法,参看jdk的帮助,很容易理解和使用。
|
android 背景xml |
|
|
<!-- Normal states -->
<item android:state_focused="false" android:state_enabled="true" android:drawable="@drawable/slideshowbutton3default" />
<!-- Disabled states -->
<item android:state_enabled="false" android:drawable="@drawable/slideshowbutton3disable" />
<!-- Focused states -->
<item android:state_focused="true" android:state_enabled="true" android:state_pressed="false" android:drawable="@drawable/slideshowbutton3focus" />
<!-- Pressed -->
<item android:state_pressed="true" android:state_enabled="true" android:drawable="@drawable/slideshowbutton3press" />
|
Android Service实现远程调用 |
|
|
//MyService.java
package com.tcl.kang.demo;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.os.RemoteException;
public class MyService extends Service
{
private ICountService.Stub myBinder = new ICountService.Stub()
{
@Override
public int getCount() throws RemoteException
{
// TODO Auto-generated method stub
return 0;
}
};
@Override
public IBinder onBind(Intent intent)
{
// TODO Auto-generated method stub
return myBinder;
}
}
//下面是ICountService.aidl
package com.tcl.kang.demo;
interface ICountService
{
int getCount();
}
|
查看剩余内存 |
|
|
StringBuffer sbf=new StringBuffer();
private void displayAvailMemory() {
final ActivityManager activityManager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
ActivityManager.MemoryInfo outInfo = new ActivityManager.MemoryInfo();
activityManager.getMemoryInfo(outInfo);
sbf.append("\n================剩余内存:---->").append(outInfo.availMem >> 10).append("k");
Log.i(TAG, sbf.toString());
}
|
Animation |
|
|
public class animation1 extends Animation {
private int mCenterX;
private int mCenterY;
private Camera camera = new Camera();
@Override
public void initialize(int width, int height, int parentWidth,int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCenterX = width / 2;
mCenterY = height / 2;
// setDuration(400);//设置动画时间延时
setDuration(100);// 设置动画时间延时
setFillAfter(true);
// setFillAfter(false);
setInterpolator(new LinearInterpolator());
// setInterpolator(new AccelerateInterpolator());
// setInterpolator(new AccelerateDecelerateInterpolator());
}
@Override
protected void applyTransformation(float interpolatdTime, Transformation t) {
final Matrix matrix = t.getMatrix();
camera.save();
camera.translate(-0.0f, 0.0f, -100.0f);
// camera.rotateX(-8*interpolatdTime);
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-mCenterX, -mCenterY);
matrix.postTranslate(mCenterX, mCenterY);
}
}
|
ImageLoader |
|
|
package com.tcl.appmarket.util;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Handler;
import android.util.Log;
import com.tcl.appmarket.data.AppImageDownloader;
import com.tcl.appmarket.debug.MyLog;
public class ImageLoader
{
public static final String TAG = "ImageLoader";
public static final boolean LOGV = false;
private HashMap<String, SoftReference<Bitmap>> mCache = new HashMap<String, SoftReference<Bitmap>>();
public ArrayList<LoadBitmapBin> mQueue = new ArrayList<LoadBitmapBin>();;
private Handler mHandler;
private boolean mStop;
private LoadBitmapBin inProgressBin;
private boolean threadStarted;
private Context mContext;
private AppImageDownloader appImageDownloader = new AppImageDownloader();;
public interface LoadedCallback
{
void onBitmapLoaded(Bitmap loadedBitmap, int index);
}
public class LoadBitmapBin
{
public int index;
public String url;
public LoadedCallback callback;
/**
* @param i
* Index of the image, it's must be unique and URI is
* computed by it.
* @param cb
*/
public LoadBitmapBin(int i, String urlStr, LoadedCallback cb)
{
index = i;
url = urlStr;
callback = cb;
}
public String geturl()
{
return url;
}
public boolean equals(Object object)
{
LoadBitmapBin bin = (LoadBitmapBin) object;
if (!bin.url.equals(this.url))
{
return false;
} else
{
return true;
}
}
public int hashCode()
{
return index;
}
}
public ImageLoader(Context context, Handler handler)
{
mContext = context;
mHandler = handler;
}
/**
*
* @param position
*
* @param urlStr
*
* @param callback
* @param needToFront
* @return
*/
public Bitmap getBitmap(int position, String urlStr,
LoadedCallback callback, boolean needToFront)
{
if (!threadStarted)
{
start();
}
synchronized (mQueue)
{
if (mQueue != null)
{
LoadBitmapBin loadBin = new LoadBitmapBin(position, urlStr,
callback);
if (inProgressBin == null || !inProgressBin.equals(loadBin))
{
boolean contains = mQueue.contains(loadBin);
if (contains)
{
if (needToFront)
{
mQueue.remove(loadBin);
mQueue.add(0, loadBin);
}
} else
{
if (needToFront)
{
mQueue.add(0, loadBin);
} else
{
mQueue.add(loadBin);
}
}
mQueue.notifyAll();
// mQueue.indexOf(b);
}
}
}
return null;
}
public void clearLoadImage()
{
synchronized (mQueue)
{
if (mQueue != null)
{
mQueue.clear();
}
}
}
synchronized private void start()
{
if (threadStarted)
{
return;
}
threadStarted = true;
mStop = false;
Thread thread = new Thread()
{
public void run()
{
while (!mStop)
{
LoadBitmapBin bin = null;
synchronized (mQueue)
{
if (mQueue.size() > 0)
{
bin = mQueue.remove(0);
inProgressBin = bin;
} else
{
try
{
mQueue.wait();
} catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
if (bin != null)
{
String urlStr = bin.url;
final int index = bin.index;
final LoadedCallback cb = bin.callback;
//MyLog.log("url=" + urlStr);
Bitmap bitmap = null;
//MyLog.log("urlStr=" + urlStr);
bitmap = getBitmap(urlStr);
final Bitmap b = bitmap;
if (mHandler != null)
{
mHandler.post(new Runnable()
{
public void run()
{
cb.onBitmapLoaded(b, index);
}
});
} else
{
cb.onBitmapLoaded(b, index);
}
}
}
}
};
thread.start();
}
protected Bitmap getBitmap(String urlstr)
{
return appImageDownloader.downloadBitmap(urlstr);
}
public void stopLoad()
{
mStop = true;
synchronized (mQueue)
{
mQueue.notifyAll();
}
threadStarted = false;
}
public void stopLoad(String[] urls)
{
synchronized (mQueue)
{
for (String u : urls)
{
if (mQueue.contains(u))
{
mQueue.remove(u);
}
}
}
}
}
|
功能性代码集合 |
|
|
/**
* 将一个字符串写入文件,如果这个文件存在,删除原来的内容
* @param content
*/
private void writeLogToFile(String content)
{
int i = 1;
String name = "/sdcard/tmp.txt";
File file = new File(name);
if(file.exists())
{
file.delete();
try
{
file.createNewFile();
} catch (IOException e)
{
e.printStackTrace();
}
}
try
{
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(file));
bufferedWriter.write(content);
bufferedWriter.close();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
|
MyLog |
|
|
class MyLog
{
/**
* 打印Log,包含类名,行数
* @param string
* 要打印的内容
*/
public static void log(String string){
StringBuffer sb = new StringBuffer();
StackTraceElement[] stacks = new Throwable().getStackTrace();
sb.append("class: " ).append(stacks[1].getClassName()).append("; method: ").append(stacks[1].getMethodName()).append("; number: ").append(stacks[1].getLineNumber());
Log.v("kang", "kang:"+sb.toString()+"--------->"+string);
}
}
如何取的Java源代码文件中文件名和行号:)
在C/C++的程序,编译器提供了两个宏来支持取得源文件中的行号和文件名,这两个宏是__FILE__,__LINE__
你可以如下的方法打印行号和文件名
查看源代码
打印帮助
1 #include <stdio.h>
2 int main()
3 {
4 fprintf(stdout,"[%s:%d] Hello World!",__FILE__,__LINE__);
5 return 0;
6 }
但是在JAVA下没有这两个宏,那么我们如何来取得文件名和行号,翻阅JDK,我们找到StackTraceElement这个类。这个类可以从Throwable取得,另外也可以从Thread类取得,通过这些我写如下的一个打印行号的测试程序:
查看源代码
打印帮助
01 public class LineNo {
02 public static int getLineNumber() {
03 return Thread.currentThread().getStackTrace()[2].getLineNumber();
04 }
05
06 public static String getFileName() {
07 return Thread.currentThread().getStackTrace()[2].getFileName();
08 }
09 public static void main(String args[]) {
10 System.out.println("["+getFileName()+":"+ getLineNumber()+"]"+"Hello World!");
11 }
12 }
留下一个问题,上面程序中的magic数字 2 代表什么含义呢?
0是thread.getCurrentThread()
1是getLineNumber()
2才是调用getLineNumber的类
|
android数据库 |
|
|
package com.tcl.kang;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class DatabaseHelper extends SQLiteOpenHelper
{
private static final String NAME = "mydatabase";
private static final String TABLE_NAME = "tb_test";
private static final int VERSION = 1;
private String TABLE_NUM="_num";
private String TABLE_DATA="_data";
public DatabaseHelper(Context context)
{
super(context, NAME, null, VERSION);
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
String sql = "CREATE TABLE "
+ TABLE_NAME
+ "(_id INTEGER PRIMARY KEY AUTOINCREMENT,_num text,_data text)";
db.execSQL(sql);// 需要异常捕获
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub
String sql = "drop table " + "tb_test";
db.execSQL(sql);
onCreate(db);
}
/**
* 添加数据
*/
public long insert(String num, String data)
{
SQLiteDatabase db = getWritableDatabase();// 获取可写SQLiteDatabase对象
// ContentValues类似map,存入的是键值对
ContentValues contentValues = new ContentValues();
contentValues.put(TABLE_NUM, num);
contentValues.put(TABLE_DATA, data);
return db.insert(TABLE_NAME, null, contentValues);
}
/**
* /** 删除记录
*
* @param _id
*/
public void delete(String id)
{
SQLiteDatabase db = getWritableDatabase();
db.delete(TABLE_NAME, "_id=?", new String[] { id });
}
/**
* 更新记录的,跟插入的很像
*/
public void update(String _id,String num, String data){
SQLiteDatabase db= getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(TABLE_NUM, num);
contentValues.put("TABLE_DATA", data);
db.update(TABLE_NAME, contentValues,
"_id=?",
new String[]{_id});
}
/**
* 查询所有数据
* @return Cursor
*/
public Cursor select(){
SQLiteDatabase db = getReadableDatabase();
return db.query(
TABLE_NAME,
new String[]{"_id",TABLE_NUM,TABLE_DATA},
null,
null, null, null, "_id desc"); //desc 降序排列,asc 升序排列
}
}
|
xml解析 |
|
|
Android--xml解析(Dom)
文章分类:移动开发
Java代码
1. Xml数据原型为:
2. <?xml version="1.0" encoding="UTF-8"?>
3. <persons>
4. <person id="23">
5. <name>李明</name>
6. <age>30</age>
7. </person>
8. <person id="20">
9. <name>李向梅</name>
10. <age>25</age>
11. </person>
12. </persons>
13. --------------------------------------------------》
14.
15.
16. package cn.android.dom;
17.
18. import java.io.InputStream;
19. import java.util.ArrayList;
20. import java.util.List;
21.
22. import javax.xml.parsers.DocumentBuilder;
23. import javax.xml.parsers.DocumentBuilderFactory;
24. import javax.xml.parsers.ParserConfigurationException;
25.
26. import org.w3c.dom.Document;
27. import org.w3c.dom.Element;
28. import org.w3c.dom.Node;
29. import org.w3c.dom.NodeList;
30.
31. import cn.android.domain.Person;
32.
33. /**
34. * dom解析xml实现类
35. * @author Administrator
36. *
37. * 2010-6-29 下午08:16:27
38. */
39. public class DomParser {
40.
41. /**
42. * 解析xml文件,返回对象集合
43. * @param is xml文件的输入流
44. * @return 对象集合
45. * @throws Exception
46. */
47. public static List<Person> paseXml(InputStream is) throws Exception {
48.
49. //新建一个集合,用于存放解析后的对象
50. List<Person> personList = new ArrayList<Person>();
51.
52. //创建对象引用
53. Person person = null;
54.
55. //得到Dom解析对象工厂
56. DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
57.
58. //通过工厂创建Dom解析对象实例
59. DocumentBuilder db = factory.newDocumentBuilder();
60.
61. //将xml文件的输入流交给Dom解析对象进行解析,并将Dom树返回。
62. Document document = db.parse(is);
63.
64. //通过Dom树接收到根元素
65. Element rootElement = document.getDocumentElement();
66.
67. //通过根元素获得下属的所有名字为person节点
68. NodeList nodeList = rootElement.getElementsByTagName("person");
69.
70. //遍历取出来的person节点集合
71. for (int i = 0; i < nodeList.getLength(); i++) {
72.
73. //得到一个person节点
74. Element personElement = (Element) nodeList.item(i);
75.
76. //新建一个Person对象
77. person = new Person();
78.
79. //将xml标签的Id属性值赋值给Person对象的Id属性
80. person.setId(new Integer(personElement.getAttribute("id")));
81.
82. //得到person标签的下属所节点
83. NodeList personChildList = personElement.getChildNodes();
84.
85. //循环的到的下属标签
86. for (int y = 0; y < personChildList.getLength(); y++) {
87.
88. //创建一个引用,指向循环的标签
89. Node node = personChildList.item(y);
90.
91. //如果此循环出来的元素是 Element对象,即标签元素,那么执行以下代码
92. if (Node.ELEMENT_NODE == node.getNodeType()) {
93.
94. //如果这个标签的名字是name,那么得到它的值,赋值给Person对象
95. if("name".equals(node.getNodeName())) {
96. String nameValue = node.getFirstChild().getNodeValue();
97. person.setName(nameValue);
98. }
99.
100. //如果这个标签的名字是age,那么得到它的值,赋值给Person对象
101. if("age".equals(node.getNodeName())) {
102. String ageValue = node.getFirstChild().getNodeValue();
103. person.setAge(new Short(ageValue));
104. }
105. }
106.
107. }
108.
109. //将此person对象添加到personList中
110. personList.add(person);
111.
112. //将person制空
113. person = null;
114.
115. }
116.
117. //返回xml解析后得到的对象集合
118. return personList;
119.
120. }
121.
122.
123. }
下面是写XML
2008-11-26
java写XML数据
源文件src
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.jdom.input.SAXBuilder;
import org.jdom.output.XMLOutputter;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
/**
* 功能:
* @author yaos email: yaos@isoftstone-ai.com
* @date 2008 11 25
*/
public class TestParseDOM {
/**
* 功能:
* @param args
* @throws TransformerException
*/
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException, TransformerException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
Element root = doc.createElement("school");
for(int i = 1 ; i <= 3 ; i ++){
Element grade = doc.createElement("grade");
grade.setAttribute("level", String.valueOf(i));
for(int j = 1 ; j <= 2 ; j ++){
Element classes = doc.createElement("classes");
classes.setAttribute("name", String.valueOf(j));
Element teacher = doc.createElement("teacher");
teacher.setTextContent("teacher"+String.valueOf(i+j));
Element monitor = doc.createElement("monitor");
monitor.setTextContent("stu"+String.valueOf(i+j));
Element number = doc.createElement("number");
number.setTextContent(String.valueOf(i*j+i*j));
classes.appendChild(teacher);
classes.appendChild(monitor);
classes.appendChild(number);
grade.appendChild(classes);
}
root.appendChild(grade);
}
doc.appendChild(root);
//下面的方法是写xml到.xml的文档
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();//此实例可以用于处理来自不同源的 XML,并将转换输出写入各种接收器。
DOMSource source = new DOMSource(doc);//创建带有 DOM 节点的新输入源
transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");//设置转换中实际的输出属性
transformer.setOutputProperty(OutputKeys.INDENT, "yes");//设置转换中实际的输出属性
PrintWriter pw = new PrintWriter(new FileOutputStream("src/testDOM.xml"));
StreamResult result = new StreamResult(pw);//从字节流构造 StreamResult 充当转换结果的持有者,可以为 XML、纯文本、HTML 或某些其他格式的标记
transformer.transform(source, result);//将 XML Source 转换为 Result
}
}
运行之后的结果应该是:
<?xml version="1.0" encoding="GB2312"?>
<school>
<grade level="1">
<classes name="1">
<teacher>teacher2</teacher>
<monitor>stu2</monitor>
<number>2</number>
</classes>
<classes name="2">
<teacher>teacher3</teacher>
<monitor>stu3</monitor>
<number>4</number>
</classes>
</grade>
<grade level="2">
<classes name="1">
<teacher>teacher3</teacher>
<monitor>stu3</monitor>
<number>4</number>
</classes>
<classes name="2">
<teacher>teacher4</teacher>
<monitor>stu4</monitor>
<number>8</number>
</classes>
</grade>
<grade level="3">
<classes name="1">
<teacher>teacher4</teacher>
<monitor>stu4</monitor>
<number>6</number>
</classes>
<classes name="2">
<teacher>teacher5</teacher>
<monitor>stu5</monitor>
<number>12</number>
</classes>
</grade>
</school>
下面是写读书程序时解析xml的代码
package test;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
class MyLog
{
/**
* 打印Log,包含类名,行数
* @param string
* 要打印的内容
*/
public static void log(String string ){
StringBuffer sb = new StringBuffer();
StackTraceElement[] stacks = new Throwable().getStackTrace();
sb.append("class: " ).append(stacks[1].getClassName()).append("; method: ").append(stacks[1].getMethodName()).append("; number: ").append(stacks[1].getLineNumber());
System.out.println("kang:"+sb.toString()+"--------->"+string);
}
}
class BookSetItemInfo
{
private int textColor;
private int backGroudColor;
private int textSize;
private int speakSpeed;
public int getSpeakSpeed()
{
return speakSpeed;
}
public void setSpeakSpeed(int speakSpeed)
{
this.speakSpeed = speakSpeed;
}
public int getTextSize()
{
return textSize;
}
public void setTextSize(int textSize)
{
this.textSize = textSize;
}
public int getBackGroudColor()
{
return backGroudColor;
}
public void setBackGroudColor(int backGroudColor)
{
this.backGroudColor = backGroudColor;
}
public int getTextColor()
{
return textColor;
}
public void setTextColor(int textColor)
{
this.textColor = textColor;
}
}
class BookMarkInfo
{
private String bookMarkName;
private int bookMarkValue;
/**
* @return the bookMarkValue
*/
public int getBookMarkValue()
{
return bookMarkValue;
}
/**
* @param value the bookMarkValue to set
*/
public void setBookMarkValue(int value)
{
this.bookMarkValue = value;
}
/**
* @return the bookMarkName
*/
public String getBookMarkName()
{
return bookMarkName;
}
/**
* @param bookMarkName the bookMarkName to set
*/
public void setBookMarkName(String bookMarkName)
{
this.bookMarkName = bookMarkName;
}
}
class BookMark
{
private FileInputStream bookMarkFileInputStream;
private final int COUNT_OF_BOOKMARD =10;//标签条数设为10
private void createNullXML(String bookMarkPath)
{
File file = new File(bookMarkPath);
try
{
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "gb2312"));
bufferedWriter.write("<?xml version=\"1.0\" encoding=\"gb2312\"?>\r\n<BookMark>\r\n</BookMark>");
bufferedWriter.close();
} catch (UnsupportedEncodingException e)
{
MyLog.log("error");
e.printStackTrace();
} catch (FileNotFoundException e)
{
MyLog.log("error");
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 打开书签文件,如果文件不存在,自动创建
* @param bookMarkPath
* 书签文件完整路径
*/
private Document bookMarkOpen(String bookMarkPath)
{
File file = new File(bookMarkPath);
Document bookMarkDocument =null;
if(!file.exists())
{
createNullXML(bookMarkPath);
}
try
{
bookMarkFileInputStream = new FileInputStream(file);
} catch (FileNotFoundException e)
{
MyLog.log("error");
e.printStackTrace();
}
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder db = null;
try
{
db = factory.newDocumentBuilder();
} catch (ParserConfigurationException e)
{
MyLog.log("error");
e.printStackTrace();
}
try
{
bookMarkDocument = db.parse(bookMarkFileInputStream);
} catch (SAXException e)
{
MyLog.log("error");
e.printStackTrace();
} catch (IOException e)
{
MyLog.log("error");
e.printStackTrace();
}
return bookMarkDocument;
}
private void bookMarkClose()
{
try
{
bookMarkFileInputStream.close();
} catch (IOException e)
{
MyLog.log("error");
e.printStackTrace();
}
}
/**
* 保存XML文件
* @param document
* @param pathString
* XML文件完整路径
*/
private void xmlSave(Document document,String bookMarkPath)
{
TransformerFactory tf = TransformerFactory.newInstance();
try
{
Transformer transformer = tf.newTransformer();//此实例可以用于处理来自不同源的 XML,并将转换输出写入各种接收器。
DOMSource source = new DOMSource(document);//创建带有 DOM 节点的新输入源
transformer.setOutputProperty(OutputKeys.ENCODING, "gb2312");//设置转换中实际的输出属性
transformer.setOutputProperty(OutputKeys.INDENT, "yes");//设置转换中实际的输出属性
PrintWriter pw=null;
try
{
pw = new PrintWriter(new OutputStreamWriter(new FileOutputStream(bookMarkPath), "gb2312"));
} catch (UnsupportedEncodingException e)
{
MyLog.log("error");
e.printStackTrace();
}
StreamResult result = new StreamResult(pw);//从字节流构造 StreamResult 充当转换结果的持有者,可以为 XML、纯文本、HTML 或某些其他格式的标记
transformer.transform(source, result);//将 XML Source 转换为 Result
} catch (TransformerConfigurationException e)
{
MyLog.log("error");
e.printStackTrace();
} catch (FileNotFoundException e)
{
MyLog.log("error");
e.printStackTrace();
} catch (TransformerException e)
{
MyLog.log("error");
e.printStackTrace();
}
}
/**
* 保存书签
* @param bookMarkPath
* 书签XML文件完整路径
* @param bookName
* 书名
* @param key
* 书签名
* @param value
* 页码
* @param timeModify
* 书的最后一次修改时间
*/
public void bookMarkSave(String bookMarkPath,String bookShortName,String key,int value,long timeModify)
{
Document document;
// bookName = "![CDATA["+bookName+"]]>";
// key = "![CDATA["+key+"]]>";//防止特殊符号
document = bookMarkOpen(bookMarkPath);
Element rootElement = document.getDocumentElement();
NodeList bookNodeList = rootElement.getElementsByTagName("Book");// 一级链表
if (bookNodeList.getLength() == 0)// 没有任何书的节点
{
MyLog.log("there is no book");
creatBook(bookMarkPath, bookShortName, key, value, timeModify, document,
rootElement);
return;
} else
{
MyLog.log("there has books");
for (int i = 0; i < bookNodeList.getLength(); i++)
{
NodeList bookItemNodeList = bookNodeList.item(i)
.getChildNodes();
Element bookNameElement = null;// 书名节点
Element bookTimeModifyElement = null;// 修改时间节点
Element bookMarkItemElement = null;// 存书签的节点
for (int j = 0; j < bookItemNodeList.getLength(); j++)
{
if (bookItemNodeList.item(j).getNodeType() == Node.ELEMENT_NODE)// 如果是有效节点
{
Element bookMark = (Element) bookItemNodeList.item(j);
String tmpString = bookMark.getNodeName();
// MyLog.log("tmpString="+tmpString);
if (tmpString.equals("BookName"))// 是书名元素
{
bookNameElement = bookMark;
} else if (tmpString.equals("BookModifyTime"))// 修改时间元素
{
bookTimeModifyElement = bookMark;
} else if (tmpString.equals("BookMarkItem"))
{
bookMarkItemElement = bookMark;
}
}
}
String bookNameString = bookNameElement.getTextContent();// 得到书名
String bookTimeModifyString = bookTimeModifyElement
.getTextContent();// 得到修改时间
// 书名相同,修改时间不同,则删除原来所有书签并更新修改时间
if (bookNameString.equals(bookShortName)
&& (!bookTimeModifyString.equals(String
.valueOf(timeModify))))
{
MyLog.log("name is equal,and timeModify is not equal");
bookTimeModifyElement.setTextContent(String
.valueOf(timeModify));// 更新修改时间
Element bookElement = (Element) bookNameElement
.getParentNode();
NodeList bookMarkItemNodeList = bookElement
.getElementsByTagName("BookMarkItem");
for (int k = 0; k < bookMarkItemNodeList.getLength(); k++)
{
if (bookMarkItemNodeList.item(k).getNodeType() == Node.ELEMENT_NODE)
{
bookMarkItemNodeList.item(k).getParentNode()
.removeChild(bookMarkItemNodeList.item(k));
}
}
createBookMark(bookMarkPath, key, value, document,
bookElement);
return;
}
// /////////////书名相同,修改时间相同,即为同一本书
else if (bookNameString.equals(bookShortName)
&& bookTimeModifyString.equals(String
.valueOf(timeModify)))
{
MyLog.log("this book has exist");
Element bookElement = (Element) bookNameElement
.getParentNode();
NodeList bookMarkItemNodeList = bookElement
.getElementsByTagName("BookMarkItem");
int count = bookMarkItemNodeList.getLength();
for (int k = 0; k < bookMarkItemNodeList.getLength(); k++)// 查找是否有重复书签
{
// 找到相同书签
if (((Element) bookMarkItemNodeList.item(k))
.getElementsByTagName("BookMarkItemKey")
.item(0).getTextContent().equals(key))
{
MyLog.log("this bookmark has exist");
// 删除此书签
bookMarkItemNodeList.item(k).getParentNode()
.removeChild(bookMarkItemNodeList.item(k));
// 创建新书签
createBookMark(bookMarkPath, key, value, document,
bookElement);
return;
}
}
// 现有书签条数已满,删除第一条
if (count == this.COUNT_OF_BOOKMARD)
{
MyLog.log("bookmark is full");
bookMarkItemNodeList.item(0).getParentNode()
.removeChild(bookMarkItemNodeList.item(0));
createBookMark(bookMarkPath, key, value, document,
bookElement);
return;
} else
{
MyLog
.log("this bookmark is not exist and count is not full");
createBookMark(bookMarkPath, key, value, document,
bookElement);
return;
}
} else
{
creatBook(bookMarkPath, bookShortName, key, value, timeModify, document,
rootElement);
xmlSave(document, bookMarkPath);
bookMarkClose();
return;
}
}
}
return;
}
private void creatBook(String bookMarkPath, String bookName, String key,
int value, long timeModify, Document document, Element rootElement)
{
Element bookMark = document.createElement("Book");//二级节点
Element bookNameElement = document.createElement("BookName");//三级节点
bookNameElement.setTextContent(bookName);//设置书名
bookMark.appendChild(bookNameElement);
Element bookModifyTime = document.createElement("BookModifyTime");////三级节点
bookModifyTime.setTextContent(String.valueOf(timeModify));//设置修改时间
bookMark.appendChild(bookModifyTime);
Element bookMarkItem = document.createElement("BookMarkItem");//三级节点
Element bookMarkItemKey = document.createElement("BookMarkItemKey");//四级节点
bookMarkItemKey.setTextContent(key);
bookMarkItem.appendChild(bookMarkItemKey);
Element bookMarkItemValue = document.createElement("BookMarkItemValue");//四级节点
bookMarkItemValue.setTextContent(String.valueOf(value));
bookMarkItem.appendChild(bookMarkItemValue);
bookMark.appendChild(bookMarkItem);//三级节点末
rootElement.appendChild(bookMark);
xmlSave(document, bookMarkPath);
bookMarkClose();
}
private void createBookMark(String bookMarkPath, String key, int value,
Document document, Element bookElement)
{
Element newBookMarkItemElement = document.createElement("BookMarkItem");//创建新元素
Element newBookMarkItemKeyElement = document.createElement("BookMarkItemKey");
newBookMarkItemKeyElement.setTextContent(key);
Element newBookMarkItemValueElement = document.createElement("BookMarkItemValue");
newBookMarkItemValueElement.setTextContent(String.valueOf(value));
newBookMarkItemElement.appendChild(newBookMarkItemKeyElement);
newBookMarkItemElement.appendChild(newBookMarkItemValueElement);
bookElement.appendChild(newBookMarkItemElement);
xmlSave(document, bookMarkPath);
bookMarkClose();
return;
}
/**
* 导出一本书的书签
* @param bookMarkPath
* 书签XML路径
* @param bookName
* 书名
* @param timeModify
* 书最后一次修改时间
* @return
* 书签链表
*/
public ArrayList<BookMarkInfo> bookMarkLoad(String bookMarkPath,String bookShortName,long timeModify)
{
Document document;
document = bookMarkOpen(bookMarkPath);
Element rootElement = document.getDocumentElement();
NodeList bookNodeList = rootElement.getElementsByTagName("Book");
ArrayList<BookMarkInfo> list = new ArrayList<BookMarkInfo>();
if(bookNodeList.getLength() == 0)//没有书节点
{
bookMarkClose();
return list;
}
else
{
for(int i=0;i<bookNodeList.getLength();i++)
{
Element bookElement = (Element) bookNodeList.item(i);
String keyString= bookElement.getElementsByTagName("BookName").item(0).getTextContent();
String valueString = bookElement.getElementsByTagName("BookModifyTime").item(0).getTextContent();
//找到这本书
if((keyString.equals(bookShortName))&& valueString.equals(String.valueOf(timeModify)))
{
MyLog.log("find the book");
NodeList bookMarkItemNodeList = bookElement.getElementsByTagName("BookMarkItem");
ArrayList<BookMarkInfo> arrayList = new ArrayList<BookMarkInfo>();
for(int j=0;j<bookMarkItemNodeList.getLength();j++)
{
Element bookMarkItemElement = (Element)bookMarkItemNodeList.item(j);
String tmpKeyString = bookMarkItemElement.getElementsByTagName("BookMarkItemKey").item(0).getTextContent();
int tmpValue = Integer.valueOf(bookMarkItemElement.getElementsByTagName("BookMarkItemValue").item(0).getTextContent()).intValue();
BookMarkInfo bookMarkInfo = new BookMarkInfo();
bookMarkInfo.setBookMarkName(tmpKeyString);
bookMarkInfo.setBookMarkValue(tmpValue);
arrayList.add(bookMarkInfo);
}
for(int j=arrayList.size()-1;j>=0;j--)//将链表排序翻转
{
list.add(arrayList.get(j));
}
return list;
}
}
}
MyLog.log("not find the book");
return list;//没有找到这本书的书签
}
}
public class Hello
{
public static void main(String [] args)
{
String string = "";
new BookMark().bookMarkSave("C:\\Documents and Settings\\Administrator\\桌面\\BOOKMARK.xml", "bbb", "c"+string, 1, 2000);
BookSetItemInfo bookSetItemInfo = new BookSetItemInfo();
bookSetItemInfo.setBackGroudColor(2);
bookSetItemInfo.setSpeakSpeed(1);
bookSetItemInfo.setTextColor(1);
bookSetItemInfo.setTextSize(1);
// new BookMark().bookSetSave("C:\\Documents and Settings\\Administrator\\桌面\\BOOKMARK.xml", bookSetItemInfo);
// BookSetItemInfo bookSetItemInfo2 = new BookMark().bookSetLoad("C:\\Documents and Settings\\Administrator\\桌面\\BOOKMARK.xml");
// MyLog.log(""+bookSetItemInfo2.getBackGroudColor()+bookSetItemInfo2.getSpeakSpeed()+bookSetItemInfo2.getTextColor());
// ArrayList<BookMarkInfo> arrayList = new BookMark().bookMarkLoad("C:\\Documents and Settings\\Administrator\\桌面\\BOOKMARK.xml", "bbbb", 2000);
// for(int i=0;i<arrayList.size();i++)
// {
// System.out.println("======"+arrayList.get(i).getBookMarkName());
// }
// ArrayList<String> arrayList = getAllTxtBooks("C:\\Documents and Settings\\Administrator\\桌面\\BOOKS");
// for(int i =0;i < arrayList.size();i++)
// {
// MyLog.log(arrayList.get(i));
// }
// MyLog.log(bookCheckCoverPic("C:\\Documents and Settings\\Administrator\\桌面\\TCLBOOKS", "3"));
}
/**
* 将制定文件夹下所有txt文件列出来
*
* @param booksFolderPath
* 文件夹路径
* @return
* 文件名链表
*/
private static ArrayList<String> getAllTxtBooks(String booksFolderPath)
{
ArrayList<String> arrayList = new ArrayList<String>();
File bookFolderFile = new File(booksFolderPath);
File[] fileArray = bookFolderFile.listFiles();
if(fileArray == null)//如果没有此目录
return arrayList;
for (int i = 0; i < fileArray.length; i++)
{
File tmpFile = fileArray[i];
// MyLog.log(tmpFile.getName());
// ////////////////////判断是不是txt文件
String tmpNameString = tmpFile.getName();
Pattern pattern = Pattern.compile(".+[.]txt");
Matcher m = pattern.matcher(tmpNameString);
boolean b = m.matches();
if (b == true)
{
String tmpString = getFileNameByFullName(tmpFile.getName());
arrayList.add(tmpString);
}
// ///////////////////
}
return arrayList;
}
/**
* 从完整文件名中提取前面部分,如1.txt中提取1
* @param FileFullName
* 完整文件名
* @return
* 文件名前部分
*/
private static String getFileNameByFullName(String FileFullName)
{
String fileNameString = null;
int index = FileFullName.lastIndexOf(".");
//MyLog.log("index="+index);
fileNameString = FileFullName.substring(0, index);
return fileNameString;
}
/**
* 将制定文件夹下所有文件列出来
*
* @param booksFolderPath
* 文件夹路径
* @return
* 文件名完整名字链表
*/
private static ArrayList<String> getAllBooksFullName(String booksFolderPath)
{
ArrayList<String> arrayList = new ArrayList<String>();
File bookFolderFile = new File(booksFolderPath);
File[] fileArray = bookFolderFile.listFiles();
if(fileArray == null)
return arrayList;
for (int i = 0; i < fileArray.length; i++)
{
File tmpFile = fileArray[i];
String tmpNameString = tmpFile.getName();
arrayList.add(tmpNameString);
}
return arrayList;
}
/**
* 根据书名查找对应的封面图片,支持格式:PNG
* @param booksFolderPath
* 文件夹路径
* @param fileName
* 书名
* @return
* 书的封面图片完整名,如果没有找到返回null
*/
private static String bookCheckCoverPic(String booksFolderPath,String fileName)
{
ArrayList<String> arrayList = getAllBooksFullName(booksFolderPath);
Pattern pattern = Pattern.compile(fileName+"[.]"+"[p,P][n,N][g,G]");
for(int i = 0 ;i< arrayList.size();i++)
{
String bookNameString = arrayList.get(i);
Matcher matcher = pattern.matcher(bookNameString);
boolean flag = matcher.matches();
if(flag == true)
{
return bookNameString;
}
}
return null;
}
}
|
Rect |
|
|
// View view = grid.getChildAt(Global.getFocus());
// ImageView imageView = (ImageView) view.findViewById(R.id.img);
// int left = imageView.getLeft();
// int top = imageView.getTop();
// int bottom = imageView.getBottom();
// Rect rect2 = new Rect();
// imageView.getGlobalVisibleRect(rect2);
// MyLog.log("rect2 left="+rect2.left+" top="+rect2.top+" right="+rect2.right+" bottom="+rect2.bottom);
// Rect rect3= new Rect();
// imageView.getDrawingRect(rect3);
// MyLog.log("rect3 left="+rect3.left+" top="+rect3.top+" right="+rect3.right+" bottom="+rect3.bottom);
// Rect rect4 = new Rect();
// imageView.getLocalVisibleRect(rect4);
// MyLog.log("rect4 left="+rect4.left+" top="+rect4.top+" right="+rect4.right+" bottom="+rect4.bottom);
// Rect rect5 = new Rect();
// imageView.getHitRect(rect5);
// MyLog.log("rect5 left="+rect5.left+" top="+rect5.top+" right="+rect5.right+" bottom="+rect5.bottom);
// int right= imageView.getRight();
// MyLog.log("image :left="+left+" top="+top+" right="+right+" bottom="+bottom);
// left=0 top=0 right=182 bottom=143
// rect2 left=118 top=145 right=286 bottom=270
// rect3 left=0 top=0 right=168 bottom=125
// rect4 left=0 top=0 right=168 bottom=125
// rect5 left=7 top=9 right=175 bottom=134
// image :left=7 top=9 right=175 bottom=134
|