I guess I have a memory leak because after I open a specific Dialog and change to a new Activity, the app crashes without any warning and Visual Studio/App stops without any warning or specific line where it happens as you can see in the animated gif:
This second animated gif is where I'm debugging the app in Visual Studio and then suddenly stops. The app finished in line that doesn't make sense base.OnDrawerSlide(drawerView, slideOffset):
Now, the Dialog, is quite heavy because it does some mathematical calculations in real-time:
Dialog:
private void BtnCompareAll_Click(object sender, EventArgs e)
{
GravityPlanets gInfo = new();
View dialogView = LayoutInflater.Inflate(Resource.Layout.CompareAll, null);
var Dialog = new Android.App.AlertDialog.Builder(Context);
int firstCelestialLoc = GetItemPosition(planets, SpinnerFirstCelestial.Text);
var gravity = new Supernova.Core.Gravity();
var listView = dialogView.FindViewById<ListView>(Resource.Id.lstCelestialObjects);
var textObject1 = dialogView.FindViewById<TextView>(Resource.Id.textObject1);
var imgView = dialogView.FindViewById<ImageView>(Resource.Id.imgCObject);
var yourWeight = dialogView.FindViewById<TextView>(Resource.Id.yourWeight);
imgView.SetImageDrawable(compareAllList[firstCelestialLoc].image);
textObject1.Text = SpinnerGravityUnits.Text == gUnits[0]
? $"{planets[firstCelestialLoc]}, {GetCelestialObject(gInfo.CelestialObjectType(firstCelestialLoc))}, {gInfo.GetGravity(firstCelestialLoc)} {SpinnerGravityUnits.Text}"
: $"{planets[firstCelestialLoc]}, {GetCelestialObject(gInfo.CelestialObjectType(firstCelestialLoc))}, {Math.Round(gravity.ChangeToFeet(gInfo.GetGravity(firstCelestialLoc)), 3)} {SpinnerGravityUnits.Text}";
List<DrawerData> currentObjects = compareAllList.DeepClone();
currentObjects.RemoveAt(firstCelestialLoc);
bool isNumeric = double.TryParse(TxtWeight.Text, out double earthWeight);
if (isNumeric && earthWeight > 0)
{
yourWeight.Visibility = ViewStates.Visible;
yourWeight.Text = $"{GetString(Resource.String.lblYourWeight)} {TxtWeight.Text}{SpinnerWeightUnits.Text}";
}
else
{
yourWeight.Visibility = ViewStates.Gone;
yourWeight.Text = "";
}
GravityPlanets gPlanets = new();
for (int i = 0; i < currentObjects.Count(); i++)
{
var secondG = GetItemPosition(planets, currentObjects[i].name);
var gPercentage = Math.Round(gInfo.PercentageGravity(firstCelestialLoc, secondG), 0);
switch (gInfo.ComparedGravity(firstCelestialLoc, secondG))
{
case 0:
gravType = GetString(Resource.String.gravLower);
currentObjects[i].color = "#43A047";
break;
default:
gravType = GetString(Resource.String.gravGreater);
currentObjects[i].color = "#F44336";
break;
}
var gravVal = SpinnerGravityUnits.Text == gUnits[0] ? gInfo.GetGravity(secondG) : Math.Round(gravity.ChangeToFeet(gInfo.GetGravity(secondG)), 3);
currentObjects[i].name = $"<b>{currentObjects[i].name}, {GetCelestialObject(gInfo.CelestialObjectType(secondG))}</b><br>{gravVal} {SpinnerGravityUnits.Text}, {string.Format(gravType, gPercentage)}";
if (isNumeric && earthWeight > 0)
{
currentObjects[i].name += $"<br>{GetString(Resource.String.lblYourWeightCO)} {GetNewWeight(gPlanets, double.Parse(TxtWeight.Text), firstCelestialLoc, secondG)} {SpinnerWeightUnits.Text}";
}
var adapter = new CompareAllAdapter(currentObjects);
listView.Adapter = adapter;
Dialog.SetView(dialogView);
Dialog.SetOnDismissListener(new OnDismissListener());
Dialog.Show();
}
}
And I use this class to "dispose" of the dialog:
Dismiss class:
private class OnDismissListener : Java.Lang.Object, IDialogInterfaceOnDismissListener
{
public void OnDismiss(IDialogInterface dialog)
{
dialog.Dispose();
}
}
Oddly, it seems it wasn't properly disposed of because I can open other dialogs and nothing happens, this is the only one that causes this abnormal behavior.
Additionally, I tried to remove its reference by making the dialog's value null while making it a property and failed. I also tried to use the garbage collector and also failed because it crashed the app.
I even tried avoiding to store any history using this in the MainActivity class:
[Android.App.Activity(Label = "Gravity Now!", MainLauncher = true, Icon = "#drawable/ic_icon", NoHistory = true)]
I even created an additional OnCancelListener where I'm even disposing of the DialogView without any result:
Dialog.SetOnCancelListener(new OnCancelListener(dialogView));
private class OnCancelListener : Java.Lang.Object, IDialogInterfaceOnCancelListener
{
private View dialogView;
public OnCancelListener(View dialogView)
{
this.dialogView = dialogView;
}
public void OnCancel(IDialogInterface dialog)
{
dialogView.Dispose();
dialogView = null;
dialog.Dispose();
dialog = null;
}
}
For more info, here is the full source code:
https://bitbucket.org/supernovaic/gnow-android/src/master/
Also, I got this crash file, but I cannot find anything useful:
https://drive.google.com/file/d/10-wmY337mG_k6ZoS7GAcFI1reR6eqQRy/view?usp=sharing
These are the last lines:
09-11 18:19:26.889 28140 31014 I ActivityManager: Force stopping
tk.supernova.gnow appid=10156 user=0: from pid 13171 09-11
18:19:26.892 28785 28785 I AppBase : AppBase.onTrimMemory():615
onTrimMemory(): 5 09-11 18:19:26.894 13171 13174 I cmd : oneway
function results will be dropped but finished with status OK and
parcel size 4 09-11 18:19:26.935 28785 28785 I
GoogleInputMethodService: GoogleInputMethodService.onTrimMemory():4225
onTrimMemory(): 5 09-11 18:19:26.951 28140 28158 W ActivityManager:
setHasOverlayUi called on unknown pid: 12844 09-11 18:19:26.953 28140
28158 W ActivityTaskManager: Activity top resumed state loss timeout
for ActivityRecord{3c51759 u0
tk.supernova.gnow/crc64c3564668e399e885.Help t-1 f}}
At this point, I don't know what else to do. Any idea what I'm doing wrong?
P.S.:
I have tested it on physical devices also (Oppo A91 and Nexus 7 - 2013).
Here is the link if you want to test the error in your physical device: https://play.google.com/store/apps/details?id=tk.supernova.gnow
Update:
I got this answer from another forum:
LeonLu-MSFT
In the
DefinitionFragment.cs file on line 36 in the LoadGif() function, you
could try to use the GetBuffer() method in-place of the ToArray()
method.
Please refer to this document for further explanations:
MemoryStream.ToArray Method (System.IO) | Microsoft Docs
Now, it loads the help but crashes without a reason again between tabs. By the way, I changed to GetBuffer() in both tabs.
I found that the bug was here:
List<DrawerData> currentObjects = compareAllList.DeepClone();
I had to change the logic and create the temp data in a different way:
private List<DrawerData> GetPlanetsData()
{
return new List<DrawerData>()
{
new DrawerData() {
name = GetString(Resource.String.itemSun),
image = GetCelestialObjectDrawable(Resource.Drawable.sun),
url = GetString(Resource.String.itemWikiSun)
},
new DrawerData() {
name = GetString(Resource.String.itemMercury),
image = GetCelestialObjectDrawable(Resource.Drawable.mercury),
url = GetString(Resource.String.itemWikiMercury)
},
new DrawerData() {
name = GetString(Resource.String.itemVenus),
image = GetCelestialObjectDrawable(Resource.Drawable.venus),
url = GetString(Resource.String.itemWikiVenus)
}
//...
};
}
List<DrawerData> currentObjects = GetPlanetsData();
It seems somehow the Deep Cloner data created cannot be removed somehow.
When I hardcode the images (no for loop) the game works perfectly. I tested the for loop on an array of numbers and it worked perfectly. When I add the images, including the image variables, the app crashes, even though Android Studio says the app installed successfully. What am I missing here? I have the ArrayList for frontImage as well. Thank you.
private void cardFront() {
for (int i = 0; i < 9; i++) {
int random = (int) (Math.random() * (drivers.length));
if (!frontImage.contains(drivers[random])) {
frontImage.add(drivers[random]);
frontImage.add(drivers[random]);
} else {
i--;
}
image11 = frontImage.get(1);
image12 = frontImage.get(2);
image13 = frontImage.get(3);
image14 = frontImage.get(4);
image15 = frontImage.get(5);
image16 = frontImage.get(6);
image17 = frontImage.get(7);
image18 = frontImage.get(8);
image19 = frontImage.get(9);
image21 = frontImage.get(10);
image22 = frontImage.get(11);
image23 = frontImage.get(12);
image24 = frontImage.get(13);
image25 = frontImage.get(14);
image26 = frontImage.get(15);
image27 = frontImage.get(16);
image28 = frontImage.get(17);
image29 = frontImage.get(18);
}
}
Both iOS and Android are using the same Xamarin code. Works fine on Android but not on iOS.
List<string> la_liste_de_liens contains URLs to podcasts such as www.something.com/podcast1.mp3, www.something.com/podcast2.mp3 and www.something.com/podcast3.mp3.
When I click the first item (item 0 from list) it plays well.
When I click the second item (item 1 from list) it would not play at all.
var les_liens = new List<string>();
string[] num1 = ((IEnumerable)some_podcast).Cast<object>()
.Select(x => x.ToString())
.ToArray();
var le_programme = Preferences.Get("prog", "default_value");
Le_prog.Text = le_programme;
Titre_episode.Text = num1[0];
List<string> la_liste_de_liens = Preferences.Get("haha",
"default_value1").Split(',').ToList();
var le_rang = Preferences.Get("rank", "default_value");
var url = la_liste_de_liens[int.Parse(le_rang)].ToString();
Console.Out.WriteLine(la_liste_de_liens);
Preferences.Set("le_url", url);
List<string> la_liste_de_durees = Preferences.Get("durdur",
"default_value2").Split(',').ToList();
var la_longueur = la_liste_de_durees[int.Parse(le_rang)].ToString();
Preferences.Set("longueur", la_longueur);
pause.ImageSource = "bouton_pause_bleu";
//low.ImageSource = "bouton_low_bleu";
//high.ImageSource = "bouton_high_bleu";
}
private void play_pod(object sender, System.EventArgs e)
{
//CrossMediaManager.Current.Volume.CurrentVolume = 30;
pause.ImageSource = "bouton_pause_bleu";
play.ImageSource = "bouton_play_vert";
stop.ImageSource = "bouton_stop_bleu";
//low.ImageSource = "bouton_low_bleu";
//high.ImageSource = "bouton_high_bleu";
var le_link = Preferences.Get("le_url", "default_value");
CrossMediaManager.Current.Play(le_link);
var le_temps = Preferences.Get("longueur", "default_value");
}
I could not figure out why. Could anyone provide some insight on this?
Here says the Web audio API works in Chrome for Android, and here I have tested CM Browser, Chrome and CyanogenMod default Android 5.1.1 browsers, and all pass the tests (specially the biquadNode one).
But When I open this codepen with an eq (biquadNode), I can hear the music but not the eq working.
Does biquadNode works in android? any special implementation is needed?
*Code pen required to post
var context = new AudioContext();
var mediaElement = document.getElementById('player');
var sourceNode = context.createMediaElementSource(mediaElement);
// EQ Properties
//
var gainDb = -40.0;
var bandSplit = [360,3600];
var hBand = context.createBiquadFilter();
hBand.type = "lowshelf";
hBand.frequency.value = bandSplit[0];
hBand.gain.value = gainDb;
var hInvert = context.createGain();
hInvert.gain.value = -1.0;
var mBand = context.createGain();
var lBand = context.createBiquadFilter();
lBand.type = "highshelf";
lBand.frequency.value = bandSplit[1];
lBand.gain.value = gainDb;
var lInvert = context.createGain();
lInvert.gain.value = -1.0;
sourceNode.connect(lBand);
sourceNode.connect(mBand);
sourceNode.connect(hBand);
hBand.connect(hInvert);
lBand.connect(lInvert);
hInvert.connect(mBand);
lInvert.connect(mBand);
var lGain = context.createGain();
var mGain = context.createGain();
var hGain = context.createGain();
lBand.connect(lGain);
mBand.connect(mGain);
hBand.connect(hGain);
var sum = context.createGain();
lGain.connect(sum);
mGain.connect(sum);
hGain.connect(sum);
sum.connect(context.destination);
// Input
//
function changeGain(string,type)
{
var value = parseFloat(string) / 100.0;
switch(type)
{
case 'lowGain': lGain.gain.value = value; break;
case 'midGain': mGain.gain.value = value; break;
case 'highGain': hGain.gain.value = value; break;
}
}
createMediaElementSource in Chrome on Android doesn't work in general. But if you have a recent build of Chrome (49 and later?), you can go to chrome://flags and enable the unified media pipeline option. That will make createMediaElementSource work like on desktop.
i build a application that record sound in Desktop using ActionScript 3 , now i convert the application to Andriod Application but there is a problem that SampleDataEvent.SAMPLE_DATA event doesn't receive any data to record
Here is the code :
private var _microphone:Microphone;
private var _buffer:ByteArray = new ByteArray();
private var _difference:uint;
public function record():void
{
if ( _microphone == null )
_microphone = Microphone.getMicrophone();
_difference = getTimer();
_microphone.setSilenceLevel(_silenceLevel, _timeOut);
_microphone.gain = _gain;
_microphone.rate = _rate;
_buffer.length = 0;
_microphone.addEventListener(SampleDataEvent.SAMPLE_DATA, onSampleData);
_microphone.addEventListener(StatusEvent.STATUS, onStatus);
}
private function onSampleData(event:SampleDataEvent):void
{
_recordingEvent.time = getTimer() - _difference;
dispatchEvent( _recordingEvent );
var buteData:Number;
while(event.data.bytesAvailable > 0)
{
buteData = event.data.readFloat();
_buffer.writeFloat(buteData);
soundBytes.writeFloat( buteData);
}
}
anyone can help here
Thanx
I think, maybe you don't check out about AIR for Android settings. If you not checked in the RECORD_AUDIO. you should check it.
refer a below image.