読者です 読者をやめる 読者になる 読者になる

後始末系の処理の覚え書き


関連事項>


 HTCでテストしてたときに発生した時に
ImageViewでandroid:src で設定済の物に対して
setImageResourceをしたらOutOfMemoryが・・・

 まあー度あることは二度ある感じなんで
色々とよく使う後始末系の処理を覚え書きとしてまとめてみようかと。
 まあここら辺の処理は遣っている人は当たり前として遣っていると思うので
あくまで自メモですね。。

 上記の処理に関しては

な呟きもみたので試してみたんだけど、それだけでは駄目。
最終的には下記の対応で落ち着きました

 まあこれとは別にアプリ終了時にメモリクリアとかしてあげないと
結構残るっぽい。onDestoryで呼ぶのがよい感じ

一応正式な記述的には

  • isRecycle() => recycle() らしいんですけど、判定しなくても落ちることはないので問題ないと思う

 あとはAndroidはなんかプロセスが残り気味なので
下記のような強制終了の処理を入れていたりしてます

 あとはAd入れているとキャッシュが溜まるので
チョコチョコ消している感じ(Unityで振り返りざまにSystem.gcとかしてると同じ感じかな)

 これはAndroid3.0だけで起こる奴なんですけど,Animation効果が残る問題。*1

//ivはImageViewとか
iv.clearAnimation();
iv.invalidate();

をしておきましょうと言うお話

追記>
 つい最近だとAndroid4.1移行だとAnimation系は結構動かなくなってる

で置き換えメモはまとめた。

 とくにRelativeLayoutの重ねがけ等はヤバゲ ><



追記)
 OutOfMemoryのAndroidRuntimeはどうしても回避できないので

GIMP
 画像=>モード=>インデックス(RGBから
 ファイル=>エクスポート
あたりにすると、画像サイズが劇的に減ります(1/2〜1/4程度に)

なお話もあるようですが、こちらの方が手軽ですね


追記2)

の状況が発生*2

低端末対応はメモリと戦いだな。。。



追記3)
キャッシュクリア系生きてくるのは下記の条件下みたい*3

  • Preference保存の場合は以下
SharedPreferences.Editor editor = getSharedPreferences("favorite", 0);
editor.clear().commit();
  • private領域なら下記な感じかも
for(String fname:fileList()){
   deleteFile(fname);
}
  • SD領域なら*4
private File getSDCardDir(){
    	File dir = null;
    	if(Build.VERSION.SDK_INT >= 8){
    		dir = ActivityUtil.getExternalFilesDir(this,null);
    	}
    	else{
    		dir = new File(Environment.getExternalStorageDirectory(),"/Android/data/" + getClass().getPackage().getName() +"/files");
    		dir.mkdirs();
    	}
    	return dir;
    }
@SuppressLint("NewApi")
public class ActivityUtil {
	public static File getExternalFilesDir(Activity activity,String type){
		return activity.getExternalFilesDir(type);
	}

WebCashedはここ)


追記4)
つい最近ロギングラッパーの話でHeapdumpの話を追加してみた。

でもこれ根本解決にならんからあんま好きではないんだよな。。。*5

どうしてもダメなときは下記みたいな対応も有る。
(layout.xmlandroid:backgroundで画像を指定しまくっている時)

	BitmapFactory.Options bmfOptions = new BitmapFactory.Options();
	bmfOptions.inPurgeable = true;
	if("htc_wwe".equals(Build.BRAND) && "HTC Desire".equals(Build.MODEL)){
		bmfOptions.inSampleSize=2;
	}
	Bitmap bt = BitmapFactory.decodeResource(m_r, res_id,bmfOptions);

なのが推奨されているけど、読み込む画像が崩れるのでオススメはしないし、

ここでもコメントしたけど

layout.xmlに定義されているものには無力。この場合は


BitmapFactory.decodeResource(m_r, resid)

  1. な感じで原寸で読み込まれる
  2. =>レイアウトで伸縮 される動きになるよう*6

所謂
layout/result.xml

<Linerlayout 
	xmlns:android="http://schemas.android.com/apk/res/android"
	 android:background="@drawable/back_result"
	android:gravity="center_horizontal"
	android:orientation="vertical"
	android:layout_width="fill_parent"
	android:layout_height="fill_parent">

</Linerlayout>

な指定の仕方のケース。*7

でその場合はどうするかというと

    	m_r = getResources();
	if("htc_wwe".equals(Build.BRAND) && "HTC Desire".equals(Build.MODEL)){
	        WindowManager windowManager = getWindowManager();
	        Display display = windowManager.getDefaultDisplay();
	        final DisplayMetrics displayMetrics = new DisplayMetrics();
	        display.getMetrics(displayMetrics);
 		Configuration config = m_r.getConfiguration();
 		displayMetrics.densityDpi = DisplayMetrics.DENSITY_MEDIUM;//.DENSITY_LOW;
 		m_r.updateConfiguration(config, displayMetrics);
	}

で強引にディスプレイ解像度の画像深度を変更すると。これでも凄い暫定対応ですけどね・・。*8


 結局は対象解像度用の画像をすべて用意してもらうのがいいんですけど

  • IOSの素材を作る
    • =>Androidそのまま流用の流れ

なので自分で画像を加工する技術をつけるかしかないのかなと思う。

 自分だと画像をgimpでインデックスカラーにするくらいが精一杯。
実際はリサイズして画像データサイズを減らすべきなんだよな。。 



参考リンク集)

*1:AlphaAnimationとか

*2:機能追加でメモリ使用量増えた><

*3:使い勝手的にはupload用の一時ファイルとか?

*4:ただしtarget8からなのでlazy-loadが必要かな

*5:昔伝来のprintデバック色が濃くて

*6:したがって汚く見えるからという理由でIOSRetina画像をポンと渡される流れ=>OutOfMemory地獄><

*7:animation-list とかも同じ

*8:画像が崩れるものは崩れる