Xamarin Forms Microcharts generating "OutOfMemoryError" - xamarin

I am trying to use a Microcharts graph in my application, which is using Xamarin.Forms (targeting Android, iOS and UWP).
I have tried following several tutorials to get a chart to display but each time it results in the error:
Unhandled Exception:
Java.Lang.OutOfMemoryError: Failed to allocate a 240048012 byte allocation with 5713730 free bytes and 87MB until OOM
If I make a new Xamarin.Forms project, this error doesn't occur and it runs absolutely fine (I am running on the same Android device, a Samsung SM-J320FN).
Here is the simplified XAML code:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Foo.DetailPage" xmlns:forms="clr-namespace:Microcharts.Forms;assembly=Microcharts.Forms">
<ContentPage.Content>
<StackLayout Grid.Row="2">
<forms:ChartView x:Name="priceChart" HeightRequest="150"/>
</StackLayout>
Here is the Code Behind:
//Temp data for charts
List<Entry> entries = new List<Entry>
{
new Entry(200)
{
Color=SKColor.Parse("#FF1943"),
Label ="January",
ValueLabel = "200"
},
new Entry(400)
{
Color = SKColor.Parse("00BFFF"),
Label = "March",
ValueLabel = "400"
},
new Entry(-100)
{
Color = SKColor.Parse("#00CED1"),
Label = "Octobar",
ValueLabel = "-100"
},
};
public DetailPage(string Code)
{
((NavigationPage)Application.Current.MainPage).BarBackgroundColor = Color.FromHex("27b286");
InitializeComponent();
priceChart.Chart = new LineChart() { Entries = entries, BackgroundColor = SKColor.Parse("#00FFFFFF") };
}
Without this chart, the page can run absolutely fine, even when the list is generated and the chart is included in XAML, it seems to be when initialising the chart through the code behind that causes the issue.

I added <application android:hardwareAccelerated="true" android:largeHeap="true"></application> to my AndroidManifest.xml and this works fine, however I still don't know what was causing so much memory to be used.

Related

After installing FFImageLoading images don't show at all

My Xamarin Forms 5 app will allow users to upload their own images which can be large. I noticed that large images were taking a long time to show so I installed FFImageLoading and followed the instructions on their Github page at https://github.com/luberda-molinet/FFImageLoading/wiki/Xamarin.Forms-API.
Specifically, I installed the following packages:
Xamarin.FFImageLoading Version="2.4.11.982"
Xamarin.FFImageLoading.Forms Version="2.4.11.982"
Xamarin.FFImageLoading.Svg.Forms Version="2.4.11.982"
Xamarin.FFImageLoading.Transformations Version="2.4.11.982"
I also initialized it as follows:
Under Android, in OnCreate method of MainActivity.cs, I added FFImageLoading.Forms.Platform.CachedImageRenderer.Init(enableFastRenderer:true); AND FFImageLoading.Forms.Platform.CachedImageRenderer.InitImageViewHandler();
Under iOS, in FinishedLaunching() method of AppDelegate.cs, I added FFImageLoading.Forms.Platform.CachedImageRenderer.Init(); AND FFImageLoading.Forms.Platform.CachedImageRenderer.InitImageSourceHandler();
I first tried it without changing anything in my XAML files, meaning I used the regular Image control and images would NOT show at all.
I then tried the following and I see NOTHING at all:
...
xmlns:ffil="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
...
<ffil:CachedImage
Source="{Binding FileUrl}"
DownsampleWidth="150"
DownsampleToViewSize="True"/>
IMPORTANT:
I also want to mention that the images are displayed within CollectionView controls AND in all cases, their source is a URL and NOT a local path.
Any idea what maybe the issue here and how to fix it?
As I'm aware FFImageLoading is not maintained anymore. A lot of apps are still using the package but keep in mind that reported open issues will most likely not be fixed. It is sad because this is one of the most popular packages for Xamarin Forms, but it looks like we will have to start looking for alternatives.
Good luck with this.
I checked your steps that you followed the instructions.Obviously,your steps are correct and I manage to display the image{using URL} with CollectionView as you said,hope it can give you some insights.
Model:
MyModel.cs
public class MyModel
{
public int id { get; set; }
public string FileUrl { get; set; }
}
View:
MainPage.xaml
<CollectionView ItemsSource="{Binding MyModels}">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="2" />
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<ContentView Padding="0">
<ffil:CachedImage
Source="{Binding FileUrl}"
DownsampleWidth="150"
DownsampleToViewSize="True"/>
</ContentView>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
Bind the ViewModel in backend:
BindingContext = new MainPageViewModel();
ViewModel:
MainPageViewModel.cs
public class MainPageViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private ObservableCollection<MyModel> myModels;
public ObservableCollection<MyModel> MyModels
{
get { return myModels; }
set { myModels = value; }
}
public MainPageViewModel()
{
MyModels = new ObservableCollection<MyModel>
{
new MyModel{id = 1, FileUrl = "http://loremflickr.com/600/600/nature?filename=simple.jpg"},
new MyModel{id = 2, FileUrl ="http://loremflickr.com/600/600/nature?filename=simple.jpg"},
new MyModel{id = 3, FileUrl = "http://loremflickr.com/600/600/nature?filename=simple.jpg"},
new MyModel{id = 4, FileUrl ="http://loremflickr.com/600/600/nature?filename=simple.jpg"},
new MyModel{id = 5, FileUrl = "http://loremflickr.com/600/600/nature?filename=simple.jpg"},
new MyModel{id = 6, FileUrl ="http://loremflickr.com/600/600/nature?filename=simple.jpg"}
};
}
}
Update:
In Android, it works well.However,in iOS there's already a reported issue:
github.com/luberda-molinet/FFImageLoading/issues/1498

