[Android后台活动返回到应用程序后消失

问题描述 投票:1回答:1

我同时在屏幕上看到活动AB

A是全屏活动,而B是较小的对话框活动。 B(对话框)在A顶部,当前处于活动状态。 A在下方可见,但已暂停。

B对话框中有一个按钮,单击该按钮后,用户将以共享Intent的身份离开应用程序,例如Gmail。返回该应用程序后,背景全屏活动A为黑色,并且仅对话框活动可见。

返回到应用程序时是否有信号通知活动A重绘自身,而没有关闭活动B(对话框)?

以下是退出该应用之前的屏幕截图。您可以一次看到两个活动。

Before leaving the app

以下是返回应用程序后的屏幕截图。您可以看到缺少后台活动,而对话框活动仍然可见并且可以。

After coming back

我想知道是否有一种方法可以发出信号,让后台活动重绘自身而不关闭对话框活动(startActivity不会成功,因为后台活动会成为前台)。

AndroidManifest.xml中的后台活动的定义是:

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

---更新---

我想我知道原因,但仍未成功解决。

活动A不是从XML定义构建的标准活动。它是纯SurfaceView活动。它创建一个SurfaceView并直接调用setContent(mySurfaceView)。表面视图启动线程onResume并杀死它onPause。这就是为什么当返回应用程序时,视图未开始绘制的原因,因为未调用onResume

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

android android-activity background dialog
1个回答
0
投票

我终于做到了。如果有人碰巧遇到相同的问题,我将描述我的解决方法。

后台活动A的生命周期方法如下:

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方法。在那里,我检查我们是否来自共享,如果是,则仅渲染一个帧。活动A中的代码如下所示:

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

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

令人讨厌的事情是,我循环并尝试获取曲面支架和画布。如果未成功,请睡眠50毫秒,然后重试几次。通常可以成功将持有者带入第二次迭代。

渲染单个框架的代码是这样的:


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

© www.soinside.com 2019 - 2024. All rights reserved.