`
收藏列表
标题 标签 来源
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
Global site tag (gtag.js) - Google Analytics