顯示具有 android 標籤的文章。 顯示所有文章
顯示具有 android 標籤的文章。 顯示所有文章

2015年12月18日 星期五

Snackbar vs Translucent mode

當 Navigation 設定成 Translucent mode 時
snackbar 會跟 navigation bar 重疊
不知道為啥 Google 設計 design library 時沒考慮到這件事

private int mNaturalBarHeight = 0;
int idShowNavigation = Resources.getSystem().getIdentifier("config_showNavigationBar", "bool", "android");
    boolean isShowNavigationBar = Resources.getSystem().getBoolean(idShowNavigation);
int navigationId =  getContext().getResources().getIdentifier("navigation_bar_height", "dimen", "android");
if (isShowNavigationBar && navigationId > 0) {
    mNaturalBarHeight = getContext().getResources().getDimensionPixelSize(navigationId);
}

要顯示 snackbar 時,改動 layout parameter

final Snackbar snackbar = Snackbar.make(mFab, R.string.msg_to_show, Snackbar.LENGTH_LONG)
        .setAction(R.string.action_to_show, new OnClickListener() {
            @Override
            public void onClick(View v) {
                // TODO: go to something
            }
        });
View v = snackbar.getView();
FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) v.getLayoutParams();
layoutParams.bottomMargin = mNaturalBarHeight;
v.setLayoutParams(layoutParams);
snackbar.show();

2015年7月9日 星期四

Android Studio vs Yosemite

昨天為了讓 Xcode 升到最新版
終於讓 2011" MBA 去升 Yosemite
系統變慢是正常的
Android Studio 結束後有 java zombie process
而且整個記憶體吃很兇
不過最讓我無法忍受的是 Android Studio 的字型變得超醜

搞了半天原來是 Java 7/8 的問題 依據官方的網頁

  • Android Studio 要跑 Java 6
  • compiler 要跑 Java 7/8

他裡面有寫要 export STUDIO_JDK
不過我試的結果是直接裝完 java 6 他就會自動去吃了

Apple Java 6 link
用了 Java 6 後
Android Studio 的速度跟吃 RAM 都變正常一點了

2015年5月11日 星期一

leakcanary

今天看到有人在討論的工具 library

leakcanary

如他的名字, 他是拿來試毒氣的金絲雀
主要是把 MAT (Memory Analyzer) 做進去 application level

Getting Started

dependencies {  
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'  
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'  
}  

PS. 我的 build.gradle 一直少加了

repositories {  
    mavenCentral()  
}  

結果 dependencies 一直出問題
加了後,他會自己去抓 library 了

public class ExampleApplication extends Application {  
  @Override public void onCreate() {  
       super.onCreate();  
       LeakCanary.install(this);  
  }  
}  

到此為止, 他做了什麼

他埋了一個 Activity Watch 在 Application level
所以當你的 Activity finish() 了, 一但 Activity 沒有被正確回收
他就在背景做 heap dump
利用 Eclipse 的 MAT(Memory Analyzer) 去分析是誰 block 住
activity 這個 reference 是誰造成 memory leak

然後他會在 notification dump 出 memory leak 的結果
拉下來點開就有一個分析的畫面跟你說哪邊 memory leak

然後要怎用

可以隨時利用他

refWatcher = LeakCanary.install(this);

寫個 getter 把 refWatcher export 出來

RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());

然後監控你要的變數

refWatcher.watch(schrodingerCat);

薛丁格的貓 被 clear 掉,卻沒有正常被 gc 掉的話
就會觸發 notification

另外因為 heap dump 需要幾秒鐘
所以會等一下才跑出來

2015年3月12日 星期四

Signing release key in AndroidStudio

Put this into ~/.gradle/gradle.properties

RELEASE_STORE_FILE={path to your keystore}
RELEASE_STORE_PASSWORD=*****
RELEASE_KEY_ALIAS=*****
RELEASE_KEY_PASSWORD=*****

注意!RELEASE_STORE_FILE 的路徑要是絕對路徑 Android Studio 很笨的會把 ~/.... 串起來, 然後找不到

