Java DOM 设置 XML 缩进

            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer transformer = tf.newTransformer();
            DOMSource source = new DOMSource(mDocument);

            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");//缩进宽度
            transformer.setOutputProperty(OutputKeys.METHOD, "xml");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

Java Enum

Java的Enum搞的越来越强大,用着也越来越别扭。看看下面的代码:

public class TestJavaEnum {

    static enum WorkDay {
        Mon("Monday"),
        Tue("Tuesday"),
        Wed("Wednesday"),
        Thu("Thursday"),
        Fri("Friday");

        private String mDay;

        private WorkDay(String day) {
            mDay = day;
        }

        @Override
        public String toString() {
            return mDay;
        }
    }

    public static void main(String[] args) {
        WorkDay[] workDays = WorkDay.values();

        System.out.println("------WorkDay------");
        for (int i = 0; i < workDays.length; i++) {
            WorkDay workDay = workDays[i];
            System.out.println(workDay.toString());
        }

        System.out.println("------Ordinal------");

        for (int i = 0; i < workDays.length; i++) {
            WorkDay workDay = workDays[i];
            System.out.println(workDay.toString() + "'s ordinal is "
                    + workDay.ordinal());
        }

        System.out.println("------ValueOf------");

        System.out.println(WorkDay.valueOf("Mon"));

    }
}

Output:

------WorkDay------
Monday
Tuesday
Wednesday
Thursday
Friday
------Ordinal------
Monday's ordinal is 0
Tuesday's ordinal is 1
Wednesday's ordinal is 2
Thursday's ordinal is 3
Friday's ordinal is 4
------ValueOf------
Monday

下面我们反编译看一下,Java究竟对Enum做了啥?

javap -c TestJavaEnum\$WorkDay

从反编译的结果中我们发现了下面的代码:

final class net.lnmcc.TestJavaEnum$WorkDay extends java.lang.Enum{

这说明Java中的Enum实际上是继承了java.lang.Enum的类。 继续往下看反编译的结果有:

public static final net.lnmcc.TestJavaEnum$WorkDay Mon;
public static final net.lnmcc.TestJavaEnum$WorkDay Tue;
public static final net.lnmcc.TestJavaEnum$WorkDay Wed;
public static final net.lnmcc.TestJavaEnum$WorkDay Thu;
public static final net.lnmcc.TestJavaEnum$WorkDay Fri;

我们定义的的每一个Enum值都成了一个WorkDay Class的静态对象。 继续往下看:

   0:	new	#1; //class net/lnmcc/TestJavaEnum$WorkDay
   3:	dup
   4:	ldc	#18; //String Mon
   6:	iconst_0
   7:	ldc	#19; //String Monday
   9:	invokespecial	#21; //Method "<init>":(Ljava/lang/String;ILjava/lang/String;)V
   12:	putstatic	#25; //Field Mon:Lnet/lnmcc/TestJavaEnum$WorkDay;
   15:	new	#1; //class net/lnmcc/TestJavaEnum$WorkDay
   18:	dup

原来Java会调用构造方法来构造我们的Enum对象,参数即为定义Enum时我们在括号中给出的值。 到这里对Java Enum的实现算是清楚了,但是呢,用起来还是别扭,哈哈。

Git 修改历史提交

修改最后一次提交

git commit --amend	

修改非最后一次提交

git rebase -i HEAD~3

-i参数的含义: --interactive  let the user edit the list of commits to rebase
HEAD~3: 需要修改倒数第三个提交

之后出现如下界面:

Alt none

把你想要修改的提交记录前的pick改成edit

下图说明我想修改7013c8c这个提交(PS:可以同时修改多个):

Alt none

保存后,git会出现提示:

Alt none

输入

git commit --amend

Alt none

弹出的界面跟第一种情况一样,你可以开始修改你的提交说明了。

最后保存你的修改。

最后执行

git rebase --continue

完成操作。如果一次选择了多个提交需要修改,只需要多次执行git commit –amendgit rebase –continue即可。

Android设置系统首次开机的默认输入法

Android OS: 4.4.4 需求:Android系统首次开机(恢复出厂状态),读取build.prop中的属性来设置默认的输入法。

增加系统属性

ro.product.IME.default

修改InputMethodService

打开文件 frameworks/base/services/java/com/android/server/InputMethodManagerService.java

增加如下方法:

    /**
     * 0: not first boot
     * 1: first boot
     */
    static final String FIRST_BOOT_FLAG = "first_boot_flag";

    private void setCustomDefaultIME() {
        int firstBootFlag = Settings.System.getInt(
                mContext.getContentResolver(), FIRST_BOOT_FLAG, 1);
        if(DEBUG)
            Slog.d(TAG, "First Boot Flag: " + firstBootFlag);

        if (1 == firstBootFlag) {// first boot
            String defaultIme = SystemProperties.get("ro.product.IME.default", "");
            if(DEBUG)
                Slog.d(TAG, "Customer Default IME: " + defaultIme);

            if (defaultIme != null && defaultIme.length() > 0)
                mSettings.putSelectedInputMethod(defaultIme);

            // set first boot flag to 0
            Settings.System.putInt(mContext.getContentResolver(),
                    FIRST_BOOT_FLAG, 0);
        }
    }

在InputMethodManagerService()的构造方法中调用它:

        // mSettings should be created before buildInputMethodListLocked
        mSettings = new InputMethodSettings(
                mRes, context.getContentResolver(), mMethodMap, mMethodList, userId);
        mFileManager = new InputMethodFileManager(mMethodMap, userId);
        mImListManager = new InputMethodAndSubtypeListManager(context, this);

        setCustomDefaultIME();

        // Just checking if defaultImiId is empty or not
        final String defaultImiId = mSettings.getSelectedInputMethod();
        if (DEBUG) {
            Slog.d(TAG, "Initial default ime = " + defaultImiId);
        }
        mImeSelectedOnBoot = !TextUtils.isEmpty(defaultImiId);

点击 这里 查看如何在Android源码中增加自定义属性

Android 自定义系统属性

增加自定义属性涉及的文件: /build/toos/buildinfo.sh

比如这里增加了一个系统默认输入法的属性:

echo "ro.product.IME.default=com.android.inputmethod.pinyin/.PinyinIME"

也可以加在device目录下的system.prop文件中,最终都会输出到build.prop

rebuild出来的system.img中的build.prop就有了上面的属性。

通过下面的代码来访问这个自定义属性:

String defaultIme = SystemProperties.get("ro.product.IME.default",  "com.android.inputmethod.latin/.LatinIME");

这里的SystemProperties为@hide类,所以需要在Android Source中使用上面的代码。

有了需要的属性后,就可以在Android机器中修改这个属性值了,但是需要注意一点: 如果是通过adb pull后再push到android机器的话,需要确保build.prop文件的权限为644,否则进不了系统。