MvvmCross Android 在发布模式下绑定 EditText

MvvmCross Android binding EditText in release mode

我在 Android 平台上绑定 EditText 时遇到问题。 今天我将我的项目 MvvmCross 框架从 6.2.X 更新到 6.3.1(+ 更新其他 NuGets)并将 TargetSdk 和 CompileSdk 从 Android 8.1 更改为 9.0 现在当我有发布模式和链接集时"Sdk Assemblies" 只有我的应用程序在绑定了 EditText 的 View 上崩溃。在调试中,我检查了 "Use Shared Runtime" 并将链接设置为 "None" 没有问题。

我在 LinkerPleaseInclude 中包含了 TextView:

public void Include(TextView text)
{
    text.AfterTextChanged += (sender, args) => text.Text = $"{text.Text}";
    text.Hint = $"{text.Hint}";
}

它抛出这个异常:https://pastebin.com/EmkuL7hM

布局:

   <?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:local="http://schemas.android.com/apk/res-auto"
    android:fillViewport="true"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <LinearLayout
        android:paddingTop="50dp"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/backgroundColor">
       <LinearLayout
            android:layout_margin="10dp"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
            <ImageView
                android:id="@+id/logo"
                android:layout_width="200dp"
                android:layout_height="100dp"
                android:src="@drawable/ic_logo_red"
                android:scaleType="fitCenter" />
        </LinearLayout>
       <LinearLayout
            android:layout_marginTop="10dp"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
            <TextView
                android:text="Email"
                local:MvxLang="Text Email"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/primaryColor"
                android:textStyle="bold"
                android:textSize="@dimen/text_medium" />
            <EditText
                android:layout_marginTop="5dp"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                local:MvxBind="Text LoginName"
                android:singleLine="true"
                android:inputType="textEmailAddress"
                android:background="@color/white"
                android:cursorVisible="true"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColorHint="@color/primaryTextColor"
                android:textColor="@color/primaryTextColor" /> 

            </LinearLayout>
            <LinearLayout
            android:layout_marginTop="10dp"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
            <TextView
                android:text="Password"
                local:MvxLang="Text Password"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textColor="@color/primaryColor"
                android:textStyle="bold"
                android:textSize="@dimen/text_medium" />
            <EditText
                android:layout_marginTop="5dp"
                android:layout_width="match_parent"
                android:layout_height="40dp"
                local:MvxBind="Text Password"
                android:singleLine="true"
                android:inputType="textPassword"
                android:background="@color/white"
                android:cursorVisible="true"
                android:paddingLeft="10dp"
                android:paddingRight="10dp"
                android:textColorHint="@color/primaryTextColor"
                android:textColor="@color/primaryTextColor" />
        </LinearLayout>
        <LinearLayout
            android:layout_marginTop="20dp"
            android:layout_marginLeft="25dp"
            android:layout_marginRight="25dp"
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:gravity="center">
            <Button
                android:gravity="center"
                android:id="@+id/loginButton"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:textSize="@dimen/text_large"
                local:MvxLang="Text Login"
                local:MvxBind="Click LoginCommand"
                android:padding="10dp"
                android:background="@drawable/button_round_primary"
                android:textColor="@color/white"
                android:text="Login"
                android:textStyle="bold" />
        </LinearLayout> 
    </LinearLayout>
</ScrollView>

ViewModel:

  public class LoginViewModel : MvxViewModel
    {
        private readonly IMvxNavigationService _navigationService;
        private readonly IInfoMessageReporter _infoMessageReporter;
        private readonly ISessionInfo _session;
        private readonly ILoginService _loginService;
        private readonly IDataService _dataService;

        public LoginViewModel()
        {
            _navigationService = Mvx.IoCProvider.Resolve<IMvxNavigationService>();
            _infoMessageReporter = Mvx.IoCProvider.Resolve<IInfoMessageReporter>();
            _session = Mvx.IoCProvider.Resolve<ISessionInfo>();
            _loginService = Mvx.IoCProvider.Resolve<ILoginService>();
            _dataService = Mvx.IoCProvider.Resolve<IDataService>();

            RememberLogin = true;
        }

        public IMvxLanguageBinder TextSource => new MvxLanguageBinder(Constants.LocalizationNamespace, GetType().Name);

        public override async Task Initialize()
        {
            await InitializePermissionsAsync();
        }

        private async Task InitializePermissionsAsync()
        {
            // some stuff...
        }

        private string _password;
        public string Password
        {
            get => _password;
            set
            {
                _password = value;
                RaisePropertyChanged(() => Password);
            }
        }

        private string _loginName;
        public string LoginName
        {
            get => _loginName;
            set
            {
                _loginName = value;
                RaisePropertyChanged(() => LoginName);
            }
        }

        private MvxAsyncCommand _loginCommand;
        public IMvxAsyncCommand LoginCommand
        {
            get
            {
                _loginCommand = _loginCommand ?? new MvxAsyncCommand(async () => await ExecuteLoginAsync());
                return _loginCommand;
            }
        }

        private async Task ExecuteLoginAsync()
        {
            // some stuff....
        }
    }

我认为您遇到的问题是 Xamarin 最新版本(围绕 Xamarin Android 9.4)中的当前错误。可以在 GitHub 上跟踪此问题 here


建议的解决方法

In case any other users come across this issue when using Xamarin.Android 9.4, a possible workaround is to use a custom linker configuration to preserve the missing types. To do that, add a new linker.xml file to the project, set the Build Action to LinkDescription, and add the XML lines to preserve the missing types. For example, for the ITextWatcherInvoker error, add the following lines to the file:

<linker>
 <assembly fullname="Mono.Android">
   <type fullname="Android.Text.ITextWatcherInvoker" preserve="all" />
 </assembly>
</linker>