Android程序运行时出现java.lang.OutOfMemoryError 错误
生活随笔
收集整理的這篇文章主要介紹了
Android程序运行时出现java.lang.OutOfMemoryError 错误
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
寫了一個用Paint和Canvas畫圖的類,畫完之后將所畫內容保存到手機sd卡上。
1》代碼如下:
package me.linkcube.taku.ui.share;import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException;import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Bitmap.Config; import android.os.Environment; import android.util.Log;public class DrawPicPNG {private Bitmap mBitmap;// 畫布private Canvas mCanvas;// 畫筆--畫圖片private Paint mPicturePaint;// 畫筆--寫字private Paint mTextPaint;// 畫筆--寫運動數據private Paint mDataPaint;public DrawPicPNG() {// TODO Auto-generated constructor stub// 初始化畫筆mPicturePaint = new Paint();// 初始化畫筆mTextPaint = new Paint();mDataPaint = new Paint();// 設置畫筆mTextPaint.setColor(Color.WHITE);// 白色畫筆mTextPaint.setTextSize(80.0f);// 設置字體大小// 初始化畫筆mDataPaint = new Paint();// 繪制文字mDataPaint.setColor(Color.RED);// 紅色畫筆mDataPaint.setTextSize(120.0f);// 設置字體大小}/*** @param resources* :Class for accessing an application's resources.* @param bg_resId* : 背景圖片的資源 ID,如,R.drawable.* @param head_resId* : 頭部圖片的資源ID* @param distance* : 距離,如123.0f* @param timeString* :時間字符串,如:23:12* @param cal* :消耗的卡路里,如:456* */public void drawBitmap(Resources resources, int bg_resId, int head_resId,float distance, String timeString, int cal) {Bitmap bm_bg = BitmapFactory.decodeResource(resources, bg_resId);// 得到圖片的寬、高int bg_width = bm_bg.getWidth();int height_bg = bm_bg.getHeight();// 創建一個你需要尺寸的BitmapmBitmap = Bitmap.createBitmap(bg_width, height_bg, Config.ARGB_8888);// 用這個Bitmap生成一個Canvas,然后canvas就會把內容繪制到上面這個bitmap中mCanvas = new Canvas(mBitmap);// 繪制背景圖片mCanvas.drawBitmap(bm_bg, 0.0f, 0.0f, mPicturePaint);// 繪制圖片Bitmap bm_head = BitmapFactory.decodeResource(resources, head_resId);// 得到圖片的寬、高int width_head = bm_head.getWidth();int head_height = bm_head.getHeight();// 繪制圖片--保證其在水平方向居中mCanvas.drawBitmap(bm_head, (bg_width - width_head) / 2, 0.0f,mPicturePaint);// 繪制運動距離文字String distanceTextString = "運動距離:";String distanceDataString = String.valueOf(distance);String distanceScalString = "米";float distanceTextString_width = mTextPaint.measureText(distanceTextString, 0, distanceTextString.length());float distanceDataString_width = mDataPaint.measureText(distanceDataString, 0, distanceDataString.length());float distanceScalString_width = mTextPaint.measureText(distanceScalString, 0, distanceScalString.length());float x_distance = (bg_width - distanceTextString_width- distanceDataString_width - distanceScalString_width) / 2;mCanvas.drawText(distanceTextString, x_distance, head_height + 30,mTextPaint);// 繪制文字mCanvas.drawText(distanceDataString, x_distance+ distanceTextString_width, head_height + 30, mDataPaint);// 繪制文字mCanvas.drawText(distanceScalString, x_distance+ distanceTextString_width + distanceDataString_width,head_height + 30, mTextPaint);// 繪制文字// 繪制運動時間文字String timeTextString = "運動時間:";String timeDataString = String.valueOf(timeString);String timeScalString = "分/秒";float timeTextString_width = mTextPaint.measureText(timeTextString, 0,timeTextString.length());float timeDataString_width = mDataPaint.measureText(timeDataString, 0,timeDataString.length());float timeScalString_width = mTextPaint.measureText(timeScalString, 0,timeScalString.length());float x_time = (bg_width - timeTextString_width - timeDataString_width - timeScalString_width) / 2;mCanvas.drawText(timeTextString, x_time, head_height + 180, mTextPaint);// 繪制文字mCanvas.drawText(timeDataString, x_time + timeTextString_width,head_height + 180, mDataPaint);// 繪制文字mCanvas.drawText(timeScalString, x_time + timeTextString_width+ timeDataString_width, head_height + 180, mTextPaint);// 繪制文字// 繪制消耗卡路里文字String calTextString = "消耗:";String calDataString = String.valueOf(cal);String calScalString = "大卡";float calTextString_width = mTextPaint.measureText(calTextString, 0,calTextString.length());float calDataString_width = mDataPaint.measureText(calDataString, 0,calDataString.length());float calScalString_width = mTextPaint.measureText(calScalString, 0,calScalString.length());float x_cal = (bg_width - calTextString_width - calDataString_width - calScalString_width) / 2;mCanvas.drawText(calTextString, x_cal, head_height + 330, mTextPaint);// 繪制文字mCanvas.drawText(calDataString, x_cal + calTextString_width,head_height + 330, mDataPaint);// 繪制文字mCanvas.drawText(calScalString, x_cal + calTextString_width+ calDataString_width, head_height + 330, mTextPaint);// 繪制文字// 保存繪圖mCanvas.save(Canvas.ALL_SAVE_FLAG);mCanvas.restore();savePicPNG();}/*** 保存為本地PNG圖片* */private void savePicPNG() {File file = new File(Environment.getExternalStorageDirectory().getPath() + "/share_pic.png");// 保存到sdcard根目錄下,文件名為share_pic.pngLog.i("CXC", Environment.getExternalStorageDirectory().getPath());FileOutputStream fos = null;try {fos = new FileOutputStream(file);mBitmap.compress(Bitmap.CompressFormat.PNG, 50, fos);} catch (FileNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}try {fos.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}} 2》當然一定要在Manifest.xml文件中加入相關權限屬性
<!-- 在SDCard中創建與刪除文件權限 --><uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /><!-- 往SDCard寫入數據權限 --><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
3》在程序中調用此方法
DrawPicPNG picPNG = new DrawPicPNG(); picPNG.drawBitmap(getResources(), R.drawable.dashboard_bg,R.drawable.share_head_img, 1234.0f,"22:11",456);
4》運行程序,出現java.lang.OutOfMemoryError 錯誤
如下圖所示:
5》原因及解決方法:
一般android內存比較大,如果出現此問題,則要檢查如下兩點:
1》》代碼質量問題,代碼中有易造內存泄露代碼
2 》》Android??臻g確實不大,避免多次調用遞歸。如果無法避免遞歸 ,那么請在遞歸函數體內少使用局部變量,及臨時變量。
6》本例解決方法--盡量減少局部變量的使用
優化后的代碼如下:
/*** @param bg_resId* : 背景圖片的資源 ID,如,R.drawable.* * @param head_resId* : 頭部圖片的資源ID* @param distance* : 距離,如123.0f* @param timeString* :時間字符串,如:23:12* @param cal* :消耗的卡路里,如:456* */public void drawBitmap(int bg_resId, int head_resId, float distance,String timeString, int cal) {Bitmap bitmap = BitmapFactory.decodeResource(getResources(), bg_resId);// 得到圖片的寬、高int bg_width = bitmap.getWidth();int height_bg = bitmap.getHeight();// 創建一個你需要尺寸的BitmapmBitmap = Bitmap.createBitmap(bg_width, height_bg, Config.ARGB_8888);// 用這個Bitmap生成一個Canvas,然后canvas就會把內容繪制到上面這個bitmap中mCanvas = new Canvas(mBitmap);// 繪制背景圖片mCanvas.drawBitmap(bitmap, 0.0f, 0.0f, mTextPaint);// 繪制圖片bitmap = BitmapFactory.decodeResource(getResources(), head_resId);// 得到圖片的寬、高int head_width = bitmap.getWidth();int head_height = bitmap.getHeight();// 繪制圖片--保證其在水平方向居中mCanvas.drawBitmap(bitmap, (bg_width - head_width) / 2, 0.0f,mTextPaint);// 繪制運動距離文字textString = "運動距離:";dataString = String.valueOf(distance);scalString = "米";textString_width = mTextPaint.measureText(textString, 0,textString.length());dataString_width = mDataPaint.measureText(dataString, 0,dataString.length());scalString_width = mTextPaint.measureText(scalString, 0,scalString.length());x = (bg_width - textString_width - dataString_width - scalString_width) / 2;mCanvas.drawText(textString, x, head_height + 30, mTextPaint);// 繪制文字mCanvas.drawText(dataString, x + textString_width, head_height + 30,mDataPaint);// 繪制文字mCanvas.drawText(scalString, x + textString_width + dataString_width,head_height + 30, mTextPaint);// 繪制文字// 繪制運動時間文字textString = "運動時間:";dataString = String.valueOf(timeString);scalString = "分/秒";textString_width = mTextPaint.measureText(textString, 0,textString.length());dataString_width = mDataPaint.measureText(dataString, 0,dataString.length());scalString_width = mTextPaint.measureText(scalString, 0,scalString.length());x = (bg_width - textString_width - dataString_width - scalString_width) / 2;mCanvas.drawText(textString, x, head_height + 180, mTextPaint);// 繪制文字mCanvas.drawText(dataString, x + textString_width, head_height + 180,mDataPaint);// 繪制文字mCanvas.drawText(scalString, x + textString_width + dataString_width,head_height + 180, mTextPaint);// 繪制文字// 繪制消耗卡路里文字textString = "消耗:";dataString = String.valueOf(cal);scalString = "大卡";textString_width = mTextPaint.measureText(textString, 0,textString.length());dataString_width = mDataPaint.measureText(dataString, 0,dataString.length());scalString_width = mTextPaint.measureText(scalString, 0,scalString.length());x = (bg_width - textString_width - dataString_width - scalString_width) / 2;mCanvas.drawText(textString, x, head_height + 330, mTextPaint);// 繪制文字mCanvas.drawText(dataString, x + textString_width, head_height + 330,mDataPaint);// 繪制文字mCanvas.drawText(scalString, x + textString_width + dataString_width,head_height + 330, mTextPaint);// 繪制文字// 保存繪圖mCanvas.save(Canvas.ALL_SAVE_FLAG);mCanvas.restore();savePicPNG();}
當然,本程序還有很多要改進的地方。如,畫圖片時,圖片的解析方式等。
總結
以上是生活随笔為你收集整理的Android程序运行时出现java.lang.OutOfMemoryError 错误的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android 如何将Canvas上绘制
- 下一篇: Android 动画(一)