【问题标题】:Dispose and restart OpenGLView in monodroid在 monodroid 中处理并重新启动 OpenGLView
【发布时间】:2012-11-07 09:32:04
【问题描述】:

我正在尝试在同一个 Activity 中处置和重新启动 OpenGLView 或 AndroidGameView,但在同一个 Activity 中处置后,游戏似乎无法再次启动。这是我使用 monodroid 游戏示例项目的测试:

GLView1 view;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Create our OpenGL view, and display it
        //view = new GLView1(this);
        //SetContentView(view);

        Timer timer = new Timer(OnTimerDone, this, 3000, 3000);
    }

    void OnTimerDone(object state)
    {
        System.Diagnostics.Debug.WriteLine("timer");
        ((Activity)state).RunOnUiThread(() =>
            {
                if (view != null)
                {
                    //view.Stop();
                    view.Dispose();
                    view = null;
                    SetContentView(null);
                    GC.Collect();
                }
                else
                {
                    view = new GLView1((Activity)state);
                    //view.Resume();
                    SetContentView(view);
                }
            });
    }

    //protected override void OnPause()
    //{
    //    base.OnPause();
    //    view.Pause();
    //}

    //protected override void OnResume()
    //{
    //    base.OnResume();
    //    view.Resume();
    //}

提前感谢您的帮助。

更新我的新代码以避免重复使用 SetContentView:

GLView1 view;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Create our OpenGL view, and display it
        //view = new GLView1(this);
        //SetContentView(view);
        SetContentView(Resource.Layout.Main);
        Timer timer = new Timer(OnTimerDone, this, 3000, 3000);
    }

    void OnTimerDone(object state)
    {
        ((Activity)state).RunOnUiThread(() =>
            {
                LinearLayout linearLayoutMain = ((Activity)state).FindViewById<LinearLayout>(Resource.Id.linearLayoutMain);
                if (view != null)
                {
                    System.Diagnostics.Debug.WriteLine("timer delete");
                    linearLayoutMain.RemoveView(view);
                    try
                    {
                        view.Stop();
                        view.Dispose();
                        view = null;
                        //SetContentView(null);
                        GC.Collect();
                    }
                    catch (Exception ex)
                    {
                        //Android.Util.Log.Debug("ex:", ex.ToString());
                        System.Diagnostics.Debug.WriteLine("ex:" + ex);
                    }
                }
                else
                {
                    view = new GLView1((Activity)state);
                    view.Run();
                    //view.Resume();
                    //SetContentView(view);
                    linearLayoutMain.AddView(view);
                    System.Diagnostics.Debug.WriteLine("timer create");

                }
            });
    }

【问题讨论】:

  • 您遇到的错误是什么?
  • 我没有收到任何错误:我认为 GLView 未正确处理是因为计时器第二次停止而没有引发任何异常!我也尝试不重用SetContentView,但问题依旧。
  • 这可能是一个愚蠢的问题,但是您是否尝试过将其包装在 Try/Catch 块中并输出任何异常消息?我发现有时我必须使用 MonoTouch 来执行此操作,因为运行时会吞噬一些异常。
  • 是的,我知道这个错误,尤其是在使用线程时,但我尝试了但没有得到任何结果。计时器已停止,仅此而已!
  • 如果将 SetContentView(null) 移到 view.Dispose() 上方会怎样??

标签: xamarin.android xamarin


【解决方案1】:

我玩弄了你的代码,发现Timer 仍在 仍在运行,但RunOnUiThread() 中的块没有被调用。我删除了view.Stop() 方法和view.Dispose(),它开始正常工作。

这是我的完整代码(使用 5000 毫秒的时间间隔)

    GLView1 view;

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        SetContentView(Resource.Layout.Main);
        Timer timer = new Timer(OnTimerDone, this, 5000, 5000);
    }

    void OnTimerDone(object state)
    {
        RunOnUiThread(() =>
        {
            try
            {
                LinearLayout linearLayoutMain = ((Activity)state).FindViewById<LinearLayout>(Resource.Id.linearLayoutMain);

                if (view != null)
                {
                    linearLayoutMain.RemoveView(view);
                    view = null;
                }
                else
                {
                    view = new GLView1(this);
                    view.Run();
                    linearLayoutMain.AddView(view);
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.ToString());
            }
        });
    }

旧视图似乎仍被垃圾收集(请参阅下面的日志)。我不认为额外的电话是必要的。我连续运行了大约 15 分钟的应用程序,没有任何问题。

11-16 00:30:05.828 D/dalvikvm( 2144): GC_EXPLICIT freed 119K, 6% free 8813K/9351K, paused 3ms+5ms, total 56ms
11-16 00:30:08.047 D/dalvikvm( 2144): GC_CONCURRENT freed 992K, 12% free 8270K/9351K, paused 4ms+36ms, total 162ms
11-16 00:30:10.667 D/dalvikvm( 2144): GC_CONCURRENT freed 202K, 10% free 8467K/9351K, paused 5ms+63ms, total 116ms

【讨论】:

  • 谢谢。我再也不会尝试做 GC 工作了!
猜你喜欢
  • 2016-11-27
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
  • 2019-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多