質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.60%

【Uno Platform】(Android)NativePivotPresenterのメモリ解放について

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 148

net-ohkubo

score 6

知りたい事
NativePivotPresenterでのメモリ解放について

環境説明
Visual Studio 2019で、Uno Platformを用いてAndroid開発を行っております。

画面のUIに、NativePivotPresenter(Uno Platform独自のUI)
を利用しているのですが、上記を利用している画面については
画面の操作を行うごとにメモリ使用量が増加し、画面遷移後にも
メモリが解放されずにメモリリークを起こす状態となっています。

該当部位を、通常のPivotへ部品を変更すると、
画面遷移後に正しくデストラクタが呼ばれ、その後
ガベージコレクションによりメモリ解放される動きをしております。
以下、NativePivotPresenterを利用した実装箇所の抜粋です。

app.xaml.cs

new Setter<NativePivotPresenter>("Template", pb => pb
    .Template = new Windows.UI.Xaml.Controls.ControlTemplate(() =>
        new Windows.UI.Xaml.Controls.Grid
        {
            RowDefinitions =
            {
                new Windows.UI.Xaml.Controls.RowDefinition(){ Height = Windows.UI.Xaml.GridLength.Auto},
                new Windows.UI.Xaml.Controls.RowDefinition(){ Height = new Windows.UI.Xaml.GridLength(1, Windows.UI.Xaml.GridUnitType.Star)},
            },

            Children =
            {
                // Header
                new Border
                {
                    Child = new Uno.UI.Controls.SlidingTabLayout(ContextHelper.Current)
                    {
                        LayoutParameters = new Android.Views.ViewGroup.LayoutParams(Android.Views.ViewGroup.LayoutParams.MatchParent, Android.Views.ViewGroup.LayoutParams.WrapContent),
                    },
                    BorderThickness = new Windows.UI.Xaml.Thickness(0,0,0,1),
                }
                .Apply(b => b.SetBinding("Background", new Windows.UI.Xaml.Data.Binding { Path = "Background", RelativeSource = RelativeSource.TemplatedParent }))
                .Apply(b => b.SetBinding("BorderBrush", new Windows.UI.Xaml.Data.Binding { Path = "BorderBrush", RelativeSource = RelativeSource.TemplatedParent })),

                // Content
                new ExtendedViewPager(ContextHelper.Current)
                {
                    OffscreenPageLimit = 1,
                    PageMargin = (int)Android.Util.TypedValue.ApplyDimension(Android.Util.ComplexUnitType.Dip, 4, ContextHelper.Current.Resources.DisplayMetrics),
                    SwipeEnabled = true,
                }
                .Apply(v => Windows.UI.Xaml.Controls.Grid.SetRow(v, 1))
            }
    })
)

menu.xaml

<Page
    x:Class="xxxxx.Menu"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:xxxxx.Display.Order"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d android"
    xmlns:android="http://uno.ui/android"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    Name="MenuPage">
    <Grid Background="White"  x:Name="MenuMainGrid" Loaded="Menu_Loaded">
        <StackPanel Grid.RowSpan="2" Name="titlePanel" Background="White">
            <Grid Height="45" VerticalAlignment="Center" Name="TitleGrid">
       (略)
            </Grid>
            <NativePivotPresenter x:Name ="Menu" Margin="0" Height="570" Background="White">
                <!--ここにコントロールが動的に追加される-->
            </NativePivotPresenter>
        </StackPanel>
    </Grid>
</Page>


menu.xaml.cs

// 画面表示
private void setDisp()
{
   {
      //  SQLiteで対象リスト listOfMenu を取ってくる(略)
          (略)

        var listOfMenu = queryMenu.ToList();
        for (int i = 0; i <= listOfMenu.Count() - 1; i++)
        {
            PivotItem MenuItem = new PivotItem();
            MenuItem.Height = 400;
            MenuItem.Width = 380;
            MenuItem.Margin = new Windows.UI.Xaml.Thickness(0);
            MenuItem.Background = new SolidColorBrush(Colors.White);
            MenuItem.Header = xxxx.Name;

            // その他設定
       (略)
            }
            MenuItem.Content = sv;
            Menu.Items.Add(MenuItem); 
        }
    }
}

UnopatformのGitHubのソース(NativePivotPresenterPivot)を確認すると、
Pivotの場合はおそらくUWPのリソースのみを使用して作成していますが
NativePivotPresenterの場合、主にandroidのリソースを利用して
作成しており、この辺りで参照がMainActivity側から発生しているため
実行しているUWP上ではガベージコレクションの回収対象にならないのではないかと思います。

OS違いですがこちらのサイトも参考にし、
後述の試行錯誤の通りメモリ解放されるよう試みているのですが、
この参照を確実に切り、メモリ解放する方法が分からずに困っております。
同部品(NativePivotPresenter)を使用されたご経験がある方の
お知恵を拝借したいと思います。

以下、試行錯誤したのですが全てメモリ解放が見られなかった内容

・NativePivotPresenterの記載箇所を、Xaml側からC#側に記載しなおして試験
・画面遷移後にNativePivotPresenterを要素から明示的に削除
・NativePivotPresenter.Dispose()
・NativePivotPresenter.items.Clear()の後、null代入して参照切り
・NativePivotPresenter.items.Clear()の後、Dispose()し、null代入して参照切り
・弱参照に変更し、その後参照を削除
・NativePivotPresenterの親要素にGridを追加し、画面遷移後にGridの子要素をClear()
・Pivotを用意しておいてそれを削除し、NativePivotPresenterに置換

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.60%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る