signingConfigs {

   release {
       storeFile file(RELEASE_STORE_FILE)
       storePassword RELEASE_STORE_PASSWORD
       keyAlias RELEASE_KEY_ALIAS
       keyPassword RELEASE_KEY_PASSWORD
   }
}

buildTypes {
        release {
            signingConfig signingConfigs.release
        }
}

ref: StackOverflow

2015年2月11日 星期三

Android Studio multiple sourcesets problem

解決了一個困擾我三個月的事...

gradle 可以把 src code 分成不同的目錄
然後可以用 build variants 分別去要不要 include 這個東西

android.sourceSets.main {}  
android.sourceSets.XXX {}

因為我們現在開發只會用到 XXX
main 也被污染了, 一定要用到 XXX 裡的 code

每次 import project 時,我的 Mac 總是會選到 XXX 的 build variants
所以我的 Android Studio 可以 build 出來
用指令 gradle build 也是正常...

可是其它人的 Windows 總是會選到 main 的那個 build variants
所以他們總是 build 不過 (不過我重灌後的 Windows 上竟然可以!?)
只能改 gradle 把 XXX 裡的目錄加到 main 裡

可是這樣 Project view 時沒辦法把 src set 切開看,很醜

... 反正結論就是 UI 上把 build variant 選成 XXXDebug 就好了
害我為了要看不同 src set local 的 gradle 檔要跟別人不一樣
(只有我用 Mac)

今天為啥會解決這件事呢...
因為我的 Android Studio project 突然爛了
重 import source set 竟然跑回 main 了
而且怎弄都是這樣
才又把 windows 上的 iml 檔拿來 diff
靈機一動想到這回事
原來只是我運氣好(!?) ... -___-

這鳥東西竟然困擾我三個月
幹!

太蠢了,寫起來記錄

2014年11月4日 星期二

ApplicationId

新的 build 系統加了 applicationId 這東西

link

簡單的說, 他要解決不同版本 (free/pro) 如何產出 apk 的問題

例如說兩個版本

  • com.example.my.app.free
  • com.example.my.app.pro

在舊的 build tool 上, 要把 AndroidManifest.xml 分別用不用的 packageName 分開
… 想到就很痛苦

新的 build 系統讓 source code 幾乎都不改的情形下
只修改 .gradle 檔

app/build.gradle:

productFlavors {
    pro {
        applicationId = "com.example.my.pkg.pro"
    }
    free {
        applicationId = "com.example.my.pkg.free"
    }
}
buildTypes {
    debug {
        applicationIdSuffix ".debug"
    }
}
....

注意的點在於,雖然不用改 manifest 裡的 pkg name
可是實際上 package name 已經改了

$ aapt d badging app-release.apk
package: name='com.example.my.pkg.free' versionCode='1' versionName='1.0' platformBuildVersionName=''
sdkVersion:'15'
targetSdkVersion:'20'

如果是直接指定 component 的情形下,要小心

adb shell am start -n com.example.my.pkg/.MainActivity 已經無法使用

要改成

adb shell am start -n com.example.my.pkg.free/com.example.my.pkg.MainActivity

2014年9月23日 星期二

use private API in gradle

build.gradle

加入

allprojects {
    gradle.projectsEvaluated {
        tasks.withType(JavaCompile) {
            options.compilerArgs << "-Xbootclasspath/p:$projectDir/libs/hidden.jar:$projectDir/libs/hidden2.jar"
        }
    }
}

Gradle duplicated resource error

BSP 在 resource 會使用 product="XXXX" 去分別不同的 target
例如 phone / tablet

在 Eclipse 時代還相安無事
可是 gradle 根本沒有考慮這個情形
(看了一下 source code, 大概吧?)

註: Merge resource check

regex saved my life again !

find res/ -name strings.xml | xargs -n 1 sed -i "" -E '/product="tablet"/d'

2013年11月26日 星期二

Nexus 5 w/ AOSP

Tested in KRT16M / KOT49H

Steps

Follow the steps here

