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

Calling finish() from SurfaceView does not destroy Activity

我想从 class RenderView finish() activity VideoPlayer。但是从 RenderView 调用 finish() 不会调用 onDestroy()。 Activity 没有被销毁,也没有 return 回到之前的 Main Activity.

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 但它 return 返回到调用 finish() 的方法 parseServerInfo() 并继续执行其余代码。

编辑

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;
    }
}

希望有人能帮忙指出我做错了什么。

您必须引用要在 SurfaceView 中完成的 Activity。您从 SurfaceView class 的构造函数中获取上下文。用这个 finish() 你的 activity,就像这样

//class member
private Context mContext;

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

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

    ...
}

最后你在那个上下文中调用 finish() 来完成你的 VideoPlayer activity。

这就是它继续并冻结的原因(如您问题的评论中所述)。这应该。这就是 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;
    }
}

所以你看到了祝酒词,结束了,说好开始了。但你不会回头看看你来自哪里。有了注释,你的初始化方法应该说的是

@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);
    }
}

这将解析您的数据,完成 activity 如果应该的话,然后停止使用您的 SurfaceView 初始化方法。抱歉有这么多冗余代码,但解释起来最简单:P