yasirkula / UnityNativeShare

A Unity plugin to natively share files (images, videos, documents, etc.) and/or plain text on Android & iOS
MIT License
891 stars 131 forks source link

Exception: No such proxy method #108

Closed D33pTh0ught closed 3 years ago

D33pTh0ught commented 3 years ago

Description

Calling share on Android triggers an Exception.

Reproduction steps

public static class Screenshot { public static event Action OnShare;

private static WaitForEndOfFrame _frameEnd = new WaitForEndOfFrame();

public static void Share()
{
    if (OnShare != null) OnShare();

    // not possible with UniTask (https://twitter.com/okprogramming/status/1229643339084943360?s=20)
    AutoMonoBehaviour.Instance.StartCoroutine(TakeScreenshotAndShare());
}

private static IEnumerator TakeScreenshotAndShare()
{
    yield return _frameEnd;
    Texture2D _screenshot = new Texture2D(Screen.width, Screen.height, TextureFormat.RGB24, false);
    _screenshot.ReadPixels(new Rect(0, 0, Screen.width, Screen.height), 0, 0);
    _screenshot.Apply();

    string filePath = Path.Combine(Application.temporaryCachePath, "shared img.png");
    File.WriteAllBytes(filePath, _screenshot.EncodeToPNG());

    // To avoid memory leaks
    UnityEngine.Object.Destroy(_screenshot);

    new NativeShare().AddFile(filePath)
        .SetSubject("Title").SetText("Description").SetUrl("https://github.com/yasirkula/UnityNativeShare")
        .SetCallback((result, shareTarget) => Debug.Log("Share result: " + result + ", selected app: " + shareTarget))
        .Share();
}

}

public class AutoMonoBehaviour : MonoBehaviour { private static AutoMonoBehaviour _Instance;

public static AutoMonoBehaviour Instance
{
    get
    {
        if (_Instance == null)
        {
            _Instance = new GameObject("MonoBehaviourInstance").AddComponent<AutoMonoBehaviour>();
        }

        return _Instance;
    }
}

}

* Call `Screenshot.Share()`

**Platform specs**

    Device: Xiamomi Redmi Note 8 (Andorid 9)
    Unity version 2020.3.2f1
    ARFoundation version 4.1.5

**Additional info**

This are the exact error messages I get:

`Exception: No such proxy method: NativeShareNamespace.NSShareResultCallbackAndroid.HasManagedCallback()`
`AndroidJavaException: java.lang.NullPointerException: Expected to unbox a 'boolean' primitive type but was returned null`

Stack Trace:

Exception: No such proxy method: NativeShareNamespace.NSShareResultCallbackAndroid.HasManagedCallback() UnityEngine.AndroidJNI:CallStaticVoidMethod(IntPtr, IntPtr, jvalue[]) UnityEngine.AndroidJNISafe:CallStaticVoidMethod(IntPtr, IntPtr, jvalue[]) (at /Users/bokken/buildslave/unity/build/Modules/AndroidJNI/AndroidJNISafe.cs:217) UnityEngine.AndroidJavaObject:_CallStatic(String, Object[]) (at /Users/bokken/buildslave/unity/build/Modules/AndroidJNI/AndroidJava.cs:591) UnityEngine.AndroidJavaObject:CallStatic(String, Object[]) (at /Users/bokken/buildslave/unity/build/Modules/AndroidJNI/AndroidJava.cs:252) NativeShare:Share() (at F:\git\Mangalica-Salzwelten\apps\salzwelten\unity\Salzwelten\Library\PackageCache\com.yasirkula.nativeshare@3776f3d47e\Plugins\NativeShare\NativeShare.cs:179) Mangalica.Api.d__5:MoveNext() (at F:\git\Mangalica-Salzwelten\libs\unity\Screenshot\Runtime\Api.cs:35) UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr) (at /Users/bokken/buildslave/unity/build AndroidJavaException: java.lang.NullPointerException: Expected to unbox a 'boolean' primitive type but was returned null java.lang.NullPointerException: Expected to unbox a 'boolean' primitive type but was returned null at $Proxy10.HasManagedCallback(Unknown Source) at com.yasirkula.unity.NativeShare.Share(NativeShare.java:61) at com.unity3d.player.UnityPlayer.nativeRender(Native Method) at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0) at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:201) at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20) at UnityEngine.AndroidJNISafe.CheckException () [0x0008d] in /Users/bokken/buildslave/unity/build/Modules/AndroidJNI/AndroidJNISafe.cs:24 at UnityEngine.AndroidJNISafe.CallStaticVoidMethod (System.IntPtr clazz, System.IntPtr methodID, UnityEngine.jvalue[] args) [0x0000f] in /Users/bokken/buildslave/unity/build/Modules/Android

yasirkula commented 3 years ago

Thank you for the detailed Issue. Can you set Managed Stripping Level to None in Player Settings? I suspect that NSShareResultCallbackAndroid.HasManagedCallback function is getting stripped.

D33pTh0ught commented 3 years ago

Thanks for the quick response. This solves the issue! To be able to still use Android ARM64 builds (requires IL2CPP Scripting Backend which does not allow setting Managed Stripping Level to None) I use this link.xml:

<?xml version="1.0" encoding="utf-8"?>
<linker>
  <assembly fullname="NativeShare.Runtime" preserve="all" />
</linker>
yasirkula commented 3 years ago

I'll try to reproduce the issue myself and see if I can resolve it without link.xml. What was your Managed Stripping Level and C++ Compiler Configuration set to?

D33pTh0ught commented 3 years ago

Managed Stripping Level was set to low and I was using the Mono Backend for testing.

yasirkula commented 3 years ago

On Unity 2019.4.19f1, using latest version of the plugin and the example code, I couldn't reproduce the issue using "Mono+Low Managed Stripping", "Mono+High Managed Stripping", "IL2CPP+High Managed Stripping+Release" or "IL2CPP+High Managed Stripping+Master" configurations. Either the managed code stripping algorithm has changed since 2019.4's release or something else is going on.

When I download 2020 LTS, if I don't forget about this issue, I'll test the plugin again.