Which Java logging library i should use? 2013

標籤

, ,

Just saw an article about the log4j 2 and its async appender. (Log4j 2: Performance close to insane)

According to the article, log4j 2 is better then log4j and logback. (e.g. performance and design).

Some advantages of log4j 2:

  • will not lose events while reconfiguring
  • performs locking at the lowest level possible; (there is deadlock issue on old log4j)
  • lock-free Asynchronous Loggers based on the LMAX Disruptor library
  • Can reload configuration automatically
  • etc…

However, log4j 2 is still is beta version. Therefore, i will choose logback in current project. (Personally, i do not want to use 3rd parties library which is in beta/snapshot version)

Some advantages of logback

  • Better performance than old log4j (I have no bench mark related to it; but some people said so)
  • Implement interfaces of SLF4J natively
  • Can reload configuration automatically
  • more: Reasons to prefer logback over log4j (for old log4j)

There is no reason for me to use old log4j and i think i will try the log4j 2 later. 🙂

Basic OO Design Principle

Base Object-Oriented Design Principle:

1. Open-Closed Principle (OCP)

Classes should be open for extension and closed for modification.

2. Don’t Repeat Yourself Principle (Dry)

Avoid duplicate code by abstracting out things that are common and placing those things in a single location.

3. Single Responsibility Principle (SRP)

Every object should have a single responsibility and all the object’s services should be focused on carrying out that single responsibility.

4. Liskov Substitution Principle (LSP)

Subtypes must be substitutable for their base types.

 

 

p.s. i typed this post when it is 2011 but i forgot to post it out… 😦

Android Dev: Device policy manager

標籤

, ,

Device policy manager是Android 2.2的新東西。因為application的permission上的不足,所以需要"Device Administrator"去控制一些安全上的特性。

在Android 2.2上,這些特性有︰

  1. 鎖屏
  2. 密碼長度及質量
  3. 重設密碼
  4. 登入監控
  5. 消除application數據

基本上,Device policy manager 最重要是要有一個"Device Administrator Receiver"去接收Device Admin的相關�信息相信信信信息和使用DevicePolicyManager去執行Device Admin相關的動作。

Device Administrator Receiver

這個Device Administrator Receiver必須

  1. 是DeviceAdminReceiver的子類
  2. 有 BIND_DEVICE_ADMIN permission
  3. 在intent filter定義ACTION_DEVICE_ADMIN_ENABLED

首先要在AndroidManifest.xml定義好Receiver:

<receiver android:name=".MyDeviceAdmin"
          android:label="@string/device_admin"
          android:description="@string/device_admin_description"
          android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin" android:resource="@xml/device_admin" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

這個recevier須要listenandroid.app.action.DEVICE_ADMIN_ENABLED這個動作。還要用android.app.device_admin去指定另一個xml檔去定義這個Device Admin需要的permission。

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <!-- List the needed permission(s) -->
    <limit-password />
    <watch-login />
    <reset-password />
    <force-lock />
    <wipe-data />
  </uses-policies>
</device-admin>

public class MyDeviceAdmin extends DeviceAdminReceiver {
  // 只需overrided相應action的method就可以了(例如onEnabled -> 當本application的Device Admin帔啓動)。
}

DevicePolicyManager

Get DevicePolicyManager from Activity:

DevicePolicyManager mDPM = (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);

Check if the Device Admin is activated:

mDPM.isAdminActive(componentName)

componentName是DeviceAdminReceiver的ComponentName.
DevicePolicyManager的具體用法可以去看看API.

Android Dev: Signing Application

標籤

,

Signing Application概要

關於signing android application大家都要注要以下的東西︰

  1. 每一個android application都必須要用digital certificate的private key去sign的。
  2. 不會以certificate作為認証,所以可以用self-signed certificate。
  3. 發佈的application不能用SDK用作debug的key去sign。
  4. 當安裝application的時候才會檢查certificate的屆滿期限。
  5. 可以為Keytool或Jarsigner去sign .apk 檔 。
  6. 用zipalign去優化signed application 。
  7. Upgrade application的時候新版本和舊版本的signature必須一樣。
  8. signature-based permissions – 使用相同的signature的application可以用這個權限分享code或data。