Xamarin GIF animation

I just started developing Xamarin
But I encountered a problem
I have a login screen and I want to play gif there
but unfortunately no images are coming
Works well for png and jpeg files
my code is below;
Content = new StackLayout
{
Padding = new Thickness(10, 40, 10, 10),
Children = {
new Label { Text = "Versiyon:"+DependencyService.Get<INativeCall>().getApplicationVersion(), FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)), TextColor = Color.White, HorizontalTextAlignment=TextAlignment.Center },
new Image { Source = "a.gif" },
username,
password,
btnLogin,
indicator,
infoServer,
infoUpdate
}
};
By default, when an animated GIF is loaded it will not be played. This is because the IsAnimationPlaying property, that controls whether an animated GIF is playing or stopped, has a default value of false. This property, of type bool, is backed by a BindableProperty object, which means that it can be the target of a data binding, and styled.
Therefore, when an animated GIF is loaded it will not be played until the IsAnimationPlaying property is set to true.
Modify code of Image as bellow :
new Image { Source = "a.jpg", IsAnimationPlaying = true}
For example , this is my gif file :
Xaml code :
<Label Text="Welcome to Xamarin.Forms!" HorizontalOptions="Center" VerticalOptions="Start" />
<Image Source="timg.gif" IsAnimationPlaying="True"/>
The effect :
Please use the nuget package - Xamarin.FFImageLoading.It processes GIFs quickly.
eg XAML -
<ffimageloading:SvgCachedImage Grid.Row="3" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" Source="celebrate.gif" />

After Creating Package in Xamarin UWP, Video is Playing Only With Voice, I am Not able to see Video

I am using MediaManager Plugin with latest version to play a video. everything works fine when i run application in debug mode, but when i create a package for window, video is not showing only voice is heard.
I am using below Package
Plugin.MediaManager.Forms
This is My XAML page
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="Digi_Sign.Views.MediaScreen"
xmlns:forms="clr-namespace:MediaManager.Forms;assembly=MediaManager.Forms"
BackgroundColor="Black">
<ContentPage.Content>
<Grid x:Name="stkLayout" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand" BackgroundColor="Black">
<forms:VideoView VideoAspect="AspectFill" x:Name="videoPlayer" ShowControls="False" />
</Grid>
</ContentPage.Content>
</ContentPage>
CS Page
CrossMediaManager.Current.Play(fileName);
No Errors Found in package error log, as i mentioned everything works fine when it is debug mode, but not working in release mode
Basically there is no way to initialize renderer for video in native code for xamrin.UWP, so we need to manually load render assembly in initialize it in App.xaml.cs of UWP platform
Below is my code where i have load assembly files inside OnLaunched() and replace existing Xamarin.Forms.Forms.Init()
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
Windows.UI.Xaml.Controls.Frame rootFrame = Window.Current.Content as Windows.UI.Xaml.Controls.Frame;
if (rootFrame == null)
{
rootFrame = new Windows.UI.Xaml.Controls.Frame();
rootFrame.NavigationFailed += OnNavigationFailed;
List<Assembly> assembliesToAdd = new List<Assembly>();
assembliesToAdd.Add(typeof(VideoViewRenderer).GetTypeInfo().Assembly);
Xamarin.Forms.Forms.Init(e, assembliesToAdd);
// Place the frame in the current Window
Window.Current.Content = rootFrame;
}
if (rootFrame.Content == null)
{
rootFrame.Navigate(typeof(MainPage), e.Arguments);
}
Window.Current.Activate();
}
for more details, here is the link. where you can find more explaination.
https://forums.xamarin.com/discussion/119451/crossmedia-works-in-debug-but-not-in-release-for-uwp-error-msg-about-onecore
Most likely from the behavior you are describing (and looking at your code), it sounds like it's because the Video is not being run on the UI thread, and this causes the app to play the audio but not the video. So change it to the following:
Device.BeginInvokeOnMainThread(() => { CrossMediaManager.Current.Play(fileName); });

Xamarin forms background image not working

