Xamarin Form Exception Heaps size and OutOfMemoryError - xamarin

How can I enable large heap in my Xamarin.Forms application ?
Here is MainActivity.cs Android code:
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
RoundedBoxViewRenderer.Init();
LoadApplication(new App());
}
}
See Exception Screenshot below:

Go to project Options > Android Build > General > Enable MultiDex & Options > Android Build > Advacnced > JavaHeapSize (Set 3G) , In manifest file you can add android:largeHeap="true" in Application Tag
<application android:largeHeap="true"/>

The Xamarin way of setting the Dalvik/Art large heap via the Appication attribute:
Application.cs
using System;
using Android.App;
using Android.Runtime;
namespace LargeHeap
{
[Application(LargeHeap = true)]
public class XamarinApplication : Application
{
public XamarinApplication(IntPtr handle, JniHandleOwnership ownerShip) : base(handle, ownerShip)
{
}
}
}
If true, then the process should be created with a large Dalvik heap; otherwise, the process will be created with the default Dalvik heap.
Ref: https://developer.xamarin.com/api/property/Android.App.ApplicationAttribute.LargeHeap/

My contribution, it worked for me:
[assembly: Application(LargeHeap = true)]
namespace Project.Droid
{
[Activity(.............)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
}
}

Related

Accessing ViewModel properties from Viewclass

I want to call Content page class from Android .cs Class.
I use StartActivity(new Intent(Application.Context, typeof(LoginPage)));
showing error message
"System.ArgumentException: type Parameter name: Type is not derived
from a java type "
Does anyone know the solution for this? Please help me in Xamarin.Forms.
This should be you App.xaml.cs class
public App()
{
MainPage = new NavigationPage ( new MainPage());
}
MainActivity.cs file
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsApplicationActivity
{
private TextView setting;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
SetContentView(Resource.Layout.HomeScreen);
setting = FindViewById<TextView>(Resource.Id.settingText);
//check setting button is null or have value
setting.Click += delegate
{
Xamarin.Forms.Application.Current.MainPage.Navigation.PushAsync(new LoginPage());
};
}
}
Use code above & debug to check if setting button have instance or is null.
Replace typeof(LoginPage) with LoginPage.Class or LoginPage::Class.java (kotlin)

Xamarin.Android Architecture Components: Not getting callbacks for lifecycle events

