我正在构建一个应用程序,它从服务器下载2张图像,将它们保存到SD卡,并显示它们(在它们之间循环,每隔15秒更换一次图像)。
我已经完成了,但几分钟后程序崩溃了:OutOfMemoryError:位图超出了VM预算的大小。
因此,某处必须存在内存泄漏。我仍然是Android编程的新手:不太清楚我需要做什么清理,VM不会。
任何帮助?
private ImageView mImageView;
private Bitmap mImageBitmap;
public static String rslt="";
/** Called when the activity is first created. */
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//Remove title bar
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
//Remove notification bar
this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
mImageView = (ImageView) findViewById(R.id.imageView1);
mImageBitmap=null;
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
int count = 1;
public void run() {
Bitmap bm = getNewImages();
if (bm != null){
mImageView.setImageBitmap(bm);
bm=null;
System.gc();
handler.postDelayed(this, 15* 1000);
}else if(count==1){
File img1 = new File(Environment.getExternalStorageDirectory(), "1.jpg");
if(img1.exists()){
bm = BitmapFactory.decodeFile(img1.getAbsolutePath());
if (bm != null){
mImageView.setImageBitmap(bm);
bm=null;
}
}
count = 2;
System.gc();
handler.postDelayed(this, 15* 1000);
}else if (count==2){
File img2 = new File(Environment.getExternalStorageDirectory(), "2.jpg");
if(img2.exists()){
bm = BitmapFactory.decodeFile(img2.getAbsolutePath());
if (bm != null){
mImageView.setImageBitmap(bm);
bm=null;
}
}
count=1;
System.gc();
handler.postDelayed(this, 15* 1000);
}
}
private Bitmap getNewImages() {
ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
mImageBitmap=null;
if (mWifi.isConnected()) {
try{
// EditText ed1=(EditText)findViewById(R.id.editText1);
// String rego=ed1.getText().toString();
String rego="AGR905";
rslt="START";
Caller c=new Caller();
c.rego=rego;
c.join();
c.start();
while(rslt=="START")
{
try
{
Thread.sleep(10);
}
catch(Exception ex)
{
}
}
}
catch(Exception ex){
}
if (rslt.length()<=1600){
}else{
byte[] decodedString = Base64.decode(rslt, Base64.DEFAULT);
mImageBitmap = BitmapFactory.decodeByteArray(decodedString, 0, decodedString.length);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
mImageBitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File from = new File(Environment.getExternalStorageDirectory(), "1.jpg");
if(from.exists()){
File to = new File(Environment.getExternalStorageDirectory(), "2.jpg");
from.renameTo(to);
from.delete();
}
//you can create a new file name "test.jpg" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()+ File.separator + "1.jpg");
try {
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
// remember close de FileOutput
fo.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return mImageBitmap;
}
};
handler.postDelayed(runnable, 2000); //for initial delay..
答案 0 :(得分:3)
有一些事情可以帮助平滑记忆。
System.gc()
。android:largeHeap="true"
进入应用程序。答案 1 :(得分:1)
我不认为问题是内存泄漏。通过同时将两个图像同时存储在内存中,可能会超出内存预算。请记住,每个位图使用 height_in_px * width_in_px * 4 字节,而应用的内存预算为 24 ... 48 MBytes (取决于设备)。
有效使用位图有a great tutorial。用它来找出问题所在并解决它。