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

2012年6月4日 星期一

[Android] Bitmap out of memory 一些解決法

使用 Bitmap 在讀取較大的原始圖片時,常會發生 Out of memory 的錯誤
即可以利用 Bitmap.Options 的參數設定來降低讀取圖片時所需要的記憶體
其中 Android Developer 官方所教導的方法是使用 isSampleSize 的方式來降低讀取圖檔時所需要的 memory

該參數大於 1 時
如 2 即表示回傳的解析度為 width /2 * height / 2 的圖檔
4 即表示回傳的解析度為 width /4 * height /4 的圖檔
依此類堆
因解析度少很多,故可以減少讀圖檔的 memory

這部份的 code 可以依自己需求修改,跟官方不太一樣
以下所計算的方式是將圖片縮到比想要的解析度大一點的最小縮圖,求在顯示時有較佳的解析度
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) 
{
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;
  
    inSampleSize = (int) Math.min(Math.ceil((float)width/(float)reqWidth),  Math.ceil((float)height/(float)reqHeight));

    return inSampleSize;
}

public static Bitmap decodeSampledBitmapFromFile(String fileName, int reqWidth, int reqHeight) 
{
    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeFile(fileName, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeFile(fileName, options);
}
ps: inJustDecodeBounds 的參數表示會讀取圖片的一些 info 但不會將圖檔本體讀進來
此時可以讀到圖檔的寬高並無法使用該圖檔去處理或顯示(因為沒讀進 memory)

不過竟然有這樣的參數
interface 應該有可能實現,直接讀取想要寬高的圖檔才對!?


Ref:http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

這樣的方式雖然可以大量減少 out of  memory 的問題
但還是有可能會發生
所以還是可以配合

bitmap.recycle();
System.gc();

來減少發生

更詳細與其他解法的 Ref:
http://givemepass.blogspot.tw/2011/11/blog-post_16.html
http://bluegray-javalearning.blogspot.tw/2011/07/android-out-of-memoryoom.html

2011年12月9日 星期五

[Android] Caused by: android.content.ActivityNotFoundException

雖然使用 eclipse ui 來建立 androidMainifest.xml 新的 activity 時還是會出現以下錯誤訊息

Caused by: android.content.ActivityNotFoundException: Unable to find explicit activity class have you declared this activity in your AndroidManifest.xml?

解決方法是手動修改 AndroidManiftest.xml 內的 android:name 輸入完整的 package namespace 含 class


以動態桌布為例

<service
android:name="your.package.namespace.TestLiveWallpaper"
</service>
<activity
android:name="your.package.namespace.TestLiveWallpaper"
</activity>

動態桌布的 xml 內的 android:settingActivity 也需要改成這樣

<wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:settingsActivity="your.package.namespace.TestLiveWallpaper"
/>

2011年12月5日 星期一

[Android] 取得螢幕解析度

繼承 activity 時

Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();


不是 activity 時

Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();

2011年11月30日 星期三

[Android] 使用 Eclipse 開發 Android 抓不到 assets 內的檔案

使用 Eclipse 開發 Android
明明在 assets 資料夾內有檔案
在getResources().getAssets().open("filename");
卻總是抓不到
是因為檔案不能直接從檔案總管丟入, 必須由 eclipse 加入才會在打包時加入
所以個人解法是
在 assets 選 import 的方式把檔案加進來

可以使用以下片段程式確認 assets 內容

String[] list = getResources().getAssets().list("");
if (list != null)
{
  for (int i=0; i < list.length ; ++i )
  {
    Log.d("Assets:", list[i]);
  }
}