I'm trying to use the architecture components package for detecting when the application enters background or foreground state. The problem is that the callbacks are not being invoked. In the sample code below, the methods onApplicationForegrounded and onApplicationBackgrounded are not invoked:
namespace POC.Droid
{
[Application]
public class MyApp : Application, ILifecycleObserver
{
static readonly string TAG = "MyApp";
public MyApp(IntPtr handle, Android.Runtime.JniHandleOwnership ownerShip) : base(handle, ownerShip)
{
}
public override void OnCreate()
{
base.OnCreate();
ProcessLifecycleOwner.Get().Lifecycle.AddObserver(this);
}
[Lifecycle.Event.OnStop]
public void onAppBackgrounded()
{
Log.Debug(TAG, "App entered background state.");
}
[Lifecycle.Event.OnStart]
public void onAppForegrounded()
{
Log.Debug(TAG, "App entered foreground state.");
}
}
}
My Xamarin version is 8.2.0.16 (Visual Studio Community) and Xamarin.Android.Arch.Lifecycle.Extensions version is 1.0.0. I'm using a Nougat device (7.0) for testing.
TL;DR Please annotate your lifecycle callbacks with [Export]
Here a more detailed description:
Generally, to get the methods of a lifecycle observer be invoked, please make sure that the related packages are present. Here is a part of my packages.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Xamarin.Android.Arch.Core.Common" version="26.1.0" targetFramework="monoandroid81" />
<package id="Xamarin.Android.Arch.Core.Runtime" version="1.0.0.1" targetFramework="monoandroid81" />
<package id="Xamarin.Android.Arch.Lifecycle.Common" version="26.1.0" targetFramework="monoandroid81" />
<package id="Xamarin.Android.Arch.Lifecycle.Extensions" version="1.0.0.1" targetFramework="monoandroid81" />
<package id="Xamarin.Android.Arch.Lifecycle.Runtime" version="1.0.3.1" targetFramework="monoandroid81" />
This is how this looks in Visual Studio:
To be able to set a lifecycle observer, we need a lifecycle owner. On the application level this can be ProcessLifecycleOwner, just like the original poster showed.
Here is a slightly modified version:
using System;
using Android.App;
using Android.Arch.Lifecycle;
using Android.Util;
using Java.Interop;
namespace Stopwatch_AAC
{
[Application]
public class MyApp : Application, ILifecycleObserver
{
const string TAG = "MyApp";
public MyApp(IntPtr handle, Android.Runtime.JniHandleOwnership ownerShip) : base(handle, ownerShip)
{
}
public override void OnCreate()
{
base.OnCreate();
ProcessLifecycleOwner.Get().Lifecycle.AddObserver(this);
}
[Lifecycle.Event.OnStop]
[Export]
public void Stopped()
{
Log.Debug(TAG, "App entered background state.");
}
[Lifecycle.Event.OnStart]
[Export]
public void Started()
{
Log.Debug(TAG, "App entered foreground state.");
}
}
}
As you can see, you annotate your lifecycle methods with for example [Lifecycle.Event.OnStop]. Also, please note that you need to use [Export]. Please make sure that Mono.Android.Export is referenced in your project as shown in the following screenshot.
If you want to have lifecycle observers for an activity, I suggest to extend AppCompatActivity as it is a lifecycle owner:
using Android.App;
using Android.Arch.Lifecycle;
using Android.OS;
using Android.Support.V7.App;
using Android.Util;
using Java.Interop;
namespace Stopwatch_AAC
{
[Activity(Label = "Minimal", Exported = true, MainLauncher = true)]
public class Minimal : AppCompatActivity, ILifecycleObserver
{
const string TAG = "Stopwatch_AAC";
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Lifecycle.AddObserver(this);
Log.Debug(TAG, Lifecycle.CurrentState.ToString());
}
[Lifecycle.Event.OnAny]
[Export]
public void Hello()
{
Log.Debug(TAG, Lifecycle.CurrentState.ToString());
}
}
}
if you need it in the activities here the events:
protected override void OnStart(){
base.OnStart();
Log.Debug(logTag, "MainActivity.OnStart() called, the activitiy is active");
}
protected override void OnPause()
{
base.OnPause();
Log.Debug(logTag, "MainActivity.OnPause() called, the activity in background");
}
protected override void OnStop()
{
base.OnStop();
Log.Debug(logTag, "MainActivity.OnStop() called, the activity is in background because of other activiy or app");
}
protected override void OnResume()
{
base.OnResume();
Log.Debug(logTag, "MainActivity.OnResume() called, the activity stated");
}
protected override void OnRestart()
{
base.OnRestart();
Log.Debug(logTag, "MainActivity.OnRestart() called, the activity is startet");
}
protected override void OnDestroy()
{
base.OnDestroy();
Log.Debug(logTag, "MainActivity.OnDestroy() called, activity is destroyed");
}
for Xamarin Forms you will find in app.xaml.cs the event which are needed for the apps.
protected override void OnStart ( ) {
// Handle when your app starts
}
protected override void OnSleep ( ) {
// Handle when your app sleeps
}
protected override void OnResume ( ) {
// Handle when your app resumes
}
I have used that package in the past, however I much prefer the implementation by James Montemagno which can be found as a nuget package called "Plugin.CurrentActivity". It creates an application class and implements the ILifecycle events for you.
From the description:
Provides a simple solution for getting access to the current Activity of the application when developing a Plugin for Xamarin.
This will lay down a base "application" class for developers in their Android application with boilerplate code to get them started.
Can be used with Android API 14+
* I am making the assumption that you're not using Xamarin.Forms. This works perfectly for a native Xamarin Android project.
Link to the Github page

Different app icon for each configuration

