• How to Add Redirects to Post URL on Octopress

    When I write a new post on Octopress, I share the link of it to somewhere doesn’t support hyperlinks. Since people can’t click the link, they should copy and paste or just type it letter by letter. I wanted to make it easier, so I maded short url for every post.

    Alias Generator for Posts

    There is a Jekyll plugin that generates redirect pages for posts with aliases. Octopress is based on Jekyll and this plugin has no compatibility problem. Its source is on GitHub, so I just added it as submodule:

    $ git submodule add git@github.com:tsmango/jekyll_alias_generator plugins/jekyll_alias_generator
    

    In your _config.yml, you may have this line:

    plugins: plugins
    

    Then it reads plugins directory and alias_generator.rb in plugins/jekyll_alias_generator/_plugins/ directory is also loaded, so you can use and manage it!

    How to Use

    This plugin checks alias inside every post’s YAML Front Matter. Just place the path of the alias:

    ---
    layout: post
    title: "How to Add Redirects to Post URL on Octopress"
    alias: /p/20140523
    ---
    

    Multiple aliases are also available:

    ---
    layout: post
    title: "How to Add Redirects to Post URL on Octopress"
    alias: [/one-alias/index.html, /another-alias/index.html]
    ---
    

    When I rake generate, the plugin generates static html file at /p/20140523/index.html:

    <!DOCTYPE html>
    <html>
    <head>
    <link rel="canonical" href="/2014/05/23/how-to-add-redirects-to-post-url-on-octopress/"/>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta http-equiv="refresh" content="0;url=/2014/05/23/how-to-add-redirects-to-post-url-on-octopress/" />
    </head>
    </html>
    

    When you go to /p/20140523, it will redirect here. It also has canonical link, so it won’t affect search engine or web analysis services.

  • Gradle 환경에서 ProGuard 사용하기

    Gradle

    Gradle

    최근 Android Studio를 통해 개발을 진행하게 되면서, 자연스럽게 Gradle을 사용하게 되었다. .gradle 확장자를 가진 파일을 통해 빌드 설정을 자유롭게 조정할 수 있다. 이 글에서는 Gradle을 이용해 배포 APK를 생성하는 방법과 함께 ProGuard를 사용법을 공유하겠다.

    Gradle 환경에서 배포 APK 생성하기

    배포 APK에는 서명이 되어 있어야 하는데, 이를 위해서는 keystore 파일과 그 암호, 키 별칭, 키 암호가 필요하다. 디버그 APK에도 서명을 하지만, 알려진 keystore 암호와 키 별칭, 키 암호를 사용한다. 배포 APK의 서명을 위해 프로젝트의 build.gradle 파일에 다음 코드를 추가하면 된다.

    android {
        // ...
    
        signingConfigs {
            release {
                storeFile file("YOUR_KEYSTORE_PATH")
                storePassword "YOUR_KEYSTORE_PASSWORD"
                keyAlias "YOUR_KEY_ALIAS"
                keyPassword "YOUR_KEY_PASSWORD"
            }
        }
    
        buildTypes {
            release {
                signingConfig signingConfigs.release
            }
        }
    }
    

    이때 buildTypes 아래의 debug 항목은 굳이 명시하지 않아도 기본적으로 생성되며, 이 buildType디버그 keystore와 키를 사용하도록 설정되어 있다.

    다만 이때 build.gradle 파일에 keystore 암호와 키 암호가 평문으로 들어가게 되는데, 소스를 공개하고 있는 등의 이유로 이를 피하고 싶다면 각각의 항목을 쉘 프롬프트에서 입력받을 수 있다.

    signingConfigs {
        release {
            storeFile file(console.readLine("\n\$ Enter keystore path: "))
            storePassword new String(console.readPassword("\n\$ Enter keystore password: "))
            keyAlias console.readLine("\n\$ Enter key alias: ")
            keyPassword new String(console.readPassword("\n\$ Enter key password: "))
        }
    }
    

    그러나 이는 IDE를 통해 디버그 APK를 생성할 때 크래시를 내며, 이는 그때 코드의 consolenull이라서 발생하는 오류다. 이를 해결한 최종 코드는 다음과 같다.

    signingConfigs {
        release {
            final Console console = System.console();
            if (console != null) {
                storeFile file(console.readLine("\n\$ Enter keystore path: "))
                storePassword new String(console.readPassword("\n\$ Enter keystore password: "))
                keyAlias console.readLine("\n\$ Enter key alias: ")
                keyPassword new String(console.readPassword("\n\$ Enter key password: "))
            }
        }
    }
    

    디버그 APK와 배포 APK의 패키지 이름이 같으면 APK의 서명이 서로 달라 개발과 디버깅에 어려움이 있다. 이를 해결하기 위해서 buildTypes 아래에 debug 항목을 선언하여 디버그 APK의 패키지 이름을 바꿀 수 있고, 추가로 버전명도 바꿀 수 있다.

    buildTypes {
        debug {
            packageNameSuffix '.debug'
            versionNameSuffix '-debug'
        }
    }
    

    이제 터미널에서 다음 명령을 실행하면 디버그 APK와 배포 APK를 각각 얻을 수 있다. 물론 디버그 APK는 IDE로도 생성할 수 있다.

    $ ./gradlew assembleDebug
    $ ./gradlew assembleRelease
    

    Gradle은 캐멀케이스 단축키를 지원해서 aR에 해당하는 다른 명령이 없는 한 assembleRelease 대신 aR을 사용할 수 있다.

    Read on →

  • Layout Inflation as Intended →

    안드로이드 개발을 하다 보면 LayoutInflaterinflate(int, ViewGroup)inflate(int, ViewGroup, boolean)는 꽤 익숙하다. 하지만 다음 두 줄의 코드가 어떻게 다른지 아는 사람은 그리 많지 않을 것 같다. 실제로 Android Lint는 한쪽 코드는 피하도록 권하고 있다.

    inflater.inflate(R.layout.my_layout, null);
    inflater.inflate(R.layout.my_layout, parent, false);
    

    Dave Smith가 이 두 코드의 비교와 함께, 바른 Layout Inflation 방법에 대해 설명한 글이 있어 소개한다.

  • Fragment Transaction & Activity State Loss →

    FragmentTransactioncommit() 했을 때 Activity의 onSaveInstanceState(Bundle)이 실행된 후라면 다음과 같은 에러 메시지를 보게 된다.

    java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
    

    이 문제의 원인이 무엇인지, 어떻게 이 Exception을 피할지, 그리고 commitAllowingStateLoss()가 왜 마지막 수단이 되어야 하는지 잘 설명한 글이 있어 소개한다. Alex Lockwood가 쓴 Fragment Transaction과 Activity State Loss에 관한 글이다.

  • Trailing whitespace is evil. Don't commit evil into your repo. →

    Jared Barboza가 쓴 줄 끝 공백에 관한 글이다.

    난 최근에 다양한 사람/언어/편집기와 함께 많은 프로젝트를 진행해 왔다. 우리들 대부분은 Git 초보자였고, 각 프로젝트는 줄 끝 공백에 관한 문제가 있었다.

    경력 있는 개발자로만 이루어진 팀이라고 해도 이런 문제는 발생하기 마련이다.

    줄 끝 공백은 당신의 저장소에서 상당히 많은 문제를 일으킬 수 있다. 실제로 바뀐 것은 공백일 뿐인데도 그 줄에 변경 사항이 있다는 잘못된 diff를 만든다.

    이는 개발 과정에서 나중에 실제 파일의 변경 사항이 무엇이었는지 찾기 불가능하게 만든다. 대부분의 오픈 소스 프로젝트 대표들은 이를 알고 있고, 그들 대부분은 줄 끝 공백을 없애지 않은 풀 리퀘스트를 거절할 것이다.

    이후 글에서는 Visual Studio와 Sublime Text 2에서 줄 끝 공백을 제거하는 방법과 git hook을 통해 커밋에 줄 끝 공백이 포함되지 않도록 하는 방법을 소개하고 있다.

    나는 Android Studio에서는 파일 저장 시 모든 줄 끝 공백을 지우고, Vim에서는 줄 끝 공백에 하이라이트를 입혀 쓰고 있다.

    highlight ExtraWhitespace ctermbg=red guibg=red
    autocmd BufWinEnter * match ExtraWhitespace /\s\+$/
    autocmd InsertEnter * match ExtraWhitespace //
    autocmd InsertLeave * match ExtraWhitespace /\s\+$/
    if version >= 702
      autocmd BufWinLeave * call clearmatches()
    end