一个WP7应用中使用了Google AdMob 控件 (客户要求使用google ad,若无要求,强烈建议使用MS的 Ad控件)。下面是使用AdMob 的WP7控件遇到的问题:
1. 墙 - 国内目前无法显示ad内容。如需测试,请用vpn电脑翻墙,手机连接电脑,测试显示效果
2. 严重的crash:
使用目前最新的4.0.4版本依然有2个严重的异常:
异常1: 常在有ad的页面加载时就抛出
System.SystemException was unhandled
Message=An unknown error has occurred. Error: 80020101.
StackTrace:
at Microsoft.Phone.Controls.NativeMethods.ValidateHResult(Int32 hr)
at Microsoft.Phone.Controls.WebBrowserInterop.InvokeScript(String scriptName, String[] args)
at Microsoft.Phone.Controls.WebBrowser.InvokeScript(String scriptName, String[] args)
at Google.AdMob.Ads.WindowsPhone7.WPF.DisplayAdBase.<>c__DisplayClass36.<RunScripts>b__34()
at System.Reflection.RuntimeMethodInfo.InternalInvoke(RuntimeMethodInfo rtmi, Object obj, BindingFlags invokeAttr, Binder binder, Object parameters, CultureInfo culture, Boolean isBinderDefault, Assembly caller, Boolean verifyAccess, StackCrawlMark& stackMark)
at System.Reflection.RuntimeMethodInfo.InternalInvoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, StackCrawlMark& stackMark)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at System.Delegate.DynamicInvokeOne(Object[] args)
at System.MulticastDelegate.DynamicInvokeImpl(Object[] args)
at System.Delegate.DynamicInvoke(Object[] args)
at System.Windows.Threading.DispatcherOperation.Invoke()
at System.Windows.Threading.Dispatcher.Dispatch(DispatcherPriority priority)
at System.Windows.Threading.Dispatcher.OnInvoke(Object context)
at System.Windows.Hosting.CallbackCookie.Invoke(Object[] args)
at System.Windows.Hosting.DelegateWrapper.InternalInvoke(Object[] args)
at System.Windows.RuntimeHost.ManagedHost.InvokeDelegate(IntPtr pHandle, Int32 nParamCount, ScriptParam[] pParams, ScriptParam& pResult)
异常2:少见。在离开应用,按Back键返回时偶有遇到
System.NullReferenceException was unhandled
Message=NullReferenceException
StackTrace:
at Google.AdMob.Ads.WindowsPhone7.Support.DownloadHelper.<>c__DisplayClass1.<Run>b__0(IAsyncResult AsyncResult)
at System.Net.Browser.ClientHttpWebRequest.<>c__DisplayClassa.<InvokeGetResponseCallback>b__8(Object state2)
at System.Threading.ThreadPool.WorkItem.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadPool.WorkItem.doWork(Object o)
at System.Threading.Timer.ring()
解决办法:无 - 需要google 修复控件存在的问题
所谓的"workaround": 在Application_UnhandledException中处理这些异常
private
void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
{if (e.ExceptionObject.Message == "An unknown error has occurred. Error: 80020101.") //google's ad control crash, ignore this{e.Handled = true;
}if (e.ExceptionObject.StackTrace.IndexOf("Google") >= 0){e.Handled = true; //ignore google's ad control crash}else
{#if
DEBUG
MessageBox.Show(e.ExceptionObject.ToString());
#else
MessageBox.Show("oops, an error occurred");#endif
e.Handled = true;
}if (System.Diagnostics.Debugger.IsAttached){// An unhandled exception has occurred; break into the debugger
System.Diagnostics.Debugger.Break();
}}参考:https://groups.google.com/forum/#!topic/google-admob-ads-sdk/aI_YSr0QX-I
3. 控件尺寸: 如果其他条件正常但是ad无法显示,可能是尺寸问题导致。控件尺寸应为480x75
MS ad control也有同样的尺寸要求: 480x80
4.前景/背景: ad控件前景色总是使用系统theme当前的前景色,例如在light theme中,前景色总是黑色,设置Foreground属性无效。而且该控件背景色为透明,这就意味着在light theme下如果应用的背景色较深,基本ad上的文字很难看清 - 可能导致应用审核不通过。
较好的方法是动态设置ad控件的背景:
<StackPanel Width="480" Height="75" x:Name="adContainer"> <google:BannerAd AdReceived="BannerAd_AdReceived" xmlns:google="clr-namespace:Google.AdMob.Ads.WindowsPhone7.WPF;assembly=Google.AdMob.Ads.WindowsPhone7" AdUnitID=""/> </StackPanel>
参考: http://msdn.microsoft.com/en-us/library/ff769552(VS.92).aspx#BKMK_BrushResourcesprivate void BannerAd_AdReceived(object sender, RoutedEventArgs e) { //ad bar foreground always uses the foreground of phone's current theme, so set background to make text readable adContainer.Background = App.Current.Resources["PhoneBackgroundBrush"] as Brush; }
5. 性能:此控件性能难令人满意,加载时会影响页面加载速度。
来自google的性能测试及注意:
In Emulator--------------------------------------------- Initial Startup:1 - 1.5 seconds
General UI Lagginess:0.1 - 0.2 seconds
Ad Refreshing:0.2 - 0.3 seconds
Removing Ad and Recreating:0.3 - 0.4 seconds
On Device--------------------------------------------- Initial Startup:0.5 - 1.0 seconds
General UI Lagginess:0.02 - 0.05 seconds
Ad Refreshing:0.06 - 0.10 seconds
Removing Ad and Recreating:0.2 - 0.3 seconds
Notes--------------------------------------------- Initial Startup:This is largely due to controls that need to be loaded. These are loaded when the ad control is first put in the visual tree, regardless of IsEnabled setting.
General UI Lagginess:Determined by running a DispatchTimer with an interval of one millisecond which updates the display
Ad Refreshing:On the emulator this is usually lost in the general UI framerate
Removing Ad and Recreating:This is not preferred as there are unwanted side effects
We use the WebBrowser control as a script engine. Unfortunately this seems to be the cause of the lag as it requires scripts be run on the UI thread (as well as the major side effect when recreating an ad - stealing input focus). We're looking for alternatives to using the WebBrowser control for scripting, but there aren't any straightforward answers.
We do recognize this and are working on it though. In the meantime, you'll get the best performance if you avoid destroying and recreating the ad control.