For my app I want to have two different versions (live and dev). The version will be build with a different build configuration.
What I want to achieve is to have a different app icon shown on the device depending on which version/build configuration I used.
I already have searched for solutions but only found some which advices to use different Manifests/csproj but I can't go with this approach.
So is there any other way to have different icons depending on the configuration?
Your best bet is to remove the icon config from the manifest and add it to your MainActivity.
It will look like this:
using Android.App;
using Android.Content.PM;
using Android.OS;
using Microsoft.Practices.Unity;
using Prism.Unity;
namespace BlankApp2.Droid
{
#if DEBUG
[Activity(Label = "Debug BlankApp2", Icon = "#drawable/debugIcon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
#else
[Activity(Label = "Prod BlankApp2", Icon = "#drawable/prodIcon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
#endif
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
LoadApplication(new App(new AndroidInitializer()));
}
}
public class AndroidInitializer : IPlatformInitializer
{
public void RegisterTypes(IUnityContainer container)
{
// Register any platform specific implementations
}
}
}

Several Xamarin.Forms Android activities

I want to use several Android activities. First is general application. Second is notification view. They have different activity settings and therefore I can't use one activity for this issue.
I try to do this:
[Activity(Label = "Life Manager", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : FormsApplicationActivity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
Forms.Init(this, bundle);
ActionBar.SetIcon(new ColorDrawable(Color.Transparent));
LoadApplication(new TimeManagerApplication());
Device.StartTimer(new TimeSpan(0, 0, 0, 5), OpenNotificationActivity);
}
private bool OpenNotificationActivity()
{
Intent intent = new Intent(this, typeof(NotificationActivity));
StartActivity(intent);
return false;
}
}
[Activity(Label = "NotificationActivity")]
public class NotificationActivity : FormsApplicationActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
RequestWindowFeature(WindowFeatures.NoTitle);
Window.AddFlags(WindowManagerFlags.Fullscreen | WindowManagerFlags.KeepScreenOn);
base.OnCreate(savedInstanceState);
Forms.Init(this, savedInstanceState);
LoadApplication(new NotificiationApplication());
}
}
In this line:
LoadApplication(new NotificiationApplication());
I take an error:
System.NullReferenceException: Object reference not set to an instance of an object.
How can I use two android activities in one application and use cross-platform Xamarin.Forms views for it?
Update:
Without these lines application perfectly works:
//RequestWindowFeature(WindowFeatures.NoTitle);
//Window.AddFlags(WindowManagerFlags.Fullscreen | WindowManagerFlags.KeepScreenOn);
But how can I hide status bar and use fullscreen view?
I decided this issue.
To take Fullscreen view without status bar is enough use only Window Flags
Window.AddFlags(WindowManagerFlags.Fullscreen | WindowManagerFlags.KeepScreenOn);
without:
RequestWindowFeature(WindowFeatures.NoTitle);
Application works as expected without exceptions.

Can't Make Caliburn.Micro Work With Windows Phone

I'm trying to understand how Caliburn.Micro works with Windows Phone (and MVVM in general) so I created a basic Windows Phone Application, installed Caliburn.Micro NuGet package (v1.2.0 - the latest for now) and followed the few instructions here and there. So, I ended up with:
WMAppManifest.xml
<DefaultTask Name ="_default" NavigationPage="Views/HomeView.xaml"/>
Framework/AppBootstrapper.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using Caliburn.Micro;
using MyCaliburn.PhoneUI.ViewModels;
namespace MyCaliburn.PhoneUI.Framework
{
public class AppBootstrapper : PhoneBootstrapper
{
PhoneContainer container;
protected override void Configure()
{
container = new PhoneContainer(RootFrame);
container.RegisterPhoneServices();
container.Singleton<HomeViewModel>();
}
protected override void OnUnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{
if (Debugger.IsAttached)
{
Debugger.Break();
e.Handled = true;
}
else
{
MessageBox.Show("An unexpected error occured, sorry about the troubles.", "Oops...", MessageBoxButton.OK);
e.Handled = true;
}
base.OnUnhandledException(sender, e);
}
protected override object GetInstance(Type service, string key)
{
return container.GetInstance(service, key);
}
protected override IEnumerable<object> GetAllInstances(Type service)
{
return container.GetAllInstances(service);
}
protected override void BuildUp(object instance)
{
container.BuildUp(instance);
}
}
}
ViewModels/HomeViewModel.cs
using Caliburn.Micro;
namespace MyCaliburn.PhoneUI.ViewModels
{
public class HomeViewModel : Screen
{
public HomeViewModel()
{
//DisplayName = "Home";
}
}
}
View/HomeView.xaml.cs (the XAML page is the default Window Phone Portrait Page)
using Microsoft.Phone.Controls;
namespace MyCaliburn.PhoneUI.Views
{
public partial class HomeView : PhoneApplicationPage
{
public HomeView()
{
InitializeComponent();
}
}
}
App.xaml
<Application
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="MyCaliburn.PhoneUI.App"
xmlns:Framework="clr-namespace:MyCaliburn.PhoneUI.Framework">
<!--Application Resources-->
<Application.Resources>
<Framework:AppBootstrapper x:Key="bootstrapper" />
</Application.Resources>
</Application>
App.xaml.cs
using System.Windows;
namespace MyCaliburn.PhoneUI
{
public partial class App : Application
{
/// <summary>
/// Constructor for the Application object.
/// </summary>
public App()
{
// Standard Silverlight initialization
InitializeComponent();
}
}
}
Now, when I hit F5, the application runs and exits without showing any page or exception and doesn't hit any breakpoints that I sit.
Can anyone tells me what's missing in my code which prevents the application from running?
Thanks in advance.
Many times when I end up with an app that does not start - it turns out that due to some refactoring the App class is not the startup object any more. Right-click on the project in solution explorer, go to properties/Application and make sure Startup object is set correctly.

Resources