亚洲有码Av一区二区三区_国产高清啪啪免费视频_69色视频国产_国产成人人人爆出白浆_国产精品自在线拍国_一本久久伊人热热精品无码_午夜性刺激在线看免费带字幕_助力高品质欧美狂喷水_亚洲精品日韩无码_精品无码一区二区三区蜜臀_麻豆高清国产AV_熟妇人素无码中文字幕_亚洲a级片在线观看_国产欧美日韩三区_99国产成人高清在线观看

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Unity手游動(dòng)態(tài)圖標(biāo)雙端工程化方案:Android activity-alias與iOS setAlternateIconName實(shí)戰(zhàn)

Unity手游動(dòng)態(tài)圖標(biāo)雙端工程化方案:Android activity-alias與iOS setAlternateIconName實(shí)戰(zhàn) 1. 動(dòng)態(tài)圖標(biāo)這件事到底在解決什么問題做過手游運(yùn)營的人都有一個(gè)共識(shí)App圖標(biāo)是成本最低、觸達(dá)最廣的運(yùn)營位。它不需要用戶打開游戲不需要推送權(quán)限甚至不需要用戶在線——只要圖標(biāo)躺在手機(jī)桌面上每一次解鎖屏幕都是一次曝光。春節(jié)換紅底、周年慶換金色、聯(lián)動(dòng)活動(dòng)換角色立繪這套玩法在國內(nèi)頭部手游里早就跑通了。但問題在于Unity作為跨平臺(tái)引擎本身并沒有提供一套統(tǒng)一的動(dòng)態(tài)圖標(biāo)API。Android和iOS兩端的實(shí)現(xiàn)路徑完全不同Android靠activity-alias做組件切換iOS靠setAlternateIconName做系統(tǒng)級(jí)替換。更麻煩的是Unity的構(gòu)建流程會(huì)覆蓋原生工程配置你手動(dòng)改的東西下一次出包就沒了。所以真正要解決的不是怎么換圖標(biāo)這個(gè)單點(diǎn)問題而是怎么在Unity的構(gòu)建管線里把雙端的動(dòng)態(tài)圖標(biāo)能力做成可配置、可自動(dòng)化、不丟配置的工程化方案。這篇文章適合三類人看一是正在做手游運(yùn)營功能開發(fā)的同學(xué)二是需要給項(xiàng)目加動(dòng)態(tài)圖標(biāo)但不知道從哪下手的Unity客戶端三是想了解Androidactivity-alias和iOS alternate icon底層機(jī)制的移動(dòng)端開發(fā)者。我會(huì)把兩端的原理、Unity側(cè)的工程改造、構(gòu)建腳本、踩過的坑全部攤開講代碼和配置都可以直接抄。先說結(jié)論Android端用activity-alias方案切換時(shí)會(huì)有一次桌面圖標(biāo)的閃動(dòng)系統(tǒng)會(huì)短暫移除再添加組件但兼容性最好從Android 5.0到14都沒問題iOS端用setAlternateIconName切換時(shí)系統(tǒng)會(huì)彈一個(gè)您已更改圖標(biāo)的提示框這個(gè)提示無法繞過除非用私有API不建議。兩端都需要在Unity構(gòu)建后處理原生工程文件這部分我用Editor腳本自動(dòng)化掉了。2. 雙端方案選型為什么Android用activity-aliasiOS用setAlternateIconName2.1 Android端activity-alias是唯一靠譜的路Android換圖標(biāo)這件事網(wǎng)上能搜到好幾種說法我一個(gè)個(gè)說清楚為什么最后選了activity-alias。第一種是直接改AndroidManifest.xml里application的android:icon屬性然后重新安裝。這顯然不行用戶不可能為了換個(gè)圖標(biāo)重新下載APK。第二種是用PackageManager.setComponentEnabledSetting動(dòng)態(tài)啟用/禁用組件。這個(gè)API本身沒問題關(guān)鍵在于你要啟用/禁用什么組件。Android的桌面圖標(biāo)本質(zhì)上是一個(gè)activity組件帶LAUNCHERcategory的那個(gè)你沒法直接替換一個(gè)activity的圖標(biāo)但你可以通過activity-alias創(chuàng)建多個(gè)別名每個(gè)別名指向同一個(gè)主Activity但各自帶不同的android:icon。然后通過setComponentEnabledSetting控制哪個(gè)別名處于啟用狀態(tài)。具體來說主Activity保持android:enabledfalse且不帶LAUNCHER category然后為每個(gè)圖標(biāo)創(chuàng)建一個(gè)activity-alias只有當(dāng)前選中的那個(gè)alias是enabledtrue且?guī)AUNCHER category。切換圖標(biāo) 禁用舊alias 啟用新alias。activity android:namecom.unity3d.player.UnityPlayerActivity android:exportedtrue android:enabledfalse intent-filter action android:nameandroid.intent.action.MAIN / /intent-filter /activity activity-alias android:name.icon_default android:targetActivitycom.unity3d.player.UnityPlayerActivity android:enabledtrue android:exportedtrue android:iconmipmap/app_icon_default android:labelstring/app_name intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity-alias activity-alias android:name.icon_festival android:targetActivitycom.unity3d.player.UnityPlayerActivity android:enabledfalse android:exportedtrue android:iconmipmap/app_icon_festival android:labelstring/app_name intent-filter action android:nameandroid.intent.action.MAIN / category android:nameandroid.intent.category.LAUNCHER / /intent-filter /activity-alias這里有幾個(gè)必須注意的細(xì)節(jié)我踩過坑主Activity的intent-filter里不能有LAUNCHER category否則桌面上會(huì)出現(xiàn)兩個(gè)圖標(biāo)。只保留MAIN action即可。每個(gè)alias的android:name建議用相對(duì)路徑如.icon_default這樣會(huì)自動(dòng)拼上包名避免硬編碼包名出錯(cuò)。android:enabled的初始狀態(tài)默認(rèn)圖標(biāo)那個(gè)alias設(shè)為true其他全部false。這個(gè)狀態(tài)會(huì)被系統(tǒng)持久化用戶重啟手機(jī)也不會(huì)丟。切換時(shí)用PackageManager.setComponentEnabledSetting必須傳DONT_KILL_APP標(biāo)志否則切換的瞬間你的進(jìn)程會(huì)被殺掉用戶體驗(yàn)極差。// Android側(cè)切換代碼 public void switchIcon(String aliasName) { PackageManager pm getPackageManager(); String pkg getPackageName(); // 先禁用所有alias String[] allAliases {icon_default, icon_festival, icon_anniversary}; for (String alias : allAliases) { pm.setComponentEnabledSetting( new ComponentName(pkg, pkg . alias), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP ); } // 啟用目標(biāo)alias pm.setComponentEnabledSetting( new ComponentName(pkg, pkg . aliasName), PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP ); }實(shí)測下來這個(gè)方案在小米、華為、OPPO、vivo、三星的主流機(jī)型上都能正常工作。唯一的問題是切換瞬間桌面圖標(biāo)會(huì)有一個(gè)短暫的消失再出現(xiàn)的過程這是系統(tǒng)launcher重新加載組件導(dǎo)致的無法避免。我的做法是在切換前給用戶一個(gè)loading提示切換完成后彈一個(gè)Toast讓用戶知道發(fā)生了什么。2.2 iOS端setAlternateIconName的能與不能iOS從10.3開始提供了setAlternateIconName:completionHandler:這個(gè)API允許App在運(yùn)行時(shí)切換圖標(biāo)。但蘋果對(duì)這個(gè)功能加了很多限制你必須提前知道第一所有備選圖標(biāo)必須在Info.plist里預(yù)先聲明。你不能在運(yùn)行時(shí)動(dòng)態(tài)生成圖標(biāo)只能從預(yù)先打包進(jìn)Bundle的圖標(biāo)里選。聲明方式是在Info.plist里加一個(gè)CFBundleIcons字典keyCFBundleIcons/key dict keyCFBundlePrimaryIcon/key dict keyCFBundleIconFiles/key array stringAppIcon60x60/string /array /dict keyCFBundleAlternateIcons/key dict keyfestival/key dict keyCFBundleIconFiles/key array stringAppIcon_Festival60x60/string /array keyUIPrerenderedIcon/key false/ /dict keyanniversary/key dict keyCFBundleIconFiles/key array stringAppIcon_Anniversary60x60/string /array keyUIPrerenderedIcon/key false/ /dict /dict /dict第二圖標(biāo)文件必須放在Bundle根目錄下不能放在Assets.xcassets里。這是最容易踩的坑。Xcode的Asset Catalog雖然方便但setAlternateIconName只認(rèn)Bundle根目錄下的png文件。你需要把備選圖標(biāo)以AppIcon_Festival60x60.png、AppIcon_Festival60x602x.png、AppIcon_Festival60x603x.png的命名方式直接拖進(jìn)Xcode工程選擇Create folder references而不是Create groups。第三切換時(shí)會(huì)彈系統(tǒng)提示框。這是iOS的硬性行為提示內(nèi)容大概是您已更改XXX的圖標(biāo)。這個(gè)提示無法通過公開API繞過。有些團(tuán)隊(duì)用UIApplication.shared.isStatusBarHidden之類的hack去遮蓋但在新版本iOS上已經(jīng)失效了不建議折騰。第四切換必須在主線程調(diào)用且completionHandler里要處理錯(cuò)誤。如果圖標(biāo)名不存在或者文件缺失會(huì)返回error。// iOS側(cè)切換代碼 - (void)switchIcon:(NSString *)iconName { if (![UIApplication sharedApplication].supportsAlternateIcons) { NSLog(當(dāng)前設(shè)備不支持切換圖標(biāo)); return; } NSString *targetName [iconName isEqualToString:default] ? nil : iconName; [[UIApplication sharedApplication] setAlternateIconName:targetName completionHandler:^(NSError * _Nullable error) { if (error) { NSLog(切換圖標(biāo)失敗: %, error.localizedDescription); } else { NSLog(切換圖標(biāo)成功); } }]; }注意傳nil表示恢復(fù)默認(rèn)圖標(biāo)。另外supportsAlternateIcons這個(gè)屬性在iOS 10.3才可用低版本要加可用性判斷。2.3 兩端方案對(duì)比對(duì)比項(xiàng)Android (activity-alias)iOS (setAlternateIconName)最低支持版本Android 5.0iOS 10.3圖標(biāo)來源打包進(jìn)APK的mipmap資源打包進(jìn)Bundle的png文件切換時(shí)系統(tǒng)提示無但桌面圖標(biāo)會(huì)閃動(dòng)有彈窗無法繞過是否需要重啟App否否圖標(biāo)數(shù)量限制理論上無限制建議不超過10個(gè)審核風(fēng)險(xiǎn)無需在審核時(shí)說明用途3. Unity工程側(cè)改造讓構(gòu)建管線自動(dòng)處理原生配置3.1 為什么不能手動(dòng)改原生工程Unity的構(gòu)建流程是這樣的每次Build它都會(huì)重新生成Android的AndroidManifest.xml和iOS的Info.plist或者至少覆蓋你手動(dòng)改的部分。你這次手動(dòng)加了activity-alias下次出包就沒了。所以必須把配置注入到Unity的構(gòu)建管線里。Unity提供了兩個(gè)關(guān)鍵接口IPreprocessBuildWithReport和IPostprocessBuildWithReport。前者在構(gòu)建前執(zhí)行后者在構(gòu)建后執(zhí)行。對(duì)于Android我們需要在構(gòu)建后修改AndroidManifest.xml因?yàn)閁nity生成的manifest在構(gòu)建后才最終確定對(duì)于iOS我們需要在構(gòu)建后修改Info.plist并拷貝圖標(biāo)文件。3.2 Android側(cè)PostprocessBuild注入activity-aliasAndroid的manifest處理有個(gè)坑Unity構(gòu)建出來的工程AndroidManifest.xml在Temp/StagingArea目錄下構(gòu)建完成后會(huì)被拷貝到最終的Gradle工程里。我們需要在OnPostprocessBuild里找到這個(gè)文件并修改。using UnityEditor; using UnityEditor.Callbacks; using System.IO; using System.Xml; using UnityEngine; public class AndroidIconPostprocessor { [PostProcessBuild(1000)] public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) { if (target ! BuildTarget.Android) return; string manifestPath Path.Combine(pathToBuiltProject, AndroidManifest.xml); // 如果是Gradle工程路徑不同 if (EditorUserBuildSettings.exportAsGoogleAndroidProject) { manifestPath Path.Combine(pathToBuiltProject, unityLibrary, src, main, AndroidManifest.xml); } if (!File.Exists(manifestPath)) { Debug.LogError(找不到AndroidManifest.xml: manifestPath); return; } XmlDocument doc new XmlDocument(); doc.Load(manifestPath); XmlNode applicationNode doc.SelectSingleNode(/manifest/application); if (applicationNode null) return; // 找到主Activity移除LAUNCHER category設(shè)置enabledfalse XmlNode mainActivity FindMainActivity(applicationNode); if (mainActivity null) return; SetMainActivityDisabled(mainActivity); // 注入activity-alias string packageName doc.DocumentElement.GetAttribute(package); string[] iconNames { default, festival, anniversary }; foreach (string iconName in iconNames) { XmlElement alias CreateActivityAlias(doc, packageName, iconName); applicationNode.AppendChild(alias); } doc.Save(manifestPath); Debug.Log(Android動(dòng)態(tài)圖標(biāo)配置注入完成); } private static XmlNode FindMainActivity(XmlNode applicationNode) { foreach (XmlNode child in applicationNode.ChildNodes) { if (child.Name ! activity) continue; XmlNode intentFilter child.SelectSingleNode(intent-filter); if (intentFilter null) continue; XmlNode launcher intentFilter.SelectSingleNode(category[android:nameandroid.intent.category.LAUNCHER]); if (launcher ! null) return child; } return null; } private static void SetMainActivityDisabled(XmlNode activity) { XmlElement elem (XmlElement)activity; elem.SetAttribute(enabled, http://schemas.android.com/apk/res/android, false); // 移除LAUNCHER category XmlNode intentFilter activity.SelectSingleNode(intent-filter); if (intentFilter ! null) { XmlNode launcher intentFilter.SelectSingleNode(category[android:nameandroid.intent.category.LAUNCHER]); if (launcher ! null) intentFilter.RemoveChild(launcher); } } private static XmlElement CreateActivityAlias(XmlDocument doc, string packageName, string iconName) { XmlElement alias doc.CreateElement(activity-alias); alias.SetAttribute(name, http://schemas.android.com/apk/res/android, .icon_ iconName); alias.SetAttribute(targetActivity, http://schemas.android.com/apk/res/android, com.unity3d.player.UnityPlayerActivity); alias.SetAttribute(enabled, http://schemas.android.com/apk/res/android, iconName default ? true : false); alias.SetAttribute(exported, http://schemas.android.com/apk/res/android, true); alias.SetAttribute(icon, http://schemas.android.com/apk/res/android, mipmap/app_icon_ iconName); alias.SetAttribute(label, http://schemas.android.com/apk/res/android, string/app_name); XmlElement intentFilter doc.CreateElement(intent-filter); XmlElement action doc.CreateElement(action); action.SetAttribute(name, http://schemas.android.com/apk/res/android, android.intent.action.MAIN); XmlElement category doc.CreateElement(category); category.SetAttribute(name, http://schemas.android.com/apk/res/android, android.intent.category.LAUNCHER); intentFilter.AppendChild(action); intentFilter.AppendChild(category); alias.AppendChild(intentFilter); return alias; } }這段代碼有幾個(gè)關(guān)鍵點(diǎn)PostProcessBuild的優(yōu)先級(jí)設(shè)為1000確保在其他后處理腳本之后執(zhí)行處理了Gradle工程和直接APK兩種構(gòu)建模式用XmlDocument操作而不是字符串替換避免格式錯(cuò)誤。3.3 iOS側(cè)PostprocessBuild修改Info.plist并拷貝圖標(biāo)iOS這邊更麻煩一點(diǎn)因?yàn)槌烁腎nfo.plist還要把圖標(biāo)文件拷貝到正確的位置。Unity構(gòu)建出來的Xcode工程Info.plist在Unity-iPhone/Info.plist圖標(biāo)需要拷貝到Unity-iPhone/根目錄下。using UnityEditor; using UnityEditor.Callbacks; using System.IO; using UnityEditor.iOS.Xcode; using UnityEngine; public class IOSIconPostprocessor { [PostProcessBuild(1000)] public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject) { if (target ! BuildTarget.iOS) return; string plistPath Path.Combine(pathToBuiltProject, Info.plist); PlistDocument plist new PlistDocument(); plist.ReadFromFile(plistPath); PlistElementDict rootDict plist.root; PlistElementDict bundleIcons rootDict.CreateDict(CFBundleIcons); // 主圖標(biāo) PlistElementDict primaryIcon bundleIcons.CreateDict(CFBundlePrimaryIcon); PlistElementArray primaryFiles primaryIcon.CreateArray(CFBundleIconFiles); primaryFiles.AddString(AppIcon60x60); // 備選圖標(biāo) PlistElementDict alternateIcons bundleIcons.CreateDict(CFBundleAlternateIcons); string[] iconNames { festival, anniversary }; foreach (string iconName in iconNames) { PlistElementDict iconDict alternateIcons.CreateDict(iconName); PlistElementArray iconFiles iconDict.CreateArray(CFBundleIconFiles); iconFiles.AddString(AppIcon_ Capitalize(iconName) 60x60); iconDict.SetBoolean(UIPrerenderedIcon, false); } plist.WriteToFile(plistPath); // 拷貝圖標(biāo)文件到Bundle根目錄 string sourceDir Assets/Editor/DynamicIcons/iOS; string destDir pathToBuiltProject; foreach (string iconName in iconNames) { string baseName AppIcon_ Capitalize(iconName) 60x60; CopyIconFile(sourceDir, destDir, baseName .png); CopyIconFile(sourceDir, destDir, baseName 2x.png); CopyIconFile(sourceDir, destDir, baseName 3x.png); } Debug.Log(iOS動(dòng)態(tài)圖標(biāo)配置注入完成); } private static void CopyIconFile(string sourceDir, string destDir, string fileName) { string src Path.Combine(sourceDir, fileName); string dst Path.Combine(destDir, fileName); if (File.Exists(src)) { File.Copy(src, dst, true); } else { Debug.LogWarning(圖標(biāo)文件不存在: src); } } private static string Capitalize(string s) { if (string.IsNullOrEmpty(s)) return s; return char.ToUpper(s[0]) s.Substring(1); } }這里用了Unity的PlistDocument類來操作plist比直接改XML安全得多。圖標(biāo)文件我放在Assets/Editor/DynamicIcons/iOS/目錄下構(gòu)建時(shí)自動(dòng)拷貝。3.4 Unity與原生層的橋接Unity側(cè)要調(diào)用原生的切換方法需要做平臺(tái)判斷和橋接。Android用AndroidJavaObjectiOS用DllImport。using UnityEngine; public class DynamicIconManager : MonoBehaviour { public static void SwitchIcon(string iconName) { #if UNITY_ANDROID !UNITY_EDITOR using (AndroidJavaClass unityPlayer new AndroidJavaClass(com.unity3d.player.UnityPlayer)) using (AndroidJavaObject activity unityPlayer.GetStaticAndroidJavaObject(currentActivity)) { activity.Call(runOnUiThread, new AndroidJavaRunnable(() { activity.Call(switchIcon, icon_ iconName); })); } #elif UNITY_IOS !UNITY_EDITOR _SwitchIcon(iconName); #else Debug.Log(編輯器模式下不執(zhí)行圖標(biāo)切換: iconName); #endif } #if UNITY_IOS !UNITY_EDITOR [System.Runtime.InteropServices.DllImport(__Internal)] private static extern void _SwitchIcon(string iconName); #endif }iOS側(cè)需要一個(gè).mm文件來暴露C接口給Unity// DynamicIcon.mm #import UIKit/UIKit.h extern C { void _SwitchIcon(const char* iconName) { NSString *name [NSString stringWithUTF8String:iconName]; dispatch_async(dispatch_get_main_queue(), ^{ if (![UIApplication sharedApplication].supportsAlternateIcons) return; NSString *target [name isEqualToString:default] ? nil : name; [[UIApplication sharedApplication] setAlternateIconName:target completionHandler:^(NSError *error) { if (error) NSLog(切換圖標(biāo)失敗: %, error); }]; }); } }這個(gè).mm文件需要放在Assets/Plugins/iOS/目錄下Unity會(huì)自動(dòng)把它編譯進(jìn)Xcode工程。4. 實(shí)操全流程從資源準(zhǔn)備到出包驗(yàn)證4.1 圖標(biāo)資源規(guī)范與準(zhǔn)備Android和iOS對(duì)圖標(biāo)尺寸的要求不一樣我整理了一個(gè)對(duì)照表平臺(tái)用途尺寸命名規(guī)范存放位置Androidmipmap-mdpi48x48app_icon_default.pngAssets/Plugins/Android/res/mipmap-mdpi/Androidmipmap-hdpi72x72app_icon_default.pngAssets/Plugins/Android/res/mipmap-hdpi/Androidmipmap-xhdpi96x96app_icon_default.pngAssets/Plugins/Android/res/mipmap-xhdpi/Androidmipmap-xxhdpi144x144app_icon_default.pngAssets/Plugins/Android/res/mipmap-xxhdpi/Androidmipmap-xxxhdpi192x192app_icon_default.pngAssets/Plugins/Android/res/mipmap-xxxhdpi/iOS60x601x60x60AppIcon_Festival60x60.pngAssets/Editor/DynamicIcons/iOS/iOS60x602x120x120AppIcon_Festival60x602x.pngAssets/Editor/DynamicIcons/iOS/iOS60x603x180x180AppIcon_Festival60x603x.pngAssets/Editor/DynamicIcons/iOS/Android的圖標(biāo)放在Assets/Plugins/Android/res/下Unity構(gòu)建時(shí)會(huì)自動(dòng)合并到APK的res目錄。注意不要放在Assets/Resources/下那樣不會(huì)被打進(jìn)原生資源。iOS的圖標(biāo)命名有個(gè)坑CFBundleIconFiles里寫的是AppIcon_Festival60x60系統(tǒng)會(huì)自動(dòng)去找AppIcon_Festival60x60.png、AppIcon_Festival60x602x.png、AppIcon_Festival60x603x.png。所以命名必須嚴(yán)格一致大小寫敏感。4.2 構(gòu)建腳本的完整配置把上面兩個(gè)Postprocessor腳本放到Assets/Editor/目錄下Unity會(huì)自動(dòng)識(shí)別。但有幾個(gè)配置項(xiàng)需要確認(rèn)Player Settings → Publishing Settings → Build如果勾選了Custom Main ManifestUnity會(huì)用你提供的manifest而不是自動(dòng)生成。這種情況下你需要手動(dòng)在自定義manifest里加aliasPostprocessor腳本要相應(yīng)調(diào)整。Player Settings → Other Settings → Package Name確保包名正確alias的name會(huì)基于包名生成。iOS Player Settings → Icon這里配置的是主圖標(biāo)備選圖標(biāo)不走這里走我們的Postprocessor。我建議的做法是不勾選Custom Main Manifest讓Unity自動(dòng)生成然后Postprocessor在構(gòu)建后注入。這樣最省心。4.3 切換邏輯的時(shí)機(jī)與狀態(tài)管理圖標(biāo)切換不是隨便什么時(shí)候都能調(diào)的。我的經(jīng)驗(yàn)是不要在App啟動(dòng)時(shí)立即切換。啟動(dòng)階段系統(tǒng)資源緊張切換容易失敗。建議在進(jìn)入主界面后延遲1-2秒再執(zhí)行。切換狀態(tài)要持久化。用PlayerPrefs記錄當(dāng)前圖標(biāo)名下次啟動(dòng)時(shí)對(duì)比服務(wù)端下發(fā)的配置如果一致就不重復(fù)切換避免不必要的閃動(dòng)和彈窗。切換前檢查網(wǎng)絡(luò)和資源。如果圖標(biāo)資源是熱更下載的Android可以iOS不行因?yàn)閳D標(biāo)必須打包進(jìn)Bundle要確保下載完成再切換。public class IconSwitchController : MonoBehaviour { private const string ICON_KEY current_icon_name; void Start() { Invoke(CheckAndSwitchIcon, 2f); } private void CheckAndSwitchIcon() { string serverIcon GetServerIconConfig(); // 從服務(wù)端或本地配置讀取 string localIcon PlayerPrefs.GetString(ICON_KEY, default); if (serverIcon ! localIcon) { DynamicIconManager.SwitchIcon(serverIcon); PlayerPrefs.SetString(ICON_KEY, serverIcon); PlayerPrefs.Save(); } } }4.4 出包驗(yàn)證清單出包后別急著發(fā)按這個(gè)清單過一遍Android安裝后桌面圖標(biāo)是否正常顯示默認(rèn)圖標(biāo)用adb shell dumpsys package 包名查看alias的enabled狀態(tài)是否正確。Android調(diào)用切換后桌面圖標(biāo)是否變成目標(biāo)圖標(biāo)殺掉App重開圖標(biāo)是否保持Android切換時(shí)App是否被殺掉如果被殺檢查DONT_KILL_APP標(biāo)志是否傳了。iOS安裝后圖標(biāo)是否正常切換時(shí)是否彈出系統(tǒng)提示切換后圖標(biāo)是否變化iOS殺掉App重開圖標(biāo)是否保持恢復(fù)默認(rèn)圖標(biāo)是否正常雙端連續(xù)切換多次是否有異常圖標(biāo)資源是否都正確打包5. 常見問題與排查技巧實(shí)錄5.1 Android端典型問題問題一桌面上出現(xiàn)兩個(gè)圖標(biāo)。這是最常見的問題。原因通常是主Activity的intent-filter里還保留著LAUNCHER category。檢查AndroidManifest.xml確保主Activity的intent-filter里只有MAIN action沒有LAUNCHER category。另外檢查是否有多個(gè)alias同時(shí)處于enabled狀態(tài)。問題二切換后圖標(biāo)沒變但alias狀態(tài)變了。這種情況通常是launcher緩存導(dǎo)致的。不同廠商的launcher刷新機(jī)制不一樣小米和華為一般會(huì)立即刷新OPPO和vivo可能有延遲。解決辦法是切換后發(fā)一個(gè)廣播通知launcher刷新但這不是標(biāo)準(zhǔn)API各廠商支持情況不一。我的做法是切換后彈一個(gè)Toast提示用戶圖標(biāo)將在幾秒后更新給用戶預(yù)期。問題三切換時(shí)App閃退。檢查是否在主線程調(diào)用setComponentEnabledSetting。這個(gè)API必須在主線程執(zhí)行。另外檢查alias的name是否拼寫正確ComponentName的第二個(gè)參數(shù)必須是完整類名包名alias名。問題四某些機(jī)型上alias不生效。部分定制ROM尤其是早期的EMUI和MIUI對(duì)activity-alias的支持有問題。實(shí)測下來Android 7.0以上的主流機(jī)型基本沒問題Android 5.x和6.x的部分機(jī)型可能有兼容性問題。如果目標(biāo)用戶里老機(jī)型占比高建議做降級(jí)處理檢測切換是否成功失敗則提示用戶手動(dòng)更換。5.2 iOS端典型問題問題一切換時(shí)報(bào)錯(cuò)icon name not found。檢查三件事Info.plist里CFBundleAlternateIcons的key是否和傳入的name一致圖標(biāo)文件是否在Bundle根目錄下不是Assets.xcassets文件名是否和CFBundleIconFiles里聲明的一致包括2x、3x后綴。問題二切換時(shí)彈窗提示您已更改圖標(biāo)能否去掉不能。這是iOS的系統(tǒng)行為公開API無法繞過。有些團(tuán)隊(duì)嘗試用UIAlertController的私有方法去攔截但在iOS 13以后已經(jīng)失效。接受它或者在產(chǎn)品層面引導(dǎo)用戶比如切換前先彈一個(gè)自定義提示說明會(huì)有一個(gè)系統(tǒng)彈窗。問題三審核時(shí)被拒說動(dòng)態(tài)圖標(biāo)功能不明確。App Store審核指南對(duì)動(dòng)態(tài)圖標(biāo)沒有明確禁止但如果你的App切換圖標(biāo)后功能沒有變化審核員可能認(rèn)為這是無意義的功能。建議在審核時(shí)提供說明動(dòng)態(tài)圖標(biāo)用于節(jié)日活動(dòng)或用戶個(gè)性化并在App內(nèi)提供明確的切換入口。問題四iPad上不生效。iPad的圖標(biāo)尺寸和iPhone不一樣CFBundleIconFiles需要額外聲明iPad的尺寸如AppIcon_Festival76x76。如果只聲明了60x60iPad上可能不生效。建議同時(shí)聲明iPhone和iPad的圖標(biāo)尺寸。5.3 雙端通用問題速查表問題現(xiàn)象可能原因排查方向解決方案切換后圖標(biāo)不變資源未打包檢查APK/Bundle里是否有圖標(biāo)文件確認(rèn)資源路徑正確切換后App重啟未傳DONT_KILL_APP檢查Android代碼加上標(biāo)志iOS切換報(bào)錯(cuò)plist配置錯(cuò)誤檢查CFBundleAlternateIcons修正key和文件名桌面出現(xiàn)雙圖標(biāo)LAUNCHER category重復(fù)檢查manifest移除主Activity的LAUNCHER切換狀態(tài)丟失未持久化檢查PlayerPrefs切換后立即Save部分機(jī)型不生效ROM兼容性查看系統(tǒng)版本做降級(jí)提示5.4 我踩過的幾個(gè)坑第一個(gè)坑是Android的alias name用了絕對(duì)路徑。一開始我寫的是com.example.game.icon_default結(jié)果在某些機(jī)型上不生效。后來改成相對(duì)路徑.icon_default讓系統(tǒng)自動(dòng)拼包名問題解決。原因是絕對(duì)路徑在某些ROM上會(huì)被當(dāng)成不同的組件處理。第二個(gè)坑是iOS圖標(biāo)文件放進(jìn)了Assets.xcassets。Xcode的Asset Catalog會(huì)把圖標(biāo)編譯成Assets.carsetAlternateIconName根本找不到。必須用folder reference的方式直接放Bundle根目錄。第三個(gè)坑是Unity構(gòu)建時(shí)覆蓋了Info.plist。我一開始在Xcode里手動(dòng)改了plist結(jié)果Unity重新構(gòu)建后全沒了。后來用Postprocessor腳本自動(dòng)注入才徹底解決。第四個(gè)坑是切換時(shí)機(jī)太早。在Awake里調(diào)用切換Android上經(jīng)常失敗因?yàn)锳ctivity還沒完全初始化。改成延遲2秒后調(diào)用穩(wěn)定了。6. 工程化擴(kuò)展與進(jìn)階玩法6.1 圖標(biāo)配置表驅(qū)動(dòng)硬編碼圖標(biāo)名不是好做法。我建議用ScriptableObject做配置表把圖標(biāo)名、資源路徑、生效時(shí)間、平臺(tái)限制都配置化。[CreateAssetMenu(fileName IconConfig, menuName DynamicIcon/IconConfig)] public class IconConfig : ScriptableObject { [System.Serializable] public class IconEntry { public string iconName; public string displayName; public long startTime; public long endTime; public bool enableAndroid; public bool enableIOS; } public ListIconEntry icons new ListIconEntry(); public string GetActiveIcon(long currentTime) { foreach (var icon in icons) { if (currentTime icon.startTime currentTime icon.endTime) return icon.iconName; } return default; } }這樣運(yùn)營配置活動(dòng)時(shí)只需要改配置表不需要改代碼。6.2 服務(wù)端下發(fā)與灰度圖標(biāo)切換的配置最好走服務(wù)端下發(fā)這樣可以隨時(shí)調(diào)整活動(dòng)時(shí)間不需要發(fā)版。服務(wù)端返回一個(gè)JSON客戶端解析后對(duì)比本地狀態(tài)決定是否切換。灰度方面可以按用戶ID哈?;蛘咔腊鼇砜刂颇男┯脩魠⑴c。6.3 與熱更系統(tǒng)的配合Android的圖標(biāo)資源可以走熱更因?yàn)閍lias的icon屬性可以指向下載到本地的資源實(shí)際上不行alias的icon必須是打包進(jìn)APK的資源。所以Android的備選圖標(biāo)也必須預(yù)先打包進(jìn)APK不能熱更。這一點(diǎn)和iOS一樣。所以動(dòng)態(tài)圖標(biāo)的動(dòng)態(tài)指的是切換時(shí)機(jī)動(dòng)態(tài)而不是圖標(biāo)資源動(dòng)態(tài)。這個(gè)認(rèn)知很重要很多團(tuán)隊(duì)一開始以為可以熱更圖標(biāo)結(jié)果發(fā)現(xiàn)不行。如果確實(shí)需要大量圖標(biāo)比如用戶自定義圖標(biāo)Android可以通過PackageManager的setComponentEnabledSetting配合動(dòng)態(tài)生成的alias來實(shí)現(xiàn)但需要反射調(diào)用隱藏API風(fēng)險(xiǎn)較高不建議。6.4 用戶體驗(yàn)優(yōu)化建議切換圖標(biāo)這件事用戶感知很強(qiáng)但也很容易做成騷擾。我的建議是給用戶選擇權(quán)。不要強(qiáng)制切換在設(shè)置里提供圖標(biāo)選擇入口讓用戶自己選。切換前告知。尤其是iOS系統(tǒng)彈窗會(huì)讓用戶困惑提前用自定義彈窗說明。提供恢復(fù)默認(rèn)的入口。用戶換了圖標(biāo)后想換回來要能方便地找到。不要頻繁切換。一天切好幾次會(huì)讓用戶覺得App不穩(wěn)定。我在實(shí)際項(xiàng)目里的做法是默認(rèn)圖標(biāo)保持不變只在重大活動(dòng)時(shí)通過服務(wù)端配置切換活動(dòng)結(jié)束后自動(dòng)恢復(fù)。同時(shí)在設(shè)置里提供圖標(biāo)樣式選項(xiàng)讓喜歡個(gè)性化的用戶自己選。這樣既保證了運(yùn)營效果又不打擾普通用戶。最后分享一個(gè)小技巧Android端可以在切換后發(fā)一個(gè)自定義廣播Intent.ACTION_PACKAGE_CHANGED部分launcher會(huì)響應(yīng)這個(gè)廣播刷新圖標(biāo)能減少圖標(biāo)閃動(dòng)的時(shí)間。但這個(gè)廣播不是所有l(wèi)auncher都認(rèn)只能算錦上添花。iOS端則可以在切換完成后用UIApplication.shared.applicationIconBadgeNumber觸發(fā)一次刷新有時(shí)候能讓圖標(biāo)更快更新但效果不穩(wěn)定看系統(tǒng)版本。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
国产精品乱码久久久久| 天天日天天爽| 男女真人网18| 人妻久热在线| 青娱乐 青青青操 日逼| 一线黄色免费性爱片| 欧洲色| 91欧美另类| 欧美色欧美| 亚洲欧美日韩精品久久久一区二区 | 97免费视频网| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 综合激情婷婷| 啪啪啪男女亚洲中文字幕99| 国产精品一区二区黄片| 91网站在线播放| 精品中文一区二区| 精品人妻av在线播放| 色色综合网站| #NAME?| 九九热久久99精品re| 人妻碰碰碰碰碰碰| 精品超碰色| 黄片免费久久久久久久| 欧美暴力猛交| 精品人妻1区| 亚洲视频小说| 欧美日本中字另类在线| 蜜臀99久久精品| 这里有精品| 中文字幕国产在线天堂| 欧美在线|亚洲| 国产亚洲精品玖玖玖在线观看| 精品中文一区二区| 啊啊啊啊好大好硬啊啊啊啊啊| 日本淫乱女一区二区三区视频| 亚洲男人的天堂在线看| 久久99久久99久久99人受| 白嫩91在线亚洲| 情色五月天网| AA丁香综合激情| 一二三四视频中文字幕在线看| 欧洲乱码视频| 亚洲 欧美日韩 另类| 校园春色宗合网| 欧美激情性久久久久久| 91精品成人| 东北少妇高潮zzzz| 成熟熟女国产精品一区二区| 五月婷视频| 91一区二匹| 日日夜夜模| 亚洲aV性爱| 日本爽爽爽爽爽爽免费视频| 91爱欧美| 欧洲亚洲国产综合在线| 日韩欧视频| 一本色道久久天天射天天干| 99re在线观看| 亚洲本色精品一区二区久久| 91色婷婷综合久久中文字幕二区| 啊啊啊好大好深| 超碰碰小说97| 午夜福利 成人 91| 一区二区三区四区姦女| 国产精品欧美激在线| 色色色热| 精品黄色电影| 国产精品精品系列在线观看| heyZO天然素人无码AⅤ专区| 国产91福利小视频在线观看| 久久精品综合| 91综合网在线| 无码操逼天堂| 色第一页| 91N综合网| 久久黄黄黄| 91综合天天看| 东京热天堂网| 欧美高清无码免费视频高清版| 被操高清无码视频| 亚洲日本加勒比在线| 日韩97| 五月天激情小说网| 黄色av一区二区在线| 丝袜色综合| 久久偷偷色综合蜜桃| 亚洲综合草草| 亚州综合| 无码视频黄色网战| 91撸色网 玖玖网 欧美| 99在线免费视频| 天天久久| 久久精品人人做人人看| 亚洲成人在线高清| 亚洲国产av中文字幕久久| 操屄不卡视频| 麻豆伊人网| 国产精品视频白浆免费| 亚洲综合五月天| 日韩伦理久 久久 清纯| 色色综合97| 日韩免费a级毛片无码a∨| 欧美内射少妇| 日韩无码视频黄色| 亚洲五月天激情| 嫩草黄页| 立川理惠无码一区二区| 亚洲色图亚洲| 福利风月五月天影院| 久久久精品中文字幕麻豆| 日本久久超碰| 中字乱伦AV| 欧美高清在线| 女优视频第10页| 丰满少妇精品一区二区| 操逼视频亚洲| 97这里只有精品| 五月天久久婷婷亚洲| 色综合色欲色综合色综合色综合| 少妇一线天久久久久久| 成人羞羞视频国产| 久jiu久神马影院| 亚洲综合999| 熟女人妻av在线资源,黄色的资源| 亚洲色婷婷综合久久久久中文| 东北丰满熟女国产一区| 国产午夜福利合集| 中国探花熟女| 久久久久久久人妻丝袜| 精品久一区免费| 超碰在线香蕉| 色路综合| 99re8免费高清在线| 午夜久久无码1000合集| 成人情色综合网| 蜜桃久久综合视频| 精品一区二区成人动漫| 人妻铁牛TV| 国产欧洲精品亚洲午夜拍精品| 日韩精品永久在线观看| 日本色色视频网站| 免费男人的天堂| 91骚妇| www久| 亚洲成A∨人影院在线欢看| 国产亚洲色婷婷久久99精品91 - 百度| 国产成人+综合亚洲+天堂| 性爱动态120秒| 色偷综合| 天干天干天干天天做| 国产乱码精品一区二区三区四川| 夂久色| 日韩性爱电影一区| 亚洲熟女少妇免费视频| 久湿久久| 久草毛片电影怡| 激情一区二区| 婷婷15月天青娱乐| 啪啪啪综合网| 98超碰日本| 激情小说亚洲视频| 99色婷婷中文字幕乱色| 欧美78| 人人澡人人爽人人精品| 欧美色图私拍91| 日日干男人的天堂| 夜夜夜夜久久久久| 日韩97| 天天躁日日躁狠狠躁| 插插综合网天天影视网| 丰满人妻-区二区三区免费看| 欧美亚州综合网图片| 亚洲欧美啪啪| 精品玖九九久| 高跟丝袜AV专区国产| 91久久精品中文字幕| 99爱视频| 宅男午夜在线视频| 免费99精品国产自在在线| 亚洲欧美色图片| 天天弄天天操| 欧美亚洲日本视频久久久| 国产情侣自拍在线播放| 九九综合| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 天天做日日做天天欢。| 亚洲综合97中文网| 亚洲少妇喷视频看| 最新精品久久蜜桃| 91综合天天看| 成 人片 黄色大片| 东北女人av| 色香色香欲天天天影视综合网| 一起草视频在线| 伦理弟一页| 亚洲一区操| 欧美美逼| 午夜120视频在线观看| 青娱乐日韩无码| 欧美少妇一区二区三区| 人妻天天爽天天爽三区| 澳门人妻久久| 欧美午夜视频免费观看| 久久久久中出| 日产欧美电影一区二区三区| 日本韩国一本产品小视频日本韩国一本产品久久久产品小视频日本韩国一本产品久 | 无码操逼天堂| 免费视频无码| 国产乱伦视频污| 久久精品欧美一区蜜桃| 午夜性刺激视频免费观看| 亚洲熟女av中文字幕| 茄子社区国产精品| 热热色中文无码| 欧洲色色| 欧美黑人极品高潮喷吹熟女黑人性暴力日韩在线欧美极品一区二区老师黑人潮喷一 | 少妇人妻在线| 操91| 人人性爱视频免费| 91黑丝操| 精品妇女一区二区三区| 天天澡天天爽日日AV| 国产精品美女在线一区| 久久AV无码1区2区3区| 国产精品人妻熟女aⅴ| 久久亚洲婷婷| 黄片com.| 91痴汉| 日本亚洲熟女视频| 国产热RE99久久6国产精品首| 亚洲男人天堂Av| 欧美色图另类图片| 日韩午夜啪啪视频| 色色色五月婷婷| 97干在线视频| 伊人久久大香线蕉亚洲五月天,青草青草欧美日本一区二区,欧美日产欧美日产国产 | 久操网线| 欧美日韩一区二区三区四区蜜桃| 69av一区二区三区| 国产美女在线精品免费看| 九九国产| 亚洲综合一| 久久精品国产99国产精品亚洲| 蜜桃无码AV一区二区| 亚洲黑丝在线| 色啪网| 99精品视频在线观看| 亚洲制服欧美另类内射| 国产区性爱在线视频秋霞豆| 再深点灬舒服灬太大了添视频| 亚洲天堂久| 淫纸中9区| 精品国产99999| 一区二区三区男人的天堂| 欧美色图小说综合| 亚洲无码日韩电影| 亚洲人成网站7777| 亚洲一卡二卡在线免费| 亚洲 国产 精品一区| 中文字幕在线日亚洲9| www四虎| 亚洲AV资源| 亚洲日韩乱码中文无码蜜桃臀网站 | 操啊国产| 强奸a片网| 日韩欧美视频青青| 99在线视频播放| 2019午夜福利视频| 久久久久久久久久va| 99自拍视频在线| 大香蕉综合久久| 亚洲色狠| 999国产精品999| 91偷拍欧美亚洲| 中国操逼无码| 国产黄色视频久久| 1204av韩国| 免费黄色片。| 亚洲精品乱码久久久久久蜜桃麻豆| 色色激情| 人妻一区久久二区三区色播| 黄色香蕉视频网站一区| 久久精品店| 国产亚洲精品激情| 国产激情综合五月久久| 亚洲乱码精品一区二区| 精品四五区| JuliaAnnXXX888| 九九aV| 欧美96交| 日韩高潮一区| 国产综合在线视频网站| 亚洲乱色视频一区、二区在线| 精品人妻一区二区三区视频在线| 色色综合网站| 久久久97| 黑人粗大V S日韩女优视频| 亚洲无码免费看| 色在线69堂| 日韩中文字幕在线视频观看| 久久精品国产亚洲av水密被窝| 国产黄片精品在线| 久久中文字幕女同性恋一区| 亚洲av无码成人精品国产| 婷婷干黄色| 欧美久久草熟女| 亚洲人妻中文高清| 激情小说成人日本无码一| 久久99九九九九6666免费观看软件| 国产精品老师| 亚洲图片欧洲图片aⅴ| 人妻五十路在线| 国产精品久久久久久亚洲色欲| 欧美在线伊人色| 乱欲一区二区| 日韩成人在线性爱视频| 亚洲国产天堂| 天天热精品| 午夜福利久久久噜久噜久久综合| 亚洲成人av电影在线| 亚洲天堂精品日韩电影| 亚洲丝袜二区在线| 欧美91精彩| 91女网站| 亚洲有码 欧美精品| 99久久久久久久久| 色吧5亚洲| 亚洲AV永久无码精品成人调教| 日韩情色视频| 97色在线观看| 中文字幕一区二区免费在线| 亚洲蜜乳av| 夜夜影视四色| 中文字幕啊啊啊在线观看视频| 极品国产内射| 97精品一区| 97人人操人人摸人人爱| 九九九九精| 国产女同在线观看视频| 男插女青青影院| 亚洲国产欧美日韩人妻日中文| 夜夜 中文视频rt| 777AV电影| 欧美少妇色综合| 天天做日日做| 狠狠亚洲| 91精品人妻偷情| 亚洲成人一二三区| 激情久久日韩精品中文字幕麻豆| 亚卅熟女乱色| 91亚洲影视| 日韩成人无码| 91午夜无码| 九九久久99| 亚洲十八禁止| 91在线观看,天天综合| 超碰97国产欧美| 日本一本一区二区三区四区五区欧美日韩中文字幕 | 精品无码产区一区二| AV乱伦专区| 国内自拍 日韩激情 99| 青青草依人大香蕉| 激情五月天丁香社区| 色777999综合| 色欧美在线| 欧在线一二区| 精品国产91内射久久| 国产一区二区在线播放量| 亚州精人品大香蕉| 懂色AV一区二区三区| 麻豆AV一区二区| 99综合自拍| 日日夜夜模| 9.1小视频| 午夜超碰| av日韩国产一区二区| 看日韩操逼| 泰国AV在线观看| 噜噜噜亚洲精品| 97色综合中文网| 日本黄大片在线观看视频| 中文字幕乱在线伦视频中文字幕乱码在线| 亚洲精品一二区| 极品五月天噜噜| 国产久久久久影院老熟女| 欧美综合色图片| 欧美探花网| 99色视频| 91操人| 九九九精品成人免费视频小说| 色在线亚洲视频www| 二色av| 久久久久久久久国产| 97欧美| 久久性爱城| 夜夜久久| 一级性爱视频免费观看| 五月天激情综合网| 欧美 日韩第一性色| 国产人妖视频一区在线观看| 天天淫人人妻日日色| 亚洲无码日韩电影| 99re久久| 久久精品导航| 久久久久免费少妇| 亚洲欧美综合图片| 欧美成人黄网色网站| 91精品久久久久久77777| 久久一区二区三区四区五区| 欧美在线视频99| 91久| 97视频观看| 中文乱码字字幕在线第5页| 久久人妻办公室视频| 国产97色在线 | 亚洲| 中文字幕jul-617人妻熟女| 亚洲伊人久久精品影院| 97色干| 亚洲性综合11| 黄色AV影视| 人人操 欧美| 欧美综合777| 吻戏激情性巴克| 老司机香蕉| renqi久久久久久久久久久久| 久久久久成人网| 99久久久99久久91熟女| 夜夜爽夜夜爽| 日韩精品99久久久久久中文字幕 | 青娱乐老司机视频| 黄色免费网| 人人操人人干xxx| 欧美久久婷| 91网站18禁| 天堂伊人久久| 欧美骚少妇| 亚洲成人在线资源| 天天干18禁| 伊人热综合| 日韩一级二级| 丁香五月天社区| 欧美亚洲第1页| 级品肉射| 中国韩国明星一极片一区乱码毛片人妻熟女一区二区三区 | 超碰日韩人妻| 2018天天干在线视频| 成人性爱高清视频免费看| 亚洲精品精品一区二区| 熟女丰满人妻一区| 欧美天堂超碰97| 日本一线产区和二线产区伦理片| 97精品久久| 精品性爱一二三区| 97亚洲国产影视| 99热日| 超碰91在线| 把腿张开老子CAO烂你| 亚洲av综合伊人久久| 男人的天堂2000| 欧洲精品人妻| 78操B| 嗯……啊…嗯嗯…啊…好舒服| 丝袜美腿诱惑亚洲欧美视频在线观看| 婷婷色香| 激情五月天丁香| 久久久一区二区三区三州| 中文字幕乱妇免费视频| 91色噜噜狠狠| 99热aaa| 国产农村妇女精品一| 嗯嗯啊好大| 三级三久久线久久99久目本WW| 无码不卡亚洲成?人片| 国产性爱欧美性爱在线| 天天综合网~69| 超碰人人超在线观看| 国产精品人人爽人人做可爱福利| 欧美性爱一区二区三区| 国产1727欧美| 久久綜合很很很| 九九久久玖玖| www.色吧5.com| 久久αⅴ| 亚洲成熟国产精品美女| 97蜜桃综合| 日韩大香蕉AV影片| 婷婷亚洲五月***久久| 97免费视频在线| 午夜无遮挡男女啪啪视频| 日韩欧洲操屄视频| 最新国产亚洲精品精品国产亚洲综合| 一区二区三区网站日日骚| 亚州国产成人精品女人久久| 26uuu国产亚洲综合| 色色婷| 大香蕉色欲AV| 乱伦图一区| 亚州再线| 日韩一级久久毛片| 麻豆区99999| 久久99人妖视频国产| 少妇69中文| 久久人妻熟女一区二区| 亚欧成人综合影院| 国产综合在线视频网站| 久久熟女人| 日韩A优精品在线观看| www.久久| 青青在线视频日韩欧美| 91超级碰碰| 97中文字幕一区| 夜夜爽爽爽| 中文字幕一二区二三区人妻专区| 久久一本大香蕉| 插入综合网| 99少妇| 精品久久久九九九孕妇| 色激情综合网站| 精品四五区| 另类TS人妖一区二区三区| 啊啊啊好大好湿| 亚洲欧洲无码97久久精品| 色色色综合| 四虎在线免费视频| 久久久久久久人妻| 玖草在线视频| 中文字幕AV片| 大地资源在线观看中文第二页| 国内成人圈中文字幕无码视频| 成人a大片在线观看| 伊人视频| 9久超碰| 东北女人的毛片| 国产成人精品网站| 青青色综合| 亚洲欧美综合网| 五十路熟女工口| 国产 日韩,欧美 自拍| 久草综合视频| 伊人91| 亚洲第一精品在线视频 | 亚洲综合夜色| 天堂在线一区二区| 久久av色| 欧美一级久久久久久久大片动画| 91丨人妻丨国产丨丝袜| 欧美97爱| 国产美女高潮| 久久精品国产亚洲妲己影视| 午夜舔阴达高潮视频免费看| 97精品综合久久| 欧美操人| 久久精品一区二区一8| 中文字幕人妻色偷偷久久皮| 久久久九九九| 欧美久久婷婷| 欧美性爱另类综合| 亚洲 自拍偷拍 欧美| 九99久久| 日日A∨| 国产一级片| 久操网线| 国产综合永久精品日韩鬼片| 欧插网站| 亚洲情色1区| 亚洲精品丝袜| 久久夜夜夜| 国产精品乱码久久久| 97超碰这里只有精品| 色综和网| 亚洲精品久久一区二区三区蜜桃臀| 吉川爱美98堂在线| 色噜噜狠狠色综合日日| 人妻嗯啊啊在线播放| 狠狠久久亚洲欧美专区| 99xav| 99re这里| 亚洲天堂男人天堂网| 欧美日韩亚洲少妇寂寞影院正在播放 | 乱人乱色一区二区三区免费| 尤物黄色在线观看网站| 久久久久白虎| 欧洲久久一二线| 亚洲人成网站7777| 黄色大片免费在线| 日韩欧视频| 激情综合婷婷| 日本理论在线| 2018色综合天天操| 96AV久久久| 伊人久久大香线综合无码| 欧美亚洲色图另类国产| 日本超碰在线国产一区| 五月天伊人| 熟女露脸激情自拍视频| 九九热九九| 日欧操屄| 无码视频黄色网战| 亚洲一二三精品久久网| 99国内熟女露脸视频| 五月天久久人妻| 91福利网在线观看| 色9999日韩国产| 大香蕉十区| 97超碰站| 怡春苑东京热| 日韩精品-原创伙伴| 亚洲97成人在线观看| 国产精品无码在线| 欧美黄色图片| 青青草好吊色| 国产中文字幕曰本毛片| 国产传媒美日韩av| 亚洲熟女综合网| 色乱二区| 天天天天天天天天综合| 精品国产乱码久久| 国产又色又爽又舒服的三级视频| 又黄又粗又硬又长又大| 欧美亚洲图片| 中文字幕在线免费观看视频| 亚洲男人的天堂网| 中文字幕精品免费一区二区| 婷婷五月天伊人| 日日干夜夜骑| 26uuu性物| 91中文精品日韩欧美在线| 天天欲望网| 无码视频黄色网战| 一级做a爰片性色毛片久久| 99热最新| 欧美黑人日韩少妇色情| 狼狼色丁香久久婷婷综合五月| 免费看污网站| 亚洲不卡三级手机播放| 国产原创自拍| 凌辱美少妇久久aV| 99操视频| 97欧美日韩精品| av婷婷色婷婷色六月| 天天日美女的B| 一级片在线观看高清无码| 六月丁操逼| 日韩欧美操逼xxx| 91美乳| 日本一区二区三区午夜观看| 色九九九| 成人无码在线超碰网| 屌妞视频久久久久久久久久久久| 97视频在线看| 性欧美体内射精| 日韩免费福利在线观看| 国产乱弄免费在线视频。| 天天射天天| 玖玖爱一区在线| 视频黄色国产一级| 乱操9999| 另类视频在线| 深夜福利黄片| 夜草欧美| 综合自拍| 亚洲人天堂| 欧美狠狠弄| 日本不卡高清视频| 国产精品对白自产拍| 99re6久热只有精品6在线直播| 亚洲少妇在线影音| 人妻少妇色综合| 国产无马视频| 园内精品自拍视频在线播放| 亚洲人妻在线精品| 污色区网站| 一级久久性爱视频| 97操B| 91超碰在线观看| 熟妇激情| AAAA级日本片免费视频| 91人妻在线视频| 日韩成人精品| 久久久久深夜无码| 亚州操操穴网| 美國A片| 亚洲欧美情色| 日本不卡二三区| 亚洲中文字幕网| 丁香婷婷五月| 天天操天天7| 久久理论字幕视频| 熟女字幕| 国产色产精品在线观看| 天天情欲宗合网| 91AV老熟女视频| 国人欧美精品一区二区| 欧美狠狠干| 97伦乱| 人妻出轨一区二区三区| 亚洲国产欧美中文永久| 国产黄片精品在线| 99热精品在线播放| 日韩免费高清大片在线| 色噜噜人妻丝袜AV资源| 九九久久九九久久| 殴美日韩m| 伊人 俄罗斯 a v| 公司1区2区3区精产精| 日本免费二区三区| 日本五区不卡| 日韩综合97P| 公司1区2区3区精产精| 精品国产乱子伦一区二区三区,精品一| 久久久精品网| 亚洲?V无码专区在线电影| 亚洲AV无码黄色强奸| 丁香六月婷婷| 欧美午夜色妇色鬼| 国产女主播视频在线观看| 天天综合欧美| 91观看 国产白丝| 好爽视频在线观看| 日韩在线性爱免费视频| 九九av| 国产福利视频精品视频| 日韩97P| 欧美精品69性爱| 涩涩涩综合| 中文字幕性感少妇av| 久久色人体| 日韩丝袜高跟制服在线观看| 九九操久久国产免费视频| 超碰在线人妻中文字幕| 在线性黄高清免费视频| 三级片大波波| 久草电影网| 澳门黄片一香蕉视频| 综合欧美日本三级| 亚洲情色图片区| 91色插| 国产AV精久久| 熟妇视频一区二区三区在线观看| 精品美女人人干| 亚洲国产成人7777| 国产亚洲色婷婷久久99精品91| 神马久久久久久久久久久久| 国产熟女无套内射| 333kkkk·亚洲com久久| 夜夜嗷嗷一区二区| 久久熟女精品不卡一区| 婷婷伊人五月| 这里只有精品久久| 91无码人妻| 国产无吗在线播放| 97电影院超碰| 九九九九九九精品| 亚洲小电影免费涩涩成人在线高清| 日日干夜夜干| 蜜汁欧美| 国产精品嫩草影院免费| 狠狠躁AV| 久久伊人影院| 91呆哥人妻| 精吧天堂| 精品亚洲国产成人精品| 日本天堂网| 99999re| 成片免费播放| 桑老女人九区| 国产AV久久久蜜爱影集| 久久AV色| 无码精品久久久天天影视| 亚洲精品欧美专业| 伊人国产成人av网站| 五月婷婷丁香六月| 九九热精品视频六| 91麻豆va国产精品| 伊人午夜福利视频| 日本色色色色色视频| 神马影院午夜福利久久久| 内射老妇BBWX0C0CK| 啪啪91| 在线综合网| 人妻夜夜爽天天爽麻豆三区网站| 我要色综合网| 99国产精品人妻人伦| 欧美少妇色图| 最新AVzaixian| 免费a v| 9色国产精品一区粉嫩 | 东京热精品97综合网| 久久AV无码AV| 午夜欧美J进J出白浆流出久久久| 国产强奸AV在线| 久久久久久性爱视频| 51国产午夜精品视频| 神马久久中文字幕| 国产精品无码久久久久2025| 狠色婷婷久久一区二区三区_| 免费看国产曰批40分钟怎么下载| 久久久111| 玖玖资源综合在线视频| 91综合天天看| 五月天婷婷基地| 神马久久久久久久| 啊啊啊啊啊好大好舒服想要| 伊人精品久久网站| 91在线丝袜| 丁香婷婷久久 | 久久久青青草| 欧美精品在线观看| 91午夜无码| 四虎影视 亚洲无码| 五月丁香综合啪啪| 另类天堂| 中国熟女网站| 亚洲五月婷婷| 日韩三级伊人| 久污| 激情小说五月天| 午夜a成v人电影| 九九人妻| 91久久久久久久久久久| 青娱乐欧美激情一区二区| 国产精品久久久久久久毛片1| 自慰白浆在线观看| 9999久久久| 91挑色欧美| 九九香蕉网| 久久精品国产AV一区二区三区| 中文字幕伊人| 久久精品亚洲婷婷| 色嗨嗨在线| 国产久久久久久| 成人熟女区| 亚洲 日韩 欧美 国产综合体| 国产亚洲日韩欧| 99超碰网| 高潮综合网| 黑丝少妇| 欧亚乱色熟女一区二区| 97香蕉网| 人妻 欧美亚洲| 美日韩一卡二卡三卡免费人妻精品| 国产精品久久久久久久毛片1| 蜜臀久久99精品久久久久| 91少妇香蕉久久精品| 99re9在线| 黑人综合色| 有码免费观看| 欧美性爱五月天| 国产精品一区二区校花| 国产精品视屏| 国产精品夜夜夜| 成人一二三区| 操逼逼中文字幕| 日韩成人大片一区二区| 久久久久久久六六| 国产欧美岛国精品一区| 青青青草伊人精品| 亚洲aV性爱| 亚洲人妻精品一区二区| 日韩欧美aⅴ综合网站发布| 九九九999久久久网站| 在线黄色污污网站| 91人妻超碰| 欧美日韩第一页| 日韩乱中文 | 欧美亚洲20p| 长长久久88视频| 欧美日韩第一页| 亚洲日韩精品一区视频在线| 91露脸熟女专区| 综合久久97| 少妇熟女一区二区三区| 日本ZZ高免费A级视频| 好屌色综合| 久草毛片电影怡| 亚洲综合113页| 啊啊啊 在线观看| 四虎AV在线观看| 色五月婷婷麻豆在| www.婷婷| 婷婷五月天小说| 色色婷婷丁香| 九九热精品在线| 99操逼| 久热九九| 另类图片五月天| 亚洲男人bt天堂| 日本在线不卡123| 亚洲最大91网| 亚洲日本男人天堂网| 按摩中文字幕| 日韩三级网址| 一区二区三区四区五区高清无码永久视频 | 超碰97亚洲区| 丝袜高跟澳门91视频| 中文一区二区| 亚洲 欧美 日本 国内 首页| 人乳av| 成人三级片一区二区三区视频| 亚洲欧洲日韩中文字幕一区| 色婷婷电影网| 99热免费| 人妻在线中出视频| 亚洲妇色| 91国产在线精品| 热热色青青草| 我想要 啊 啊 啊| 91美女视频| 欧美日韩*字幕一区| 思思热免费在线视频| 岛国片国产成人亚洲播放| 亚洲第一无码播放立川理惠| 第一高清av中文字幕| 五月丁香激情综合| 免费的av网| 9999亚洲精品| 99草精| 在线视频97| 亚洲精品免费中文字幕| 国产 日韩 欧美高清| 麻豆啪啪啪视频| 男人天堂一区二区| 美女大乳久久久久久久女人18| 欧美成人一区二区| 91白虎| 日本操逼aaaaa| 欧美激情中文字幕另类小说| 激情小说五月天| 美腿丝袜偷拍亚洲欧美| avav青青草久久夜| 久久只有精品| 全免费a敌肛交毛片免费| 五月丁香啪啪啪| 97色涩| 好涩综合| 手机在线A片| 91亚洲人电影| 狠狠躁日日躁夜夜躁A| 美女久久久久久久久久久| 欧美呦呦性爱| 日本久久精品| 密臀AV在线| 夜夜欢天天干| 久久精品毛片免费不卡| 国产精品一二三区福利| 香蕉免费一区二区三区不读| 99re99| 国产精品久久久久久片| 1956日韩精品| 欧美综合亚洲| 三级激情网站| 99国产精品人妻人伦| 超碰一区二区| 自拍偷拍第26| 亚洲综合色网| 97就爱干| 超碰国产精品无码| 日日日日日| 超碰一区二区| 欧美日产国产在线成人第一区| 丁香五月激情啪啪| 亚洲综合射| 免费视频在线一区二区不卡| 色综合久| 精品二区三四区五电影 | 亚洲成人在线资源| 91精品久久久| 日韩精品人妻中文字幕有码午| 亚洲色图8| 青娱乐国产盛宴视频| 97人人爱人人做人人乐| 亚洲男人天堂av| 色情五月丁香| 夜夜爽夜夜摸夜夜操免费视频| 中文字幕日韩电影人妻| 加勒比海色香蕉婷婷| 亚洲一区中文字幕一区| 色偷综合| 正在播放国产精品一区| 精品久久久中文字幕不| 蜜臀久久久99久久久久 | 男人高清无码一区二区| 东北女人的毛片| 天堂无码| 久久天天性久久伊人| 久区视频| 激情综合婷婷| 亚洲欧美综合网 | 无码区蜜乳| 少妇一区二区三区在线观看| 尤物视频视频官网| www.狠狠干.coom| 国产三级片在线观看| 丁香五月成人| 97超级久久| 丁香五月激情五月| 天天天肏屄肏屄肏屄欧美欧美| 久久久精品国产亚洲AV无码| 日韩无码服务区| www黄片免费看com| 夜夜骑日日| 欧美在线干| 亚洲色电影在线| 熟妇熟女视频一区二区三区| 一区二区不卡视| 任我爽视频在线观看| 天天草天天日| 在线视频五十市| 综合免费无码中文| 亚洲丝袜制服国产91_国语字幕免费观看完整版下载第5集_ | 91国产伊人大香蕉| 欧美极品少妇交| 中文字幕精品区先锋资源| 成人精品久久久午夜福利| 九t超碰| 男人的天堂三级| 色香伊人| 综合网欧美在线| 精品78| 911粉嫩人妻| 色原狠狠天天天| 亚州伊人色综台| 自拍偷拍第26| 欧美在线 亚洲| a在线观看| 欧美色狠| 啊啊啊好舒服视频在线观看| 女人喷水视频在线观看| 97亚洲自在精品在线观看| 淮穴色AV| 99老司机精品视频在线观看| 成人久久久精品| 大香交伊人网| 国产亚洲性生活视频播放| 夜色97| 亚洲av在线免费观看| 精品国产三级av韩国在线| 九九自拍伦理| 丁香五月色情| 91色图片| 亚洲无码?第一页| 久久伊人影院| 1二区9| 欧美操人| 国产精品露脸在线观看| 国产少妇内射| 淫色网综合| 看黄片视频免费| 超碰91在线| 97超碰人操| 青青青操| 亚洲 欧美 手机在线观看| 搡老女人老91妇女老熟女| 一本久久精品中文字| 人妻久久久久久久久久久久久久久 | 久久黄色视频一区二区三区| 色狠狠一区二区三区香蕉| 欧美熟女激情| 天天插天天操| ,成人免费啪啪视频| 日韩91网| 国产丰满少妇久久久精品影院| 亚洲第一综合| blacked精品一区国产| 好属操| 18禁久久| 素颜老阿姨乱情色| 91超碰人人| 色吧五月| 亚洲乱码国产乱码精网站| 亚洲国产另类在线中文| 亚洲清纯综合| 男人精品天堂一区| 午夜福利久久久噜久噜久久综合| 人人考人人摸人人干| 91av一区二区在线观看| 久久久久久久97| 精品高清牛人盗摄一区二区三区中文字幕A片免费在线观看 | 日本天堂网| 激情六月婷婷| 黄色视频特级毛片| 涩涩这里只有精品视频| 91夜色| 人人操人人肉久久精品| 欧美草草| 欧美 亚洲 综合 制服 另类| 超碰 另类 欧美| 亚洲一区中文字幕久久,果冻传媒一区二区天美传媒 | 亚洲。天堂。日本在线观看| AV老汉| 亚洲精品久久久久久久久豆丁网| 九九精品热| 91GD.COM| 亚洲最新a在线观看| 亚洲一区二区三区中文字幕| 老子午夜伦不卡影院| 熟女探花啪啪| 欧美色网| 懂色aV一区二区天美传媒| 精精品人妻一区二区三区| 四虎免费在线播放| 伊人网一本| 天天影视之亚洲综合网| 在线观看午夜婷婷久久久久清性观看| 国产污视频麻豆传媒一区二区| 久久久久久久久久久久久9999| 青青国产精品在线| 欧美性天天影视| 中文字幕 码 自拍 视频 区| 婷婷在线视频| 色色婷婷五月天| 91日韩在线| 天天色综合图片| 久草成人福利导航| 91性网| 婷婷激情四射| 91美女小视频| 麻豆久久精品亚洲精品88 | 青青青艹在线视频| 蘋果手機免費看成人Av| 五月天加勒比啪| 啊啊啊啊好大好硬啊啊啊啊啊 | 欧美在线伊人色| 一及黄久一点| 精品人妻一区春色| 欧美在线色| 日韩射图| 免费视频一二三区| a片自拍直播视频| 香蕉黄色一级视频| 国产精品久久99日日| 91操人| 婷婷五月天伊人| 五月天春色激情网| 夜夜騷av、一區二區| 欧美日韩国产人人| 一本色道久久综合亚洲二区三区| 婷婷激情丁香| 国产无码成人无码| 亚洲一区二区久久久久| 无码聚合| 啊啊啊啊一区| 天天做天天爱天天爽AV| 亚洲性猛| 超碰久超碰久| 台湾一区国产高清在线| 欧美日韩在线国产在线| 中文字幕在线免费观看视频| 欧美性猛交美女自慰91| 97色视频在线| rivers-china.com| 婷婷超| 少妇高潮对白在线观看| 色五月综合| 嗯阿好爽好紧| 二级毛片| 99国产精品视频尤物| 亚洲免费人妻在| 日韩人妻少妇中文字幕|