http://source.android.com/source/building.html

  • unlock device
  • get source code Version

    • KRT16M | android-4.4_r1
    • KOT49H | android-4.4.2_r1
  • get nexus driver

  • fix what's missing in nexus driver

    link
    yes, pull the binary from stock ROM first If you didn't do that, your SIM cannot be used

  • (optional) get /system/media/bootanimation.zip Because AOSP android doesn't have nexus animation

  • (ADD: 2013/11/29 16:55) add Network Location Provider for GMS
    link
    Fixed Wireless GPS issues. Changed "config_locationProviderPackageNames" from "com.google.android.location" to "com.google.android.gms" in frameworks/base/core/res/res/values/config.xml

  • start to build

      $ source build/envsetup.sh  
      $ lunch  
          => Press AOSP hammerhead userdebug  
      $ make clobber  
      $ make -j 4  
    
  • flash custom recovery (CWM or TWRP)

  • flash everything other than recovery

  • fastboot reboot bootloader

  • Press VOL-UP than power button to enter recovery mode
    Choose Advanced -> sideload mode, if you are using TWRP

      $ adb sideload gapps
          gapps link http://forum.xda-developers.com/showthread.php?t=2397942
      $ adb sideload stock_boot_animation or 
          adb push bootanimation.zip into /system/media/bootanimation.zip
    
  • do a factory reset

  • (ADD: 2013/12/19 16:07)
    fix green line issue in camcorder KOT49H (KRT16M has this issue?)
    Replace /system/lib/libmmcamera_interface.so by stock one
    link

Have fun!

2013年11月12日 星期二

WeakReference listener in API

在找 OnSharedPreferenceChangeListener 範例抄時找到這個

SharedPreferences keeps listeners in a WeakHashMap. This means that you cannot use an anonymous inner class as a listener, as it will become the target of garbage collection as soon as you leave the current scope.

SharedPreferences.onSharedPreferenceChangeListener not being called consistently

靠... 這很容易踩到啊 =_=

2013年11月2日 星期六

ad block on android

plurka 廣告設計得太爛,不要怪我對你不義啊

記錄一下

adb shell mount -o rw,remount /system 
adb push hosts.for.mobile.txt /etc/hosts
adb reboot

refs: xda

2013年9月16日 星期一

BuildConfig in BSP

BuildConfig 在 Eclipse 裡會自動生成 不過如果這份 source code 同時要在 BSP 裡使用就會有問題 先找到一個很醜的解法
wrapper!
public class L {
    private static boolean BUILDCONFIG_DEBUG = false;
    static {
        try {
            Class<?> c = Class.forName("com.helloworld.BuildConfig");
            Field field = c.getField("DEBUG");
            BUILDCONFIG_DEBUG = field.getBoolean(null);
        } catch (NoSuchFieldException e) {
        } catch (ClassNotFoundException e) {
        } catch (IllegalArgumentException e) {
        } catch (IllegalAccessException e) {
        }
    }
}

2013年8月27日 星期二

View.isInEditMode()

每次都會忘記的東西
在 Custom View 裡, 想要在 GUI layout editor 看到東西
if (isInEditMode()) { // put some item here }
這樣在 layout editor 就可以看到,而不是空空的一片
這個可以參考 Google IO 2011 影片

2013年8月21日 星期三

Eclipse 使用 hidden API

Eclipse 使用 hidden API

流程

  • 會需要 out/ 下的東西, 所以先完整的 build 過一次
  • jar 檔 out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/ classes-full-debug.jar
  • $ unzip classes-full-debug.jar -d xxx
  • 把 META-INF 和所有不需要的 class 刪除
  • 例如 app 需要以下的 import
android.app.ActivitManager
android.content.Intent
android.media.AudioManager
android.media.AudioSystem
android.text.TextUtils
  • 重新打包成 jar 檔
$ jar cvf ~/hidden.jar android
  • 加進 Eclipse 的 libs/ 下
  • clean build

script, save your life

$ cat classlist.txt
android.app.ActivitManager
android.content.Intent
android.media.AudioManager
android.media.AudioSystem android.text.TextUtils
$ unzip classes-full-debug.jar -d xxx; cd xxx; cat ../classlist.txt | sed 's/./\//g' | sed 's/$/.class/' | perl -ne '@ = glob $; print "$ " for @;' | xargs jar cvf ../hidden.jar