With the rise of traffic realization, more and more advertising SDKS are pouring in. In addition to Byte pangolin, there are Tencent’s Uquanhui, Baidu’s advertising alliance, and others, such as AdView and Wandushiji, have gradually retired from the stage of history.
Based on com.pangle.cn: ADS-SDK :3.6.1.8, this article will focus on the integration process of pangolin Android SDK access documentation and the holes in the adaptation process.
Basic integration
Add a reference to Maven in the build.gradle file in the project directory
allprojects {
repositories {
maven { url 'https://artifact.bytedance.com/repository/pangle'}
}
}
Copy the code
Add SDK dependencies to the build.gradle file of the main Module
Dependencies {implementation 'com.pange.cn: adS-SDK :3.6.1.8'}Copy the code
Add permissions in androidManifest.xml
<! - necessary permissions - > < USES - permission android: name = "android. Permission. INTERNET" / > <! -- Optional permission --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.GET_TASKS"/> <! -- Optional, Pangolin provides two ways to report a user's location: "Get location permission" and "Don't give location permission, developers pass in location parameters." Either way is optional, adding location permission or parameters will help to place location-based ads --> <! -- Please note: No matter how the location is provided to pangolin users, it is required to declare to the users that the location permission will be applied to pangolin advertising. Pangolin is not mandatory for geography information - > < USES - permission android: name = "android. Permission. ACCESS_FINE_LOCATION" / > <! --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <! -- Permissions used in demo scenarios, Not necessary - > < USES - permission android: name = "android. Permission. RECEIVE_USER_PRESENT" / > < USES - the permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <! -- Pangolin 3400 added: It is recommended to add the "query_all_package" permission. Pangolin will use this permission to determine whether the application corresponding to the advertisement is installed on the user's app on Android R system, so as to avoid the wrong advertisement and improve the user's advertising experience. If you want to add this permission, you need to declare it in your user privacy document! --> <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>Copy the code
Note: The Pangolin SDK is not mandatory to obtain the above permissions, and the SDK can run normally even without obtaining optional permissions; Obtaining the above permission will help Pangolin optimize advertising accuracy and users’ interactive experience, and improve eCPM.
It is suggested to call the method provided by SDK at an appropriate time before advertising request, and obtain the permission in the statement under the condition that the user can authorize, so as to improve the efficiency of advertising realization
/ / TTAdManager methods on the interface, the context can be the Activity or Application void requestPermissionIfNecessary context (context).Copy the code
Add the provider to androidManifest.xml
Note:
- The provider needs to be properly configured in the manifest file in order not to affect the use of downloadable advertising regardless of the stage of the APP
- To ensure that advertising conversion and revenue are not affected, make sure to configure XXX.ttMultiProvider in the manifest file
If your application needs to run in android 7.0 or above, please add the following code to the AndroidManifest:
<provider
android:name="com.bytedance.sdk.openadsdk.TTFileProvider"
android:authorities="${applicationId}.TTFileProvider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
Copy the code
In the res/ XML directory, create a new XML file file_paths and add the following code to the file:
<? The XML version = "1.0" encoding = "utf-8"? > <paths xmlns:android="http://schemas.android.com/apk/res/android"> <! -- Set path="." --> <external-path name="tt_external_root" path="." /> <external-path name="tt_external_download" path="Download" /> <external-files-path name="tt_external_files_download" path="Download" /> <files-path name="tt_internal_file_download" path="Download" /> <cache-path name="tt_internal_cache_download" path="Download" /> </paths>Copy the code
Note: Single or multiple processes must be configured
<provider
android:name="com.bytedance.sdk.openadsdk.multipro.TTMultiProvider"
android:authorities="${applicationId}.TTMultiProvider"
android:exported="false" />
Copy the code
Runtime Environment Configuration
This SDK runs on Android4.0 (API Level 14) and above. < uses-SDK android:minSdkVersion=”14″ android:targetSdkVersion=”24″ /> < uses-SDK android:minSdkVersion=”14″ Android :targetSdkVersion=”24″ You have obtained all the permissions required by the SDK. Otherwise, some features of the SDK may be limited
Code obfuscation setting
If you need to obfuscate code with ProGuard, make sure you don’t obfuscate the SDK code. Add the following configuration to the end of the proGuard.cfg file (or other obfuscated file) :
-keep class com.bytedance.sdk.openadsdk.** { *; } -keep public interface com.bytedance.sdk.openadsdk.downloadnew.** {*; } -keep class com.pgl.sys.ces.** {*; } -keep class com.bytedance.embed_dr.** {*; } -keep class com.bytedance.embedapplog.** {*; }Copy the code
Note: Confusing the SDK code can cause ads to fail to display or other exceptions. Avoid confusing the SDK code as much as possible
SDK Support architecture
Note: The SO files used in the SDK support five architectures: x86,x86_64, Armeabi, Armeabi-V7A, ARM64-V8A. If your application supports more than one of these five architectures, use abiFilters in build.gradle to select the supported architecture. As follows:
NDK {// set the supported SO library architecture (abiFilters 'armeabi-v7a', 'arm64-v8a', x86', x86_64', 'armeabi');Copy the code
The SDK initialization
Note:
- The Pangolin SDK needs to be initialized in the main thread
- Multi-process involvement
WebView
Users who want to use their own data path can call this before the SDK is initializedWebView.setDataDirectorySuffix()
- Currently, the SDK supports multiple processes. If it is clear that a process will not use the AD SDK, you can only initialize the AD SDK for a specific process
/** * We can use a singleton to hold the TTAdManager instance, */ class TTAdManagerHolder private constructor(){companion Object {private Val instance: TTAdManagerHolder by lazy(mode = LazyThreadSafetyMode.SYNCHRONIZED) { TTAdManagerHolder() } @JvmStatic fun get() : TTAdManagerHolder { return instance } @JvmStatic fun getTTAdManager() : TTAdManager? { if (! Ttadsdk.isinitsuccess ()) {return null} return ttadSDk.getAdManager ()}} For details, see the access document and pangolin platform description // pangolin SDK initialization // it is strongly recommended to call the Application#onCreate() method in the corresponding application to avoid null content fun doInit(context: Context) {/// the ttadSDk.isinitSuccess () parameter is found to be invalid after successful initialization or false? Alog. I (" Pangolin SDK initialization result ", ttadsdk.isinitSuccess ()); AppData.get().querySystemConfig()? .tt_app_id? .let { TTAdSdk.init(context,buildConfig(context,it),object :TTAdSdk.InitCallback{ override fun success() { Alog. I (" Pangolin SDK initialized successfully ", ttadsdk.isinitSuccess (), ttadSDk.getAdManager ().sdkversion); LiveEventBus.get<TaskEventBean>(DataTag.tt_sdk_init_result) .post(TaskEventBean(key = 0)) } override fun fail(p0: Int, p1: String?) {alog. I (" pangolin SDK failed to initialize ",p0,p1); LiveEventBus.get<TaskEventBean>(DataTag.tt_sdk_init_result) .post(TaskEventBean(key = p0,value = p1)) } }) } } private fun buildConfig(context: Context,appId:String): TTAdConfig { return TTAdConfig.Builder() .appId(appId) .appName(DataUtils.getString(R.string.app_name)) .paid(true) /*.customController(object: TTCustomController() {Override Fun isCanUseLocation(): Boolean { return false } override fun isCanUsePhoneState(): Boolean { return false } override fun isCanUseWifiState(): Boolean { return false } override fun isCanUseWriteExternal(): Boolean {return false}})*/.usetExtuReview (true) Can use TextureView. AllowShowNotify (true) / / whether to allow the SDK show notification bar tip / /. AllowShowPageWhenScreenLock (true) / / under the lock screen pangolin SDK won't out of the landing page, Debug (buildconfig.debug) // This API is deprecated and calls have no effect. When launching to remove this call. DirectDownloadNetworkType (TTAdConstant.NET and TTAdConstant.NET WORK_STATE_WIFI WORK_STATE_3G, TTAdConstant.NETWORK_STATE_4G) // Allow direct download of the network state collection. SupportMultiProcess (false) // whether to support multiple processes. NeedClearTaskReset () .httpStack(TTAdStack())//.httpStack(new MyOkStack3())// Custom network library. .build() } }Copy the code
It is then called in Application#onCreate()
TTAdManagerHolder.get().doInit(it)
Copy the code
Initial configuration parameters
public static class TTAdConfig.Builder { private String mAppId; // This parameter is mandatory. Set the AppId of the application. Private String mAppName; // This parameter is mandatory. Set the application name. Private Boolean mIsPaid = false; // This parameter is optional. The value can be true for an accounting user or false for a non-accounting user. The default value is false. Private String mKeywords; private String mKeywords; // Set the keyword list of user portrait to no more than 1000 characters ** as an optional parameter. Private String mData; private String mData; private String mData; ** private int mTitleBarTheme = ttadconstant.title_bar_theme_light; // Set additional user information to no more than 1000 characters. TTAdConstant#TITLE_BAR_THEME_LIGHT private Boolean mAllowShowNotify = true; // This parameter is optional to set whether to allow SDK pop-up notifications. The value can be true or false. Private Boolean mIsDebug = false; // This parameter is optional. Debug Displays debugging information. The value can be true to enable or false to disable. The default false close private int [] mDirectDownloadNetworkType; Private Boolean mIsUseTextureView = false; private Boolean mIsUseTextureView = false; private Boolean mIsUseTextureView = false; // An optional parameter that sets whether to use texture to play the video: true uses texture, false does not. Private Boolean mIsSupportMultiProcess = false; // This parameter is optional. The value can be "true" or "false". Default is false. Private IHttpStack mHttpStack is not supported. Private Boolean mIsAsyncInit = false; // The default value is urLConnection. // Whether to initialize the SDK asynchronously. If this is enabled, the initialization time can be reduced. // Optional parameter, you can set the privacy information control switch}Copy the code
Privacy information control switch
Public Abstract class TTCustomController {/** * Whether to allow the SDK to use geo-location information ** @return True, false, false. Public Boolean isCanUseLocation() {return true; } /** * When isCanUseLocation=false, you can pass in the location information, * * @return */ public TTLocation getTTLocation() {return null; } /** * Whether to allow SDK to actively use the phone hardware parameters, such as: imei ** @return true: yes, false: no. Public Boolean isCanUsePhoneState() {return true; } /** * pass in iMEI when isCanUsePhoneState=false, Public String getDevImei() {return null; } /** * Whether the SDK is allowed to use the ACCESS_WIFI_STATE permission ** @return True yes, false no. Public Boolean isCanUseWifiState() {return true; } /** * Whether to allow the SDK to use the WRITE_EXTERNAL_STORAGE permission ** @return True Yes, false no. Public Boolean isCanUseWriteExternal() {return true; } /** * developer can pass oaid ** @return oaid */ public String getDevOaid(); }}Copy the code
Note:
- So before we rewrite getTTLocation() we need to set the isCanUseLocation()
- We need to set isCanUsePhoneState() before we can override getDevImei()
TTAdManger Indicates the interface
Public interface TTAdManager {// Create object TTAdNative using activity TTAdNative createAdNative(Context Context); / / some models need to take the initiative to apply for permission, such as READ_PHONE_STATE permission to void requestPermissionIfNecessary (Context Context). // Try to display the "Prompt to Install app" dialog box on exit, return the value: True display dialog, false does not display the dialog box Boolean tryShowInstallDialogWhenExit (Context Context, final ExitInstallListener listener); String getSDKVersion(); String getSDKVersion(); // Set the theme type. 0: normal mode; // Set the theme type. 1: Night mode; Default is 0; Void setThemeStatus(int themeStatus); void setThemeStatus(int themeStatus); // Get the current theme type int themeStatus (); }Copy the code
SDK import points to note:
Keep TTAdManagerHolder in singleton mode;
2. When the SDK is initialized multiple times by a single process, the first initial setting information is the main one;
3. AppId is a 7-digit word generated by the wearable application on the platform;
4. Black screen after loading any type of video advertisement can be tried to solve as follows:
Whether to add <uses-permission android:name=" android.permission-wake_lock "> try to play the video using the TextureView controlCopy the code
5. If appName is not empty, it is recommended that the appName be the same as that of the application created on the platform
6, directDownloadNetworkType configuration:
It can be configured according to specific product requirements. The network set in the method is the network that allows direct download. If the user needs to download from any network, there will be confirmation pop-ups, and you can write blank (not null) directly in the method
7. SupportMultiProcess
This must be changed to false if the project is single-process and true if the project is multi-process. More than if each process needs to show in the process of advertising should be carried out each process initialization of the SDK If your application needs to support multiple processes, please be sure to set the TTAdConfig. SupportMultiProcess (true). Confirmation of app multi-process support judgment methods: A, pangolin SDK initialization B, Pangolin advertisement acquisition C, pangolin advertisement display the call of the three key points in different processes is multi-process, otherwise it is a single process, if not necessary, try not to use multi-process switch, the efficiency of multi-process is not as high as that of single process
8. Configure the provider
The provider required by pangolin must be configured in either single process or multiple processes. No matter the platform application is in the test state or the official state, the provider needs to be configured. To ensure that the transformation and revenue of ads are not affected, please be sure to configure XXX.ttMultiProvider in the manifest file
9, if your application also confuses resources (such as andResGuard), please do not confuse any of the pangolin resources, in case the resources can not be found and crash.
The resources in the whitelist. TXT whiteList in the COMPRESSED SDK file do not support confusion. The developer needs to re-check the whiteList content during the SDK update iteration
Opening the advertising
Note:
- View: width = width; Height must be >=75% screen height, otherwise charging will be affected.
- Supported AD size: The size of the open screen AD is the size set when the developer requests the AD. It is recommended to set the request size to be consistent with the size of the display area to avoid material deformation.
- SDK render open screen ads: default; Template rendering open screen advertisement: whitelist, need to apply for open.
- There is no difference in the request mode between template rendered open screen and SDK rendered open screen advertisement, only the difference in the request parameters. This is required in the open screen request method for template rendering
setExpressViewAcceptedSize
Parameter, the SDK does not need to set this parameter to render open screen advertisements.
private val expressViewWidth by lazy { UIUtils.getScreenWidthDp(getThis()) } private val expressViewHeight by lazy { Uiutils.getheight (getThis())} uiutils.getheight (getThis())} uiUtils.getheight (getThis())} And only the template rendering code bit ID is used, Val adSlot = adslot.builder ().setCodeId() //.setUserId () // UserID, optional parameter.setSupportDeeplink (true) .setimageAcceptedSize (ExpressViewWidth.toint (), expressViewHeight.toint ()).build() To request correction of advertising make rendering processing TTAdManagerHolder. GetTTAdManager ()? .createAdNative(this)? .loadSplashAd(adSlot, object : SplashAdListener { @MainThread override fun onError(code: Int, message: String?) {alog. I (" open error", code,message); } @mainThread Override fun onTimeout() {alog. I (" open AD load timeout "); } @MainThread override fun onSplashAdLoad(ad: TTSplashAd?) {// Get SplashView viewData? .flContainer? .let { if (! isFinishing){ it.removeAllViews() if (ad? .splashView? .parent ! =null){ (ad.splashView.parent as ViewGroup).removeView(ad.splashView) } it.addView(ad? .splashView)}} // Set the splashView interactive listener AD? .setSplashInteractionListener(object : TTSplashAd.AdInteractionListener { override fun onAdClicked(view: View? , type: Int) {alog. I (" open AD click "); } override fun onAdShow(view: View? , type: Int) {alog. I (" open screen AD display "); } Override fun onAdSkip() {alog. I (" onAdSkip "); } Override fun onAdTimeOver() {alog. I (" open AD countdown is over "); } //Splash: Open the AD interaction type in the browser (normal type); .interactionType == TTAdConstant.INTERACTION_TYPE_DOWNLOAD) { ad.setDownloadListener(TTAppDownloadListenerImpl()) } } }, 3500).Copy the code
Which TTAppDownloadListenerImpl () for the user to click on the download after the callback:
class TTAppDownloadListenerImpl: TTAppDownloadListener { override fun onIdle() { // ALog.i("onIdle"); } override fun onDownloadActive(p0: Long, p1: Long, p2: String? , p3: String?) { // ALog.i("onDownloadActive",p0,p1,p2,p3); } override fun onDownloadPaused(p0: Long, p1: Long, p2: String? , p3: String?) { // ALog.i("onDownloadPaused",p0,p1,p2,p3); } override fun onDownloadFailed(p0: Long, p1: Long, p2: String? , p3: String?) { // ALog.i("onDownloadFailed",p0,p1,p2,p3); } override fun onDownloadFinished(p0: Long, p1: String? , p2: String?) { // ALog.i("onDownloadFinished",p0,p1,p2); } override fun onInstalled(p0: String? , p1: String?) { // ALog.i("onDownloadFinished",p0,p1); }}Copy the code
Pay attention to the screen advertising:
1, template rendering method of opening the request to set unit dp setExpressViewAcceptedSize parameters. The unit of the setImageAcceptedSize parameter is px for the non-template rendering open screen request method. Remember not to use errors
2. It is recommended that the loading timeout period of open screen advertisements be greater than 3500ms to ensure the display rate of advertisements can be open screen experience to the maximum extent. In the example, 3500ms is set
3. In order to maximize revenue, all open screen ads should be requested in real time and not cached.
4, developers to onError(), onTimeout(), onAdSkip(), onAdTimeOver() callback and TTSplashAd AD is null developers do jump home page processing, jump after the open screen control view removed.
5. Developers need to make a mark in onStop() in the Activity of opening the screen, and do the logical processing of jumping to the main page in onResume(), and remove the view on the control of opening the screen after jumping. Such as:
@override protected void onResume() {if (mForceGoMain) {goToMainActivity(); } super.onResume(); } @Override protected void onStop() { super.onStop(); mForceGoMain = true; }Copy the code
6. If you want to add your own logo at the bottom, you need to reduce the display area of the screen advertisement. At this time, when you request, fill in the width and height after cutting, that is, the request size is screen width * (screen height – LOGO height).
Incentive video
Incentive video advertising requires users to actively choose to watch, and the effect of advertising is that users are rewarded after watching the video advertisement. Usage scenarios include but are not limited to:
- In-game gold for watching video ads in games and other apps;
- Integration application access;
Note:
- Supported AD sizes: full-screen landscape (16:9 aspect ratio), full-screen portrait (9:16 aspect ratio). Android does not support gravity rotation.
- There is no difference in the way of advertisement request between template rendering and SDK rendering inspiring video, only the difference in request parameters. Template rendering needs to be set in the incentive video request method
setExpressViewAcceptedSize
Parameter, the value must be greater than 0. - Template rendering code bits
setExpressViewAcceptedSize
Required. Do not upload the SDK template rendering code bit ID. - To ensure the smooth playback of advertising video suggestions in
onRewardVideoCached
After the callback is loaded, it is called in the main threadshowRewardVideoAd
Methods To display advertisements. Set the AD object to NULL immediately after displaying the AD
var mttRewardVideoAd: TTRewardVideoAd? = null // Create template val adSlot = adslot.builder ().setCodeId().setSupportDeeplink (true).setrewardName (" gold coin ") SetRewardAmount (3). / / the number of reward setExpressViewAcceptedSize (500 f and 500 f) / / template ads need to set expectations personalized template, the size of the unit of dp, incentive video scene, //.setUserID(datatag.ttad_user_id) // UserID is mandatory. SetMediaExtra ("media_extra") // Additional parameter, Optional.setOrientation(ttadconstant. VERTICAL) // Mandatory: TTAdConstant. HORIZONTAL or TTAdConstant. VERTICAL. The build () / / request advertising mTTAdNative loadRewardVideoAd (adSlot, object: TTAdNative.RewardVideoAdListener { override fun onError(code: Int, message: String) { ALog.e("onError",code,message); } // After the video AD is loaded, the video resource is cached to the local callback, after this callback, the local video is played, smooth without blocking. override fun onRewardVideoCached() { ALog.e("onRewardVideoCached"); // mIsLoaded = true mttRewardVideoAd? .showRewardVideoAd(getThis(), TTAdConstant.RitScenes.CUSTOMIZE_SCENES, "Scenes_test ") mttRewardVideoAd = null} // After the video advertisement material is loaded, such as the video URL, the online video can be played. The network is bad, and the loading buffer may occur, affecting the experience. override fun onRewardVideoAdLoad(ad: TTRewardVideoAd) { ALog.e( "onRewardVideoAdLoad",ad.interactionType) // mIsLoaded = false mttRewardVideoAd = ad ad.setRewardAdInteractionListener(object : TTRewardVideoAd.RewardAdInteractionListener { override fun onAdShow() { ALog.d("onAdShow") } override fun OnAdVideoBarClick () {alog.d (" onAdVideoBarClick")} Override fun onAdClose() {alog.d ("onAdClose")} onAdClose() {alog.d ("onAdClose") override fun onVideoComplete() { ALog.d( "onVideoComplete") } override fun onVideoError() { ALog.e("onVideoError") } Override Fun onRewardVerify(rewardVerify: rewardAmount: rewardVerify: rewardVerify: rewardVerify) Boolean, rewardAmount: Int, rewardName: String, errorCode: Int, errorMsg: String) { ALog.e("onRewardVerify",rewardVerify,rewardAmount,rewardName,errorCode,errorMsg) } override fun onSkippedVideo() { ALog.i("onSkippedVideo"); } }) if (mttRewardVideoAd? .interactionType == TTAdConstant.INTERACTION_TYPE_DOWNLOAD) { mttRewardVideoAd!! .setDownloadListener(TTAppDownloadListenerImpl()) } } }) override fun onDestroy() { super.onDestroy() // Clear the AD object in the Activity onDestroy method mttRewardVideoAd = null}Copy the code
Full screen video
Full-screen video AD. The effect of this AD is to play a full-screen video. The video can be skipped after a certain period of time.
Note:
- Supported AD sizes: full-screen landscape (16:9 aspect ratio), full-screen portrait (9:16 aspect ratio). Android does not support gravity rotation.
- There is no difference between template rendering full-screen and SDK rendering full-screen AD request, only the difference in request parameters. The template rendering full-screen video request method needs to be set
setExpressViewAcceptedSize
The value must be greater than 0. - Template rendering code bits
setExpressViewAcceptedSize
Required. Do not upload the SDK template rendering code bit ID. - Smooth video material for advertising is recommended in
onFullScreenVideoCached
The method is called in the main thread after it has loadedshowFullScreenVideoAd
Methods To display advertisements. Set the AD object to NULL immediately after displaying the AD.
// Create a TTAdNative object, CreateAdNative (Context Context) Context needs to be passed in the Activity object TTAdNative mTTAdNative = TTAdSdk.getAdManager().createAdNative(this); AdSlot AdSlot = new Adslot.Builder ().setCodeid (codeId) AdSlot AdSlot = new Adslot.Builder ().setCodeid (codeId) }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} The template rendering code bits. Do not use setExpressViewAcceptedSize (500500). SetSupportDeepLink (true). SetOrientation (orientation) / / required parameters, Expect the video to be played in the direction ttadconstant.horizontal or ttadconstant.vertical.build (); mTTAdNative.loadFullScreenVideoAd(adSlot, New TTAdNative. FullScreenVideoAdListener () {/ / request advertising failure @ Override public void onError (int code, @override public void onFullScreenVideoAdLoad(TTFullScreenVideoAd) {} @override public void onFullScreenVideoCached() {if (mttFullVideoAd! = null&&mIsLoaded) {// Display ads, Introduced into display advertising and scene mttFullVideoAd. ShowFullScreenVideoAd (FullScreenVideoActivity. This, TTAdConstant. RitScenes. GAME_GIFT_BONUS, null); mttFullVideoAd = null; } else {TToast. Show (FullScreenVideoActivity. This, "please load the advertising"); }}); @override protected void onDestroy() {super.onDestroy(); // Clear the AD object in the Activity's onDestroy method. if (mttFullVideoAd ! = null) { mttFullVideoAd = null; }}Copy the code