Android 返回应用程序时背景 activity 消失

Android background activity disappears when coming back to the app

我有 activity AB 同时在屏幕上可见。

A 是全屏 activity,B 是小对话框 activity。 B(对话框)位于 A 之上并且当前处于活动状态。 A 在下方可见,但已暂停。

B 对话框中有一个按钮,单击该按钮后,用户将退出应用程序并共享 Intent,例如 Gmail。回到应用程序后,背景全屏 activity A 是黑色的,只有对话框 activity 可见。

有没有办法在不关闭 activity B(对话框)的情况下向 activity A 发出信号以在返回应用程序时重新绘制自身?

下面是退出应用前的屏幕截图。您可以同时看到这两个活动。

下面是返回应用程序后的屏幕截图。你可以看到背景 activity 不见了,而对话框 activity 仍然可见并且正常。

我想知道是否有一种方法可以在不关闭对话框的情况下向背景 activity 发出重绘自身的信号 activity(startActivity 不会成功,因为背景 activity 将成为前景)。

背景activity在AndroidManifest.xml中的定义是:

        <activity
            android:name="com.mypackage.thegame.GameActivity"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:launchMode="singleTask"
            />

---更新---

我想我知道这其中的原因,但仍然没有成功的解决方法。

Activity A 不是根据 XML 定义构建的标准 activity。是纯粹的SurfaceViewactivity。它创建一个 SurfaceView 并直接调用 setContent(mySurfaceView)。表面视图启动一个线程 onResume 并杀死它 onPause。这就是为什么当返回到应用程序时视图不会开始绘制,因为 onResume 没有被调用。

但是,我发现调用了 onStart 方法,我在其中放置了代码,以便在单独的线程中仅渲染当前状态的一帧(也在调用它的线程中尝试过)。但表面视图似乎无法获得要在其上绘制的 holder 和 canvas...我将继续调查,如果发现更多详细信息,请 post。

我终于做到了。我将描述我的解决方法,以防有人遇到同样的问题。

后台生命周期方法activityA如下:

App Launch

-> onCreate
-> onStart
-> onResume (drawing thread is started)

Dialog Activity B Launches

-> onPause (drawing thread is killed)

Leave App

---

Come back to App

-> onStart (nothing happens, drawing thread does not exist)

A 唯一可以重绘自身的地方是 onStart 方法。在那里我检查我们是否来自 Share,如果是,我只渲染一个帧。 activity A 中的代码如下所示:

class MyActivity {
    public void onStart() {
        super.onStart();

        if (afterShare) {
            surfaceView.renderSingleFrame();
        }
    }
}

棘手的事情是我循环并尝试获取表面支架和 canvas。如果不成功,则休眠 50ms,然后重试几次。它通常会在第二次迭代时成功拿下 holder。

渲染单帧的代码是这样的:


public void renderSingleFrame() {
    Runnable runnable = new Runnable() {
        public void run() {
            int retry = 0;
            while(retry < 5) {
                if (!holder.getSurface().isValid()) {
                    retry++;  
                    try { Thread.sleep(50); } catch (InterruptedException e) {}  
                    continue;               
                }

                Canvas canvas = null;  

                try {  
                    canvas = holder.lockCanvas();  
                    if (canvas != null) {
                        this.drawFrame(canvas, 0); // canvas, deltaTime
                    }
                }  
                catch(Exception e) {}  
                finally {  
                    if (canvas != null && holder.getSurface().isValid()) {  
                        holder.unlockCanvasAndPost(canvas);  
                    } 
                }

                break;
            }
        }
    };

    Thread thread = new Thread(runnable);
    thread.start();
}