我们的线程每200ms从网络摄像头获取一张图片,从JPG转换成Bitmap放到安卓的imageView里。每个循环BitmapFactory会创建新的内存 garbageCollection( )来不及回收 就造成程序死掉。望网求大神指教! 代码如下:
public Bitmap LoadBitmapFromNetwork(URL url) {
Bitmap vcBitmap = null; try {
String vcCredential = "admin:admin";
String vcEncode = Base64.encodeToString(
vcCredential.getBytes("UTF-8"), Base64.DEFAULT);
URLConnection vcConn = url.openConnection();
vcConn.setRequestProperty("Authorization",
String.format("Basic %s", vcEncode));
HttpURLConnection vcHttpConn = (HttpURLConnection) vcConn; if (vcHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream vcInStream = vcHttpConn.getInputStream();
vcBitmap = BitmapFactory.decodeStream(vcInStream);
vcInStream.close();
} vcHttpConn.disconnect();
} catch (IOException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} return vcBitmap;
} /**
* 视频直播
*
* @param image
*/
public class VlinCamLive implements Runnable { private ImageView vcImage; public VlinCamLive(ImageView image) {
vcImage = image;
} public void run() {
try {
URL vcUrl = new URL(getBaseContext().getResources().getString(
R.string.camera_ip)); while (true) {
final Bitmap vcBitmap = LoadBitmapFromNetwork(vcUrl); if (vcBitmap != null) {
vcImage.post(new Runnable() {
public void run() {
vcImage.setImageBitmap(vcBitmap);
}
});
} Thread.sleep(100L);
}
} catch (InterruptedException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (MalformedURLException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
}
}
}
public Bitmap LoadBitmapFromNetwork(URL url) {
Bitmap vcBitmap = null; try {
String vcCredential = "admin:admin";
String vcEncode = Base64.encodeToString(
vcCredential.getBytes("UTF-8"), Base64.DEFAULT);
URLConnection vcConn = url.openConnection();
vcConn.setRequestProperty("Authorization",
String.format("Basic %s", vcEncode));
HttpURLConnection vcHttpConn = (HttpURLConnection) vcConn; if (vcHttpConn.getResponseCode() == HttpURLConnection.HTTP_OK) {
InputStream vcInStream = vcHttpConn.getInputStream();
vcBitmap = BitmapFactory.decodeStream(vcInStream);
vcInStream.close();
} vcHttpConn.disconnect();
} catch (IOException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} return vcBitmap;
} /**
* 视频直播
*
* @param image
*/
public class VlinCamLive implements Runnable { private ImageView vcImage; public VlinCamLive(ImageView image) {
vcImage = image;
} public void run() {
try {
URL vcUrl = new URL(getBaseContext().getResources().getString(
R.string.camera_ip)); while (true) {
final Bitmap vcBitmap = LoadBitmapFromNetwork(vcUrl); if (vcBitmap != null) {
vcImage.post(new Runnable() {
public void run() {
vcImage.setImageBitmap(vcBitmap);
}
});
} Thread.sleep(100L);
}
} catch (InterruptedException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (MalformedURLException e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
} catch (Exception e) {
Log.v("VlinCam", e.toString());
e.printStackTrace();
}
}
}
解决方案 »
- InputDispatcher异常,导致程序闪退,调试一个星期了,求高手
- POST提交数据不成功
- 有关ListView ,TextView焦点问题
- Andriod黑屏问题
- android 应用程序加载界面如何实现?求教!
- android 复制的调用
- 如何解决: E/AndroidRuntime:java.lang.NulPointerException
- 【2014访问android.com】哪位大大知道指导下或者私信,感激不尽~~
- 关于后台进程被kill的问题
- cordova build android时候出现这个错误,请问应该怎么解决
- Gallery放在layout中如何设置显示的位置呢?
- (大牛来挑战下,mtk出的一款软件就可以的)何如将<xliff:g>写入xml文件中
bmp.recycle();释放资源
InputStream vcInStream = vcHttpConn.getInputStream();
vcBitmap = BitmapFactory.decodeStream(vcInStream);
vcInStream.close();
}
图片过大会出错的,可以优化一下(具体看需求)
第一张图
vcImage.setImageBitmap(vcBitmap1);
第二张图
vcImage.setImageBitmap(vcBitmap2);
vcBitmap1.recycle();
不再显示的图片手动释放,差不多就这个意思
* Free the native object associated with this bitmap, and clear the
* reference to the pixel data. This will not free the pixel data synchronously;
* it simply allows it to be garbage collected if there are no other references.
* The bitmap is ed as "dead", meaning it will throw an exception if
* getPixels() or setPixels() is called, and will draw nothing. This operation
* cannot be reversed, so it should only be called if you are sure there are no
* further uses for the bitmap. This is an advanced call, and normally need
* not be called, since the normal GC process will free up this memory when
* there are no more references to this bitmap.
*/
public void recycle() {
if (!mRecycled) {
mBuffer = null;
nativeRecycle(mNativeBitmap);
mNinePatchChunk = null;
mRecycled = true;
}
}源码中说的比较清楚,你可以调用recycle()函数释放将指针置为null,等待系统GC回收,如果不置null系统GC永远不会回收,只会等程序完全退出才会释放内存。但是recycle也不是随便就能用的,很明确当你确定你不在使用时可以调用此函数进行内存释放,也就是说在你显示过之后你就可以将内存释放了。
我建议你在 public void run() { try { URL vcUrl = new URL(getBaseContext().getResources().getString( R.string.camera_ip)); while (true) { final Bitmap vcBitmap = LoadBitmapFromNetwork(vcUrl); if (vcBitmap != null) { vcImage.post(new Runnable() { public void run() { vcImage.setImageBitmap(vcBitmap); //在这之后加一句 vcBitmap.recycle(); } }); } Thread.sleep(100L); }
在C/C++中,new出来的内存 想手动释放就是 classP *p = new classP(); delete p; p=null;java只不过是倒过来 先将p=null delete的操作等待系统调用GC时统一释放java的内存管理实际上只是简化了程序猿的操作,不过呢开销比较大,在python 等面向对象语言中都与自己的内存管理方法,甚至在一些类库中都存在自己的管理方法,让程序猿自己在使用类库时减轻指针异常的压力