本周在测试 deeplink 时遇到一个闪退的问题,提取日志:
03-05 10:46:30.442 2633 2633 D Unity : Uploading Crash Report
03-05 10:46:30.443 2633 2633 E Unity : UnityException: TrySetSetString can only be called from the main thread.
03-05 10:46:30.443 2633 2633 E Unity : Constructors and field initializers will be executed from the loading thread when loading a scene.
03-05 10:46:30.443 2633 2633 E Unity : Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
03-05 10:46:30.443 2633 2633 E Unity :
03-05 10:46:30.443 2633 2633 E Unity : Rethrow as TargetInvocationException: com.adjust.sdk.AdjustAndroid+DeferredDeeplinkListener.launchReceivedDeeplink(UnityEngine.AndroidJavaObject)
03-05 10:46:30.443 2633 2633 E Unity : at UnityEngine.AndroidJavaProxy.Invoke (System.String methodName, System.Object[] args) [0x00000] in <00000000000000000000000000000000>:0
03-05 10:46:30.443 2633 2633 E Unity :
03-05 10:46:30.443 2633 2633 E Unity : (Filename: currently not available on il2cpp Line: -1)
03-05 10:46:30.443 2633 2633 E Unity :
关键信息是 UnityException: TrySetSetString can only be called from the main thread
,即 SetString
只能在主线程中被调用。
回到代码处:
void DeferredDeeplinkCallback(string param)
{
UnityEngine.PlayerPrefs.SetString(key, param);
}
这个函数是在 adjust 初始化时注入的,也就是说实际进行 SetString
确实不是 unity 主线程。
解决这个问题的一个简单思路是,将内容缓存下来,等待主线程去执行 SetString
。
void checkDeeplink()
{
if (!string.IsNullOrEmpty(_deeplink))
{
UnityEngine.PlayerPrefs.SetString(key, _deeplink);
_deeplink = null;
}
}