从SurfaceView调用finish()不会破坏Activity

时间:2015-03-14 12:38:51

标签: java android android-activity surfaceview

我想finish()来自班级VideoPlayer的活动RenderView。但是,从finish()调用RenderView不会调用onDestroy()。活动不会被销毁,也不会返回到之前的主要活动。

public class VideoPlayer extends Activity  {

    @Override
    protected void onPause(){
        super.onPause();
        renderView.pause();     
    }

    @Override
    protected void onStop() {
        super.onStop();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        naClose2();
    }

}

mFinished = true但它会返回调用parseServerInfo()的方法finish()并继续执行其余代码。

修改

public class RenderView extends SurfaceView implements SurfaceHolder.Callback   {
    private Context mContext;

    private Runnable prDisplayVideoTask = new Runnable() {
        public void run() {
            if(zoomState.isPlaying()==false){
                if(zoomState.getFlag()==FlagType.PAUSE){
                    zoomState.setFlag(FlagType.NONE);
                    naPause();
                }
            } else {
                naStart();
            }
            prVideoDisplayHandler.postDelayed(this, prDelay);
        }
    };

    public RenderView(...) {
        super(_context);
        this.mContext = _context;
        init(address, windowWidth, windowHeight, videoWidth, videoHeight,
                server_ip, server_port);
        SurfaceHolder holder = getHolder();
        holder.setFormat(PixelFormat.RGBA_8888);
        holder.addCallback(this);
    }

    @SuppressLint("NewApi")
    public void init(...) {
        parseServerInfo(receivedData);
        prVideoDisplayHandler.removeCallbacks(prDisplayVideoTask);
        prVideoDisplayHandler.postDelayed(prDisplayVideoTask, prDelay);
    }

    public void pause(){
        naPause();
        prVideoDisplayHandler.removeCallbacks(prDisplayVideoTask);
    }

    public void resume(){
        prVideoDisplayHandler.postDelayed(prDisplayVideoTask, prDelay);
    }

    public void parseServerInfo(String data) {
        if (numCameras == 0) {
            Toast.makeText(mContext, "No stream detected!", Toast.LENGTH_LONG).show();

            // Finish is called here
            VideoPlayer videoplayer = (VideoPlayer) mContext;
            videoplayer.finish();
            return;
        }
    }

    @Override
    public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        if (mCreated  == true) {
            surfaceDestroyed(holder);
        }
        Surface surface = holder.getSurface();
        render(surface);
        mCreated = true;
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        mCreated = false;
    }
}

希望有人可以帮助指出我做错了什么。

2 个答案:

答案 0 :(得分:1)

这就是为什么它会继续并冻结(正如你的问题的评论中所提到的)。这应该。这就是java语言的工作方式。这里,

@SuppressLint("NewApi")
public void init(...) {
    parseServerInfo(receivedData);
    ...
}

你打电话给parseServerInfo(receivedData);

public void parseServerInfo(String data) {
    if (numCameras == 0) {
        Toast.makeText(mContext, "No stream detected!", Toast.LENGTH_LONG).show();

        // Finish is called here
        VideoPlayer videoplayer = (VideoPlayer)getContext();
        videoplayer.finish();
        return;
    }
}

所以你看到Toast,完成调用,然后说好话。但是你不回头看你来自哪里。有了注释,你的init方法应该说的是

@SuppressLint("NewApi")
public void init(...) {
    // make a call to check that the number of cameras is not 0
    parseServerInfo(receivedData);    
    // AND CONTINUE NO MATTER WHAT...
    prVideoDisplayHandler.removeCallbacks(prDisplayVideoTask);
    prVideoDisplayHandler.postDelayed(prDisplayVideoTask, prDelay);
}

您需要的是

public boolean parseServerInfo(String data) {
    if (numCameras == 0) {
        Toast.makeText(mContext, "No stream detected!", Toast.LENGTH_LONG).show();

        // Finish is called here... AND FALSE IS RETURNED
        VideoPlayer videoplayer = (VideoPlayer) mContext;
        videoplayer.finish();
        return false;
    }
    return true;
}

然后

@SuppressLint("NewApi")
public void init(...) {
    // make a call to check that the number of cameras is not 0
    // AND CONTINUE IF GOOD (TRUE)
    if(parseServerInfo(receivedData)){
        prVideoDisplayHandler.removeCallbacks(prDisplayVideoTask);
        prVideoDisplayHandler.postDelayed(prDisplayVideoTask, prDelay);
    }
}

这将解析您的数据,如果它应该完成活动,然后使用SurfaceView init方法停止进度。很抱歉这么多冗余代码,但最简单的解释一下:P

答案 1 :(得分:0)

您必须在SurfaceView内引用您想要完成的活动。您从SurfaceView类的构造函数中获取上下文。用这个来finish()您的活动,就像这样

//class member
private Context mContext;

public RenderView(...) {
    super(_context);

    //make the context accessible from the whole class
    this.mContext = _context;

    ...
}

最后,您在该上下文中调用finish()来完成VideoPlayer活动。