Signature in Debug Mode

SDK自動生成的signature有以下的属性︰

  1. Keystore name: “debug.keystore"
  2. Keystore password: “android"
  3. Key alias: “androiddebugkey"
  4. Key password: “android"
  5. CN: “CN=Android Debug,O=Android,C=US"

大家可以替換這個signature,但是要注要的是Keystore name,Keystore password和Key alias都要和以上的一樣。
這個debug keystore的默認路徑是︰

  • Linux/OS X︰~/.android/avd/debug.keystore
  • Windows︰%HOME_DIR%\.android/debug.keystore

如果debug certificate過期了,可以移除這個debug.keystore。下次build application就會再次自動生成debug.keystore。
如果用Eclipse/ADT,可以在Windows > Preferences > Android > Build 替換debug signature。

Signature in Release Mode

Java SDK的keytools可以用來生成private key的︰

keytool -genkey -v -keystore key-file.keystore -alias alias_name -keyalg RSA -keysize 2048 -validity 365

之後keytool會要求輸入private key和keystore的密碼,還有certificate的information。完成後,一個儲在key-file.keystore的別名為alias_name的private key便會生成,而這個certitifcate的有效期為365日。

用eclipse sign android application

在Package Explorer選擇project,File > Export。開啟Android folder,選擇Export Android Application。之後跟住wizard一步一步做就可以了。這個Export Wizard會幫你compiled, signed, aligned你的android application。

Android Dev: Block Exit

標籤

,

Block Exit 是十分危險的,因為可能會影響其他application的運作(e.g. phone in)。

要做到Block Exit,首先要在離開該Activity時trigger的methods(e.g. onStop / onPause / onWindowFocusChanged) 上做手腳︰

public class BlockExitActivity extends Activity {   
    private BroadcastReceiver mReceiver;
    public final static String BLOCK_EXIT_ACTION = "suiaing.BLOCK_EXIT";

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
    
    /**
     * Loop back call to keep the lock me activity active.
     */
    private void keepingLockme() {
        Intent loopback = new Intent(BLOCK_EXIT_ACTION);
        getApplicationContext().sendBroadcast(loopback);
    }

    @Override
    protected void onStop() {
        super.onStop();
	keepingLockme();
    }

    @Override
    protected void onPause() {
        super.onPause();
        keepingLockme();
    }


    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        if (!hasFocus) {
            keepingLockme();
        }
    }

    @Override
    public boolean dispatchKeyEvent(KeyEvent event) {       
        // block the key event
        return true;
    }
    
}

當onStop / onPause / onWindowFocusChanged 被調用的時候,broadcast一個intent。有一個BroadcastReceiver去接聽這個broadcast,用重新開始之前的Activity。

public class BlockExitReceiver extends BroadcastReceiver {
    
    @Override
    public void onReceive(Context context, Intent intent) {
        if (BlockExitActivity.BLOCK_EXIT_ACTION.equals(intent.getAction())) {
            Intent blockExitIntent = new Intent();
            lockMeIntent.setClassName("suiaing.blockecit", "BlockExitActivity");
            lockMeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_FROM_BACKGROUND);
            context.startActivity(blockExitIntent);
        }
    }
}

這樣做,這個Activity便不會exit了。因為每次要exit的時候,這個Activity便會重新被調出來。

Android Dev: Miscellaneous Tips

標籤

,

Is System Application

This method can be used to check if the application is system application. The application installed in /system/app is system application.

