Viol1997
Viol1997

Reputation: 173

Xamarin Forms Android app crashes after creating a class object during event handler

In my login page, whenever I create a class object of User (which is necessary to access its properties), the app crashes.

My Login page code:

using System;
using System.Collections.Generic;
using System.Linq;
using WeatherApp.Models;
using Xamarin.Forms;

namespace WeatherApp
{
    public partial class LoginPage : ContentPage
    {
        
        public LoginPage()
        {
         
            InitializeComponent();
            
        }

        async void Button_Clicked(System.Object sender, System.EventArgs e)
        {
            User user = new User();
            //var username = Username.Text;
            //var password = Password.Text;

            //var _user = user.GetUser(username);

            /*if (username == _user.Username && password == _user.Password)
            {
                 user.Username = username;
                 user.Firstname = _user.Firstname;
                 await DisplayAlert("Log in successful", null, "OK");
                 await Navigation.PushAsync(new ProfilePage(user));
            }
                
            else
            {
                await DisplayAlert("Log in failed", $"No such combination with username: {username}", "Try again");
            }*/

            await DisplayAlert("Test OK", null, "OK");
        }
    }
}

User class code:

using System;
using System.Collections.Generic;
using System.Linq;

namespace WeatherApp.Models
{
    public class User
    {
        public int Id { get; set; }
        public string Username { get; set; }
        public string Password { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }

        public List<User> _users = new List<User>
        {
            new User { Id = 1, Username = "user1", Password = "admin123", Firstname = "John", Lastname = "Doe" },
            new User { Id = 2, Username = "user2", Password = "admin123", Firstname = "Eric", Lastname = "Johnsson"},
            new User { Id = 3, Username = "user3", Password = "admin123", Firstname = "Elisabeth", Lastname = "Kant"}
        };

        public User GetUser(string username)
        {
            return _users.SingleOrDefault(u => u.Username == username);
        }

    }
}

