NativeScript / nativescript-angular

Integrating NativeScript with Angular
http://docs.nativescript.org/angular/tutorial/ng-chapter-0
Apache License 2.0
1.21k stars 241 forks source link

app freezing for 5 seconds withe nativescript-photo-editor #1726

Open Serge-SDL opened 5 years ago

Serge-SDL commented 5 years ago

Environment Provide version numbers for the following components (information can be retrieved by running tns info in your project folder or by inspecting the package.json of the project):

Describe the bug Hello, I have got a strange behavior using nativescript-photo-editor plugin. I post here because I don't think it's related to the plugin : same exact code woks fine on pure nativescript (without angular). When I edit a phot with PhotoEditor and cancel (or save or whatever), the app is like feezing for 5 seconds. I tryed to add timers to see if it was the actual behavior -> and il looks like 1 second setTimeOut take 5 seconds to be executed (same time as freezing feeling on app). When I execute de code I got this logs:

To Reproduce

<ActionBar class="action-bar">
    <Label class="action-bar-title" text="Home"></Label>
</ActionBar>

<StackLayout>
    <Image src="~/app/test-image.jpg" stretch="aspectFit"></Image>
    <Button (tap)="editImage()" text="Lauch"></Button>
</StackLayout>

Do anyone have an idea ? thanks

Serge-SDL commented 5 years ago

Hey! I also tried several things with zone run(), runOutsideAngular() ... but it didn't work. and tried to use workers but I think it's not possible to launch/manage UI from worker...

NickIliev commented 5 years ago

@Serge-SDL it feels like a plugin related issue but still, I've tested the described scenario with latest Angular and everything works as expected on my side. Check this test app for reference and let me know if there are changes that can be made to reproduce the issue.

Serge-SDL commented 5 years ago

Hey @NickIliev , thank you for your answer! I have downloaded and tried your code and I still have the problem :( To reproduce, juste change your editPhoto() method to

    editPhoto() {
        this.photoEditor.editPhoto({
            imageSource: this.originalImage,
            hiddenControls: [
                PhotoEditorControl.Text,
                PhotoEditorControl.Crop,
            ],
        }).then((newImage: ImageSource) => {
            this.imageSrc = newImage;
            var time = (new Date()).getTime();
            setTimeout(() => { console.log('setTimeout 1000 after ' + ((new Date()).getTime() - time) + 'ms'); }, 1000);
        }).catch((e) => {
            console.error(e);
            var time = (new Date()).getTime();
            setTimeout(() => { console.log('setTimeout 1000 after ' + ((new Date()).getTime() - time) + 'ms'); }, 1000);
        });
    }

and run on real device (it works corectly on emulator). I tried your code with this change on 2 devices (action: cancel photo edition, but its the same if I save the image):

Its like the app is freezing 100ms after the answer (then or catch) for 3 to 5 seconds. I tried to change page just after the answer (then or catch) -> it works, the navigation appends, but the feezing occurs on the new page!

I tried to run the code outside angular (this._zone.runOutsideAngular) because it works well on vanilla nativescript, but it does'nt change anything...

NickIliev commented 5 years ago

@Serge-SDL what you are experiencing here is something specific to setTImeout in Nodejs environment. See the related documentation article and specifically the following section:

The callback will likely not be invoked in precisely delay milliseconds. 
Node.js makes no guarantees about the exact timing of when callbacks will fire, nor of their ordering. 
The callback will be called as close as possible to the time specified.
Serge-SDL commented 5 years ago

@NickIliev Thanks angain for your answer! I think this is not the problem here: I use setTimeout() only to have an objectiv representation of the freezing, but the real issue can be reproduced this way:

<GridLayout rows="100, 100, *" columns="*" class="page">
    <Button row="0" text="editPhoto" (tap)="editPhoto()"></Button>
    <TextField row="1"></TextField>
    <Image row="2" (loaded)="onImageLoaded($event)" [src]="imageSrc"></Image>
</GridLayout>
NickIliev commented 5 years ago

@Serge-SDL it still feels like the plugin takes its time to create a new ImageSource for editing purposes (even when you press cancel with opened plugin). Can you try to isolate the case in a sample app and share with us the source?

Serge-SDL commented 5 years ago

@NickIliev, not sure to underestand your need: I can create an app that show the issue, is that it (what do you mean by isolate the case) ? By the way I don't know if it's the ImageSource part that cause the freezing because withe the same process, not problem on vanilla Nativescript...

NickIliev commented 5 years ago

@Serge-SDL I've created a simple test app with Angular and was able to reproduce the delay on real device (used Pixel for test) but also I've done the same test with the nativescript-camera plugin (which also opens the camera activity and then returns an asset in its promise) and there was no delay at all.

After some tests, it seems that the issue is happening only when the intent is passing the photo editor class (the freeze won't happen if you pass, for example, the camera intent).

I am not finding the native library that stands behind the com.tangrainc.photoeditor so I can't really say what is causing this one.

PeterStaev commented 5 years ago

Hey @NickIliev , you can find the native source here.

But again since this happens only in Angular NS, I do not think the problem is in the native source itself.

Serge-SDL commented 5 years ago

Hey @NickIliev and @PeterStaev, I tried to remove all the logic from native an plugin part:

-> and I still have the same issue ! I can put sources online if needded... I agree with @PeterStaev , it looks to have nothing to do with the native part or the plugin part, only with using it with angular NS.

the java code:

package com.tangrainc.photoeditor;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;

public class PhotoEditorActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("PhotoEditorLog", "onCreate");
    }
}

