2016年1月21日 星期四

Android 實戰記錄 (21) - multiDexEnabled 造成的 NoClassDefFoundError 問題

因為啟用了multiDexEnabled之後
反而在特定的手機(ASUS),出現了 NoClassDefFoundError 問題

瞭解之前版本與之後版本差異就差在我因為加了
multiDexEnabled

因為加入了
compile 'org.apache.commons:commons-lang3:3.4'
的關係

超過了65K method

後來終於解決問題,是查看了
以下這篇文章
Building Apps with Over 65K Methods
https://developer.android.com/intl/zh-tw/tools/building/multidex.html

調整了一些gradle的設定

啟用了(應該是改下面幾個設定就可以了)
dependencies {
    compile 'com.android.support:multidex:1.0.0'}


buildToolsVersion "21.1.0"

defaultConfig {
    multiDexEnabled true}

然後改寫原本繼承的Application
https://developer.android.com/intl/zh-tw/reference/android/support/multidex/MultiDexApplication.html

複寫方法
protected void attachBaseContext(Context base) {
    super.attachBaseContext(base);
    MultiDex.install(this);
}

則可以解決問題。
ASUS,就可以運行正常。

2015年12月31日 星期四

Java - 列印所有程式程式碼行數

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

public class ScanCode {
public static void main(String args[]) {
ScanCode scanCode = new ScanCode();

final File folder = new File("C:\\workspace\\android\\src");
scanCode.listFilesForFolder(folder);
}

public void listFilesForFolder(final File folder) {
   for (final File fileEntry : folder.listFiles()) {
       if (fileEntry.isDirectory()) {
           listFilesForFolder(fileEntry);
       } else {
        try {
        System.out.println(folder.getAbsolutePath() + "\t" + fileEntry.getName() + "\t" +countLines(fileEntry.getAbsolutePath()));
        } catch(Exception ex) {
        ex.printStackTrace();
        }
       }
   }
}

public int countLines(String filename) throws IOException {
   InputStream is = new BufferedInputStream(new FileInputStream(filename));
   try {
       byte[] c = new byte[1024];
       int count = 0;
       int readChars = 0;
       boolean empty = true;
       while ((readChars = is.read(c)) != -1) {
           empty = false;
           for (int i = 0; i < readChars; ++i) {
               if (c[i] == '\n') {
                   ++count;
               }
           }
       }
       return (count == 0 && !empty) ? 1 : count;
   } finally {
       is.close();
   }
}

}

2015年12月28日 星期一

Android 實戰記錄 (20) - status bar 背景色變更

要改status bar 背景色,
需要先把build.gradle 的 compileSdkVersion設為 21以上

並且在程式加入以下程式碼。
Window window = getWindow();
// clear FLAG_TRANSLUCENT_STATUS flag:window.clearFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// add FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS flag to the windowwindow.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
if (android.os.Build.VERSION.SDK_INT >= 21) {
// finally change the color window.setStatusBarColor(getResources().getColor(R.color.status_bar_background)); }

status bar 的背景色,只支援 sdk 21 以上,
而開發者,需要將compile sdk設在21以上,compile才不會出錯。
並且做 sdk判斷,才能避免出問題。

Android status bar 是從 Android 5.0開始才支援Lollipop 版本


2015年12月24日 星期四

Android 實戰記錄 (19) - ViewPager 滑動速度


因為要做輪播,但輪播速度過快,導致
需要調整滑動速度
參考以下這個解

 http://my.oschina.net/javalover/blog/179003

public class FixedSpeedScroller extends Scroller {
    private int mDuration = 1500;
    public FixedSpeedScroller(Context context) {
        super(context);
    }
    public FixedSpeedScroller(Context context, Interpolator interpolator) {
        super(context, interpolator);
    }
    @Override
    public void startScroll(int startX, int startY, int dx, int dy, int duration) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
    @Override
    public void startScroll(int startX, int startY, int dx, int dy) {
        // Ignore received duration, use fixed one instead
        super.startScroll(startX, startY, dx, dy, mDuration);
    }
    public void setmDuration(int time) {
        mDuration = time;
    }
    public int getmDuration() {
        return mDuration;
    }
}

try {
    Field field = ViewPager.class.getDeclaredField("mScroller");
    field.setAccessible(true);
    FixedSpeedScroller scroller = new FixedSpeedScroller(mViewPager.getContext(),
         new AccelerateInterpolator());
    field.set(mViewPager, scroller);
    scroller.setmDuration(2000);
} catch (Exception e) {
    LogUtils.e(TAG, "", e);
}