I commented out the pieces of code that do not execute at all since the app already crashes when I instantiate the User object. I figured that the User object instantiation must be the problem since when I comment out the object instantiation, the "Test" DisplayAlert works perfectly fine. Another strange element here is that it used to work before, but suddenly it stopped working. My VS is up-to-date and I'm working with the Pie 9.0 - API 28 OS. The build output shows me the following error (not sure if related to the problem at hand):

    Thread started:  #9
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_call_static_void_method_a'.
[Mono] Probing 'java_interop_jnienv_call_static_void_method_a'.
[Mono] Found as 'java_interop_jnienv_call_static_void_method_a'.
[] HostConnection::get() New Host Connection established 0xd0b49740, tid 8352
[ConfigStore] android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasWideColorDisplay retrieved: 0
[ConfigStore] android::hardware::configstore::V1_0::ISurfaceFlingerConfigs::hasHDRDisplay retrieved: 0
[OpenGLRenderer] Initialized EGL, version 1.4
[OpenGLRenderer] Swap behavior 1
[OpenGLRenderer] Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
[OpenGLRenderer] Swap behavior 0
[EGL_emulation] eglCreateContext: 0xd1136580: maj 3 min 0 rcv 3
[EGL_emulation] eglMakeCurrent: 0xd1136580: ver 3 0 (tinfo 0xd0af1d60)
[Choreographer] Skipped 31 frames!  The application may be doing too much work on its main thread.
[EGL_emulation] eglMakeCurrent: 0xd1136580: ver 3 0 (tinfo 0xd0af1d60)
[OpenGLRenderer] Davey! duration=847ms; Flags=0, IntendedVsync=4884011429238, Vsync=4884528095884, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=4884531739711, AnimationStart=4884531936711, PerformTraversalsStart=4884533006711, DrawStart=4884536005711, SyncQueued=4884760953711, SyncStart=4884764832711, IssueDrawCommandsStart=4884773311711, SwapBuffers=4884824837711, FrameCompleted=4884862621711, DequeueBufferDuration=734000, QueueBufferDuration=3630000, 
[Mono] DllImport searching in: '__Internal' ('(null)').
[Mono] Searching for 'java_interop_jnienv_call_float_method_a'.
[Mono] Probing 'java_interop_jnienv_call_float_method_a'.
[Mono] Found as 'java_interop_jnienv_call_float_method_a'.
[Mono] Requesting loading reference 7 (of 11) of /storage/emulated/0/Android/data/com.companyname.weatherapp/files/.__override__/Xamarin.Android.Support.Fragment.dll
[Mono] Loading reference 7 of /storage/emulated/0/Android/data/com.companyname.weatherapp/files/.__override__/Xamarin.Android.Support.Fragment.dll asmctx DEFAULT, looking for Xamarin.Android.Arch.Lifecycle.LiveData.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
[Mono] Assembly Ref addref Xamarin.Android.Support.Fragment[0xe885cfe0] -> Xamarin.Android.Arch.Lifecycle.LiveData.Core[0xe885c260]: 2
[Choreographer] Skipped 36 frames!  The application may be doing too much work on its main thread.
[Mono] Requesting loading reference 7 (of 8) of /storage/emulated/0/Android/data/com.companyname.weatherapp/files/.__override__/WeatherApp.Android.dll
[Mono] Loading reference 7 of /storage/emulated/0/Android/data/com.companyname.weatherapp/files/.__override__/WeatherApp.Android.dll asmctx DEFAULT, looking for Xamarin.Forms.Platform, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null
[Mono] Assembly Ref addref WeatherApp.Android[0xe885ba80] -> Xamarin.Forms.Platform[0xe885de20]: 3
[OpenGLRenderer] Davey! duration=768ms; Flags=0, IntendedVsync=4891577757377, Vsync=4892177757353, OldestInputEvent=9223372036854775807, NewestInputEvent=0, HandleInputStart=4892194044711, AnimationStart=4892194119711, PerformTraversalsStart=4892195493711, DrawStart=4892336371711, SyncQueued=4892337359711, SyncStart=4892337854711, IssueDrawCommandsStart=4892338010711, SwapBuffers=4892338797711, FrameCompleted=4892346959711, DequeueBufferDuration=1586000, QueueBufferDuration=3761000, 
[Choreographer] Skipped 30 frames!  The application may be doing too much work on its main thread.
[libc] Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xff7d5f94 in tid 8292 (name.weatherapp), pid 8292 (name.weatherapp)

This is the error that the emulator displays:

enter image description here

Fixing this problem would really make my day, since I'm struggling with it already for hours.

Upvotes: 1

Views: 296

Answers (1)

Jason
Jason

Reputation: 89102

you need to create a UserService separate from your User model

public class User
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}

public class UserService {
    
    private List<User> _users = new List<User>
    {
        new User { Id = 1, Username = "user1", Password = "admin123", Firstname = "John", Lastname = "Doe" },
        new User { Id = 2, Username = "user2", Password = "admin123", Firstname = "Eric", Lastname = "Johnsson"},
        new User { Id = 3, Username = "user3", Password = "admin123", Firstname = "Elisabeth", Lastname = "Kant"}
    };

    public User GetUser(string username)
    {
        return _users.SingleOrDefault(u => u.Username == username);
    }

}

then your click handler would look like this

    async void Button_Clicked(System.Object sender, System.EventArgs e)
    {
        var svc = new UserService();

        var username = Username.Text;
        var password = Password.Text;

        var _user = svc.GetUser(username);

        if (_user != null && username == _user.Username && password == _user.Password)
        {
             await DisplayAlert("Log in successful", null, "OK");
             await Navigation.PushAsync(new ProfilePage(_user));
        }
            
        else
        {
            await DisplayAlert("Log in failed", $"No such combination with username: {username}", "Try again");
        }

        await DisplayAlert("Test OK", null, "OK");
    }

Upvotes: 2

Related Questions