如何加载大量的位图而不会崩溃Android中的应用程序

时间:2011-02-25 21:01:43

标签: android memory-management bitmap android-ndk android-video-player

我正致力于从网络流式传输视频。我在本机代码中解码视频/音频内容并获取视频的原始像素

我在java代码中创建一个位图,使用surfaceholder和canvas,并从本机代码更新每个位图的像素,然后将位图作为视频流传输。我的问题是,由于内存不足,视频会在几秒钟后崩溃。

我想知道是否有任何我需要确保不会崩溃应用程序并使用低内存。

这是我的代码。

public CanvasThread(SurfaceHolder surfaceHolder, Panel panel) {
    _surfaceHolder = surfaceHolder;
    _panel = panel;     }
public void setRunning(boolean run) {
    _run = run;    }

@Override
public void run() {
    Canvas c;
    while (_run) {
        c = null;
        try {
            c = _surfaceHolder.lockCanvas(null);
            synchronized (_surfaceHolder) {
                _panel.onDraw(c);
            }
        } finally {
                if (c != null) {
                _surfaceHolder.unlockCanvasAndPost(c);
            }
       }    

  public class Panel extends SurfaceView implements SurfaceHolder.Callback{
    private CanvasThread canvasthread;
    private static Bitmap mBitmap;
    private static boolean ii=false;
       public Panel(Context context, AttributeSet attrs) {
        super(context, attrs); 
        getHolder().addCallback(this);
        canvasthread = new CanvasThread(getHolder(), this);
        setFocusable(true);
       mBitmap=Bitmap.createBitmap(480, 320, Bitmap.Config.RGB_565);//bitmap created in constructor
    }

     public Panel(Context context) {
           super(context);
            getHolder().addCallback(this);
            canvasthread = new CanvasThread(getHolder(), this);
            setFocusable(true);
        }

     private static native void renderbitmap(Bitmap bitmap); //native function
    @Override
    public void onDraw(Canvas canvas) {

        renderbitmap(mBitmap); //Update pixels from native code
        canvas.drawBitmap(mBitmap, 0,0,null);//draw on canvas
}

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {        }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        canvasthread.setRunning(true);
        canvasthread.start();       }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        boolean retry = true;
        canvasthread.setRunning(false);
        while (retry) {
            try {
                canvasthread.join();
                retry = false;
            } catch (InterruptedException e) {              }
    }

3 个答案:

答案 0 :(得分:1)

这可能不会因为你的内存量有限。仿真器可能大约为16MB。您不应将所有图像存储在内存中。你必须选择

  1. 修复算法,不要这样做 需要记忆中的一切
  2. 或者只在内存中保留一张图片 其余的在磁盘上

答案 1 :(得分:1)

通过快速扫描代码,您的基本问题似乎是每次调用OnDraw方法时都在创建新的位图。相反,请注释掉该行,并在启动时仅为mBitmap创建一次位图。

答案 2 :(得分:1)

你可以查看Richard Quirk的glbuffer。我在视频播放器应用程序中使用它。

通常,您希望保留您正在接收的视频数据包,并且只在它们需要显示之前解码它们。将代码与glbuffer集成并绕过Java代码中的任何Bitmap分配应该很容易。

在本机代码和GL纹理存储器中存在的任何给定时间将存在一个解码帧,并且您将保留用于缓冲的若干编码数据包。