本週在測試 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;
}
}