public static boolean isSystemApplication(Application application) {
    ApplicationInfo appInfo = application.getApplicationInfo();
    if ((appInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
        Log.d(LOG_TAG, "Application '" + appInfo.name + "' is system application.");
        return true;
    }
    return false;
}

Git分佈式流程

標籤

Distributed Workflows(分佈式流程)是DVCS其中一項比傳統VCS優勝的地方。Distributed Workflows最基本的概念是從remote repository clone project下來,修改並commit到local repository,最後再把修改push回remote repository。

從remote到local

最初local什麽也沒有,從remote repository clone 一個project下來吧。(剛剛學android program就clone一個android project下來好了)

$ git clone git://android.git.kernel.org/platform/packages/apps/Music.git

Git做了些什麽呢?Git其實是clone了remote repository到local的remote branches並建立了local branch(master)。來看看local的remote branches吧。

$ git branch -r
origin/HEAD
origin/master

這些以"origin/"為首的就是local的remote branches。Git就是用這些branches和remote reposity打交道。

如果人們修改了remote repository的檔案,要如何取得這些修改呢。就是把remote repository的修改fetch下來。

$ git fetch

這個fetch命令只是把remote repository下載到local的remote branches,但不會merge到local branch的。之後就要自己git merge到local branch了。

當然有一些方便的命令可以一次做fetch和merge,這就是push了。

$ git pull

從local到remote

拉(pull)下來的東西當然是要推(push)回去啦。

$ git push

備註

Git是支援多過一個的remote repository的,所以fetch/pull/push的時候是需要加入參數去指定remote repository。

Git分支(Branching)與合併(Merging)

標籤

分支(Branching)

建立分支
Git是可以管理多個分支的。 要建立分支可以用: (假設分支名是testing_branch)

$ git branch testing_branch

之後可以用command看看有什麼分支:

$ git branch
*   master
testing_branch

你可以看到現在所有Git管理的分支,而有" * “的就是現在正在使用的分支。 要轉換到其他分支可以用:

$ git checkout testing_branch

之後就可以在這個branch上工作。

轉換當前分支
如果想建立分支並即時轉換到新分支可以使用:

$ git checkout -b testing_branch2

删除分支
要删除分支可以用git branch的-d參數:

$ git branch -d testing_branch2

這樣git會檢查要删除的分支是否己合併到當前的分支上。如果沒有,則不能删除分支。
如果真的要删除該分支,可以用-D參數去強行删除分支:

$ git branch -D testing_branch2

分支更名
要更改分支名可以用git branch的-m參數:

$ git branch -m old_name new_name

分支合併(Merging)

Merging主要分三種:straight merge, squashed commits,cherry-picking。請緊記合併之後的記錄如果沒有沖突是會立即提交的。

Straight merge是直接把分支合拼到當前的分支。這會把分支上所有的歷史記錄全部合併到當前的分支上。
如果想把testing_branch分支直接合併到當前的分支上可以使用:

$ git merge testing_branch

squashed commits是把分支上的所有的歷史記錄合成一個歷史記錄,再合併到當前的分支。
如果想把testing_branch分支壓合合併到現在正使用的分支上可以使用:

$ git merge --squash testing_branch

cherry-picking是把分支上的一個提交合併到當前的分支。要使用這種合併可能是因為分支上的一個功能需要合併到當前分支上。但是用戶要如何指定要合併的提交呢﹖答案就是每一個git的object model都有的SHA-1 hashcode。那40個位的hashcode實在很難記下或再鍵入,所以Git通常只是用hashcode的首7個位。

$ git commit -a -m "Please find the hashcode"
Create commit 7654321: Please find the hashcode

7654321就是這個提交的id了。所以如果要用cherry-picking來合併這個提交可以用:

$ git cherry-pick 7654321

如果不想Git立即提交合併或想再揀選更多提交合併,那麽便要加上-n參數:

$ git cherry-pick -n 7654321

這様做git只是把提交合併到staging area,用戶可以再用cherry-pick去合併提交或者提交已合併的東西。

恢復修改

修改了檔案而未提交,但是又想放棄修改了的東西。那麽便要恢復到最近一次提交(HEAD)了:

$ git reset --hard HEAD

指定提交代號

有些時候常指定一些特定的版本但是每次都要找那些hash code實在很煩人,所以Git就有一些提交代號:
最近一次提交: HEAD
HEAD之前的那個提交: HEAD^
HEAD之前早兩個的那個提交: HEAD^^
HEAD之前的那個提交: HEAD~1
HEAD之前前早兩個的那個提交: HEAD~2