the activity xml code:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    android:background="#000000"
    tools:context="com.tangrainc.photoeditor.PhotoEditorActivity">
</RelativeLayout>

the plugin js code:

import * as application from "application";
import { ImageSource } from "image-source";
import { EditPhotoOptions, PhotoEditor as PhotoEditorBase } from ".";

declare const com: any;

export class PhotoEditor implements PhotoEditorBase {
    private static readonly EDIT_PHOTO_REQUEST = 9090;

    public editPhoto(options: EditPhotoOptions) {
        options.hiddenControls = options.hiddenControls || [];

        return new Promise<ImageSource>((resolve, reject) => {         
            const intent = new android.content.Intent(application.android.foregroundActivity, com.tangrainc.photoeditor.PhotoEditorActivity.class);
            application.android.foregroundActivity.startActivityForResult(intent, PhotoEditor.EDIT_PHOTO_REQUEST);    
        });
    }
}
Serge-SDL commented 5 years ago

@NickIliev I can work on this issue but I don't know where to start... -> doesn't look like it's native code related -> doesn't looks like it's plugin or NS related (as it works fine on vanilla js ns) => should be ns-angular related! but how can I try to debug this ? the nativescript-angular layer is not really easy to understand, I tried to put logs on zonjs but it looks like nothing appends on this side during this 5 seconds... -> I'm a bit lost and I really need this plugin on my app :(

Serge-SDL commented 5 years ago

Hello @NickIliev and @PeterStaev!

some news about the issue:

I and my team work on our project for about 2 years and this is the main issue for us, with no workaround yet. Waiting 5s for nothing is not an acceptable option for my clients... I can spend some time on this (already spends days), but I need help .. Iit looks like the problem is deep in nativescript-agular.

thanks for your help!

Serge-SDL commented 5 years ago

Hello @NickIliev and @PeterStaev!

I have found the issue: the feezing is due to a garbage collector call on tns-core-module/application/application.android.js line 225 in function onActivityDestroyed -> if I comment the gc(); part it works fine!

        onActivityDestroyed: profiling_1.profile("onActivityDestroyed", function (activity) {
            if (activity === androidApp.foregroundActivity) {
                androidApp.foregroundActivity = undefined;
            }
            if (activity === androidApp.startActivity) {
                androidApp.startActivity = undefined;
            }
            androidApp.notify({ eventName: ActivityDestroyed, object: androidApp, activity: activity });
            //gc();
        }),

but its maybe not that simple, I dont know if it's really an problem not to run garbage collector here... can you take a look at this ?

thanks!

sashok1337 commented 5 years ago

Also interested in this bug solving. In my case after scan (nativescript-barcodescanner package) app freezes for 3-10 seconds (depends on device). And gc(); line commenting don't help much