朋友,
我正在使用以下代码在活动中显示单个全屏图像,使用线程问题场景来自每个缩略图上的自定义图库,点击此屏幕上的大图像。
现在问题是用户点击图像并且线程加载图像并按下后退按钮转到上一页用户继续逐个点击每个缩略图以显示全屏图像并重复此场景。
最后,应用程序因内存不足错误位图而崩溃。 请指导我在做什么错误?
public void Move(final String path)
{
if (!isConnected()) {
Constants.DisplayMessage(getApplicationContext(),
Constants.CONNECTION_ERROR_MESSAGE);
return;
}
progressBar = (ProgressBar) findViewById(R.id.progressbar_default);
progressBar.setVisibility(View.VISIBLE);
myThread = new Thread(new Runnable() {
public void run() {
while (serviceData == null) {
serviceData = DisplayLiveImage(path);
callComplete = true;
}
mHandler.post(MoveNow());
}
});
if(myThread.getState() == Thread.State.NEW)
myThread.start();
}
private Runnable MoveNow() {
return new Runnable() {
public void run() {
if (callComplete) {
try
{
if (!serviceData.equals(""))
{
bm = (Bitmap)serviceData;
float ImageHeight = bm.getHeight();
float ImageWidth = bm.getWidth();
float totalHeight = (ImageHeight / ImageWidth ) * CurrentScreenWidth;
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
params.width = LayoutParams.FILL_PARENT;
params.height = (int)totalHeight;
img.setLayoutParams(params);
img.setImageBitmap(bm);
}
else
{
// show error
}
}catch(Exception ex)
{
// show error
}finally
{
progressBar.setVisibility(View.GONE);
serviceData = null;
callComplete = false;
}
}
}
};
}
public void stopThread()
{
try
{
if(myThread != null)
myThread.interrupt();
}catch(Exception ex)
{ }
}
@Override
public void onDestroy()
{
if(bm != null)
{
bm.recycle();
bm = null;
}
stopThread();
super.onDestroy();
}
答案 0 :(得分:2)
发生内存不足错误时是否正在运行调试程序?如果是这样,那么调试器可能是问题的根源。如果您在调试器下运行应用程序,则调试器仍将保留所创建的任何线程,即使它们已完成运行。这会导致在没有调试器的情况下运行应用程序时不会发生的内存错误。尝试在没有调试器的情况下运行,看看是否仍然会出现内存泄漏。
http://code.google.com/p/android/issues/detail?id=7979
https://android.googlesource.com/platform/dalvik/+/master/docs/debugger.html
如果不是这种情况,请尝试使用Eclipse Memory Analyzer来追踪内存问题。 http://www.eclipse.org/mat/
答案 1 :(得分:2)
使用Android管理位图是最烦人的事情。
为了避免我使用的大部分OOM异常:
//Try to free up some memory
System.gc();
System.runFinalization();
System.gc();
是的,你读对了2 system.gc ...去图:s
在尝试解码之前。所以在你的情况下,它将在我假设的setImageBitmap之前。但请查看您的日志,并将其放在导致您的应用崩溃的行之前。
如果仍然发生,请在分配位图时使用bitmapOtions.insamplesize打开较小版本的位图。