I am working on Xamarin forms, cross platform app (Android and iOS). I wanted to have background image for login form.
I set it on constructor of form and code is :
this.BackgroundImage = ImageSource.FromResource("PCLProjectName.Images.Login.loginbackground.png").ToString();
And Image is in PCL project and I have set its action property as Embedded resource.
PCL project folder hierarchy as as below
Root
- Images
- Login
-loginbackground.png
Image is not displaying
If you want to add background image in XAML file for the entire page in Xamarin project, then use the BackgroundImage property and add your image to the Android project under Resources -> drawable folder and for iOS Resources folder.
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:PhoneDailerDemo"
x:Class="PhoneDailerDemo.MainPage"
BackgroundImage="image3.jpg">
<Label Text="Welcome to Xamarin Forms!"
VerticalOptions="Center"
HorizontalOptions="Center" />
<StackLayout Padding="100">
//..........
</StackLayout>
</ContentPage>
For images to work, they must be placed in different folders in iOS and android. Subfolders or custom file structures cannot be used to my knowledge.
For Android devices, images must be in the Android project under Android>Resources>Drawable. Build action set to Android Resource (this folder should already exist)
For iOS devices, images must be in the iOS project folder iOS>Resources. Build Action set to Bundle Resource (This folder should also already exist)
With the images in the respective folders, you can set the image like so..
this.BackgroundImage = ImageSource.FromFile("loginbackground.png")
edit: To continue with your PCL Embedded Resource approach..
You can run this piece of code somewhere to see that the images are detected correctly in the resources. I know from experience there are some weird file naming issues (though I don't see any I've encountered in your example)
var assembly = typeof(EmbeddedImages).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
System.Diagnostics.Debug.WriteLine("found resource: " + res);
Xamarin does not allow you to use an image from external storage or Url as background image of ContentPage.
so instead of setting a BackgroundImage ="image_name_in_resources" inside the root tag of page ( ContentPage ) , put it in an Image tag neighboring you inside code , both inside an AbsoluteLayout
here's a snippet of my Code
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
.....
.....>
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Image x:Name="imageBG" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" Aspect="AspectFill" Source="myimage.jpg" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"/>
<StackLayout AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All" >
....
</StackLayout>
</AbsoluteLayout>
to change the source prof CS code here's a little snippet i worked with
string serverAdress = Constants.HTTP_PRE + Constants.SERVER_IP;
Logo.Source = new UriImageSource
{
Uri = new Uri(serverAdress + Constants.HEADER_IMAGE),
CachingEnabled = true
};
For more controle over whether the server response is valid ...
try
{
string url = Constants.HTTP_PRE + DependencyService.Get<IStoredData>().GetData(Constants.SHARED_PREF_ADDRESS);
url += Constants.HEADER_IMAGE;
HttpWebRequest wrq = (HttpWebRequest)WebRequest.Create(url);
//You should be getting only the response header
wrq.Method = "HEAD";
if ( ( (HttpWebResponse)wrq.GetResponse() ).ContentLength > 0) // if filePath is correct - serverIP is set
{
Uri uri = new Uri(url);
UriImageSource uriImageSource = new UriImageSource { Uri = uri, CachingEnabled = true };
Logo.Source = uriImageSource;
}
}catch (Exception e) { System.Console.WriteLine(e.StackTrace); }

Centering Layout With Padding - rounding error

Nested layouts in xamarin seem to be biased to the left of the screen. I'm assuming this is a dp to pixel rounding bias or something?
Can anyone confirm, is there a work around or solution?
Although my example uses Absolute layout the problem seems to be on all layouts.
using System;
using Xamarin.Forms;
namespace XamarinTest
{
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
AbsoluteLayout child = layout;
AbsoluteLayout.SetLayoutFlags(child, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(child, new Rectangle(0, 0, 1, 1));
Random rand = new Random();
for (int i =0;i<100; i++)
{
child = addLayout(child, rand) ;
}
AbsoluteLayout abs = new AbsoluteLayout();
AbsoluteLayout.SetLayoutFlags(abs, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(abs, new Rectangle(0, 0, 0.5, 0.5));
abs.BackgroundColor = Color.Black;
layout.Children.Add(abs);
}
private AbsoluteLayout addLayout(AbsoluteLayout parent, Random rand)
{
AbsoluteLayout abs = new AbsoluteLayout();
AbsoluteLayout.SetLayoutFlags(abs, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(abs, new Rectangle(0,0,1,1));
abs.Padding = new Thickness(2.0);
abs.BackgroundColor = new Color(rand.NextDouble(), rand.NextDouble(), rand.NextDouble());
parent.Children.Add(abs);
return abs;
}
}
}
XAML
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="XamarinTest.Page1">
<AbsoluteLayout BackgroundColor="White" x:Name="layout">
</AbsoluteLayout>
</ContentPage>
Screen shot (if it uploads):
I think you are seeing differences in the emulator's rendering vs. an issue with the Forms code running on Android as the DPI of the simulate screen can throw offsets into the mix. ​
iOS Simulator does a great job at rendering at a 1:1 based upon the actual devices' DPI and then down-sampling the display based upon your view settings and your code will always render those StackLayout at the requested position.
If you look at the your code running on two (OS-X-based) emulators using a DPI that divides "cleanly" to the pixels on the physical screen of the emulator:
Versus one that does not:
If you have the paid-version of GenyMotion's emulator, there is a one-2-one scaling option that provides a similar experience as the iOS simulator.
Moral of the story, use physical devices for final checks of your layouts. A great way is to use Xamarin's Test Cloud and add a screenshot capture to each of your app's Form pages

Resources