@24jieqi/react-native-brayant-ad 0.1.24 → 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/README.md +321 -3
  2. package/android/src/main/java/com/brayantad/AdManager.java +68 -0
  3. package/android/src/main/java/com/brayantad/BrayantAdPackage.java +2 -0
  4. package/android/src/main/java/com/brayantad/dy/DyADCore.java +9 -0
  5. package/android/src/main/java/com/brayantad/dy/banner/BannerAdModule.java +175 -0
  6. package/android/src/main/java/com/brayantad/dy/banner/view/BannerAdView.java +11 -0
  7. package/android/src/main/java/com/brayantad/dy/splash/SplashAdModule.java +155 -0
  8. package/android/src/main/java/com/brayantad/dy/splash/activity/SplashActivity.java +20 -5
  9. package/lib/commonjs/dy/api/AdManager.js +15 -1
  10. package/lib/commonjs/dy/api/AdManager.js.map +1 -1
  11. package/lib/commonjs/dy/api/SplashAd.js +29 -1
  12. package/lib/commonjs/dy/api/SplashAd.js.map +1 -1
  13. package/lib/commonjs/index.js +24 -0
  14. package/lib/commonjs/index.js.map +1 -1
  15. package/lib/module/dy/api/AdManager.js +14 -1
  16. package/lib/module/dy/api/AdManager.js.map +1 -1
  17. package/lib/module/dy/api/SplashAd.js +26 -1
  18. package/lib/module/dy/api/SplashAd.js.map +1 -1
  19. package/lib/module/index.js +3 -3
  20. package/lib/module/index.js.map +1 -1
  21. package/lib/typescript/src/dy/api/AdManager.d.ts +8 -1
  22. package/lib/typescript/src/dy/api/AdManager.d.ts.map +1 -1
  23. package/lib/typescript/src/dy/api/SplashAd.d.ts +30 -1
  24. package/lib/typescript/src/dy/api/SplashAd.d.ts.map +1 -1
  25. package/lib/typescript/src/index.d.ts +3 -3
  26. package/lib/typescript/src/index.d.ts.map +1 -1
  27. package/package.json +1 -1
  28. package/src/dy/api/AdManager.ts +14 -1
  29. package/src/dy/api/SplashAd.ts +49 -1
  30. package/src/index.tsx +16 -2
package/README.md CHANGED
@@ -98,9 +98,47 @@ EmuAnim = 'default' | 'none' | 'catalyst' | 'slide' | 'fade';
98
98
  | codeid | 广告位id | string | - | 是 |
99
99
  | anim | 广告进入方式 | EmuAnim | default | 否 |
100
100
 
101
+ ### preloadSplashAd (Android 推荐)
102
+
103
+ **Android 端推荐使用预加载方式,可避免启动页结束后出现白屏。**
104
+
105
+ 在应用启动时(init 之后)预加载开屏广告,展示时直接使用已加载的广告。
106
+
107
+ ```ts
108
+ // 预加载开屏广告
109
+ await preloadSplashAd({ codeid: 'your_code_id' });
110
+
111
+ // 展示广告(使用预加载的广告,无白屏)
112
+ const splashAd = dyLoadSplashAd({ codeid: 'your_code_id' });
113
+ ```
114
+
115
+ | 参数 | 说明 | 类型 | 默认值 | 是否必填 |
116
+ | ------ | -------- | ------ | ------ | -------- |
117
+ | codeid | 广告位id | string | - | 是 |
118
+
119
+ ### hasPreloadedSplashAd
120
+
121
+ 检查是否有预加载的广告可用(Android)。
122
+
123
+ ```ts
124
+ const { hasAd, status } = await hasPreloadedSplashAd();
125
+ // hasAd: boolean - 是否有可用的预加载广告
126
+ // status: number - 预加载状态 (0:未加载 1:加载中 2:成功 3:失败)
127
+ ```
128
+
129
+ ### clearPreloadedSplashAd
130
+
131
+ 清除预加载的广告缓存(Android)。
132
+
133
+ ```ts
134
+ clearPreloadedSplashAd();
135
+ ```
136
+
101
137
  ## 如何使用
102
138
 
103
- > 这边案列默认全部init初始化后
139
+ ### 基础用法(实时加载)
140
+
141
+ > 注意:这种方式在 Android 端可能会出现白屏
104
142
 
105
143
  ```tsx
106
144
  import { dyLoadSplashAd } from '@24jieqi/react-native-brayant-ad';
@@ -142,6 +180,123 @@ const ScrenPage = () => {
142
180
  };
143
181
  ```
144
182
 
183
+ ### 推荐用法(预加载 - Android)
184
+
185
+ **Android 端推荐使用预加载方式,避免启动页到广告之间出现白屏。**
186
+
187
+ ```tsx
188
+ import {
189
+ init,
190
+ preloadSplashAd,
191
+ hasPreloadedSplashAd,
192
+ dyLoadSplashAd,
193
+ } from '@24jieqi/react-native-brayant-ad';
194
+ import { useEffect } from 'react';
195
+
196
+ const App = () => {
197
+ useEffect(() => {
198
+ const initialize = async () => {
199
+ // 1. 初始化 SDK
200
+ await init({
201
+ appid: 'your_app_id',
202
+ app: '应用名称',
203
+ debug: false,
204
+ });
205
+
206
+ // 2. Android: 预加载开屏广告(避免白屏)
207
+ if (Platform.OS === 'android') {
208
+ await preloadSplashAd({ codeid: 'your_splash_code_id' });
209
+ console.log('开屏广告预加载完成');
210
+ }
211
+ };
212
+
213
+ initialize();
214
+ }, []);
215
+
216
+ // 3. 展示开屏广告(Android使用预加载,iOS实时加载)
217
+ const showSplash = async () => {
218
+ // 检查预加载状态(可选)
219
+ if (Platform.OS === 'android') {
220
+ const { hasAd } = await hasPreloadedSplashAd();
221
+ console.log('是否有预加载广告:', hasAd);
222
+ }
223
+
224
+ const splashAd = dyLoadSplashAd({
225
+ codeid: 'your_splash_code_id',
226
+ anim: 'default',
227
+ });
228
+
229
+ splashAd.subscribe('onAdShow', (event) => {
230
+ console.log('广告展示', event);
231
+ });
232
+
233
+ splashAd.subscribe('onAdClose', (event) => {
234
+ console.log('广告关闭', event);
235
+ });
236
+
237
+ splashAd.subscribe('onAdError', (error) => {
238
+ console.log('广告错误', error);
239
+ });
240
+ };
241
+
242
+ return (
243
+ // ...
244
+ );
245
+ };
246
+ ```
247
+
248
+ ### 在应用启动时自动展示开屏广告
249
+
250
+ ```tsx
251
+ import { init, preloadSplashAd, dyLoadSplashAd } from '@24jieqi/react-native-brayant-ad';
252
+ import { hide } from 'react-native-bootsplash';
253
+
254
+ const SplashAdManager = () => {
255
+ useEffect(() => {
256
+ const showSplashAdOnLaunch = async () => {
257
+ try {
258
+ // 1. 初始化广告 SDK
259
+ await init({ appid: 'your_app_id', app: '应用名称' });
260
+
261
+ // 2. Android: 预加载广告
262
+ if (Platform.OS === 'android') {
263
+ await preloadSplashAd({ codeid: 'your_splash_code_id' });
264
+ }
265
+
266
+ // 3. 展示广告(Android使用预加载,无白屏)
267
+ const splashAd = dyLoadSplashAd({
268
+ codeid: 'your_splash_code_id',
269
+ anim: 'fade',
270
+ });
271
+
272
+ splashAd.subscribe('onAdShow', () => {
273
+ console.log('广告展示');
274
+ // Android: 此时可以隐藏启动页(广告已准备好)
275
+ hide({ fade: true });
276
+ });
277
+
278
+ splashAd.subscribe('onAdClose', () => {
279
+ console.log('广告关闭');
280
+ });
281
+
282
+ splashAd.subscribe('onAdError', (error) => {
283
+ console.log('广告加载失败', error);
284
+ // 出错时也要隐藏启动页
285
+ hide({ fade: true });
286
+ });
287
+ } catch (error) {
288
+ console.error('广告初始化失败:', error);
289
+ hide({ fade: true });
290
+ }
291
+ };
292
+
293
+ showSplashAdOnLaunch();
294
+ }, []);
295
+
296
+ return null;
297
+ };
298
+ ```
299
+
145
300
  # 2. 激励视频
146
301
 
147
302
  ## API
@@ -348,6 +503,52 @@ const RewardVideoPage = () => {
348
503
 
349
504
  # 5. Banner广告
350
505
 
506
+ > 注意:Banner广告目前仅支持Android平台
507
+
508
+ ## API
509
+
510
+ ### preloadBannerAd
511
+
512
+ 预加载 Banner 广告(Android 专用)
513
+
514
+ 在组件渲染前调用,提前加载广告数据,减少白屏时间。预加载的广告会缓存 5 分钟,过期后自动失效。
515
+
516
+ | 参数 | 说明 | 类型 | 默认值 | 是否必填 |
517
+ | -------- | ------------ | ------ | ------ | -------- |
518
+ | codeid | 广告位 ID | string | - | 是 |
519
+ | adWidth | 广告宽度(dp) | number | 320 | 否 |
520
+ | adHeight | 广告高度(dp) | number | 50 | 否 |
521
+
522
+ ```tsx
523
+ import { NativeModules } from 'react-native';
524
+ const { BannerAdModule } = NativeModules;
525
+
526
+ // 在页面进入前预加载
527
+ useEffect(() => {
528
+ BannerAdModule.preloadBannerAd({
529
+ codeid: 'your_codeid',
530
+ adWidth: 320,
531
+ adHeight: 50,
532
+ });
533
+ }, []);
534
+ ```
535
+
536
+ ### hasPreloadedBannerAd
537
+
538
+ 检查是否有预加载的 Banner 广告
539
+
540
+ ```tsx
541
+ const hasCache = await BannerAdModule.hasPreloadedBannerAd('your_codeid');
542
+ ```
543
+
544
+ ### clearPreloadedBannerAd
545
+
546
+ 清除预加载的 Banner 广告缓存
547
+
548
+ ```tsx
549
+ BannerAdModule.clearPreloadedBannerAd();
550
+ ```
551
+
351
552
  ## 组件
352
553
 
353
554
  ### BannerAdView
@@ -366,10 +567,10 @@ const RewardVideoPage = () => {
366
567
  | onAdShow | 广告展示事件 | Function | - | 否 |
367
568
  | onAdDislike | 用户不感兴趣事件 | Function | - | 否 |
368
569
 
369
- > 注意:Banner广告目前仅支持Android平台
370
-
371
570
  ## 使用
372
571
 
572
+ ### 基础用法
573
+
373
574
  ```tsx
374
575
  import { BannerAdView, init } from '@24jieqi/react-native-brayant-ad';
375
576
  import { useEffect, useState } from 'react';
@@ -418,8 +619,87 @@ const BannerAdPage = () => {
418
619
  };
419
620
  ```
420
621
 
622
+ ### 推荐用法(预加载)
623
+
624
+ ```tsx
625
+ import { BannerAdView } from '@24jieqi/react-native-brayant-ad';
626
+ import { NativeModules } from 'react-native';
627
+ import { useEffect, useState } from 'react';
628
+ import { View } from 'react-native';
629
+
630
+ const { BannerAdModule } = NativeModules;
631
+
632
+ const BannerAdPage = () => {
633
+ const [showBannerView, setShowBannerView] = useState(false);
634
+
635
+ useEffect(() => {
636
+ // 先预加载广告,再显示组件
637
+ const preloadAndShow = async () => {
638
+ try {
639
+ await BannerAdModule.preloadBannerAd({
640
+ codeid: 'your_codeid',
641
+ adWidth: 320,
642
+ adHeight: 50,
643
+ });
644
+ } catch (error) {
645
+ console.log('预加载失败', error);
646
+ } finally {
647
+ // 无论预加载成功与否,都显示组件
648
+ setShowBannerView(true);
649
+ }
650
+ };
651
+
652
+ preloadAndShow();
653
+ }, []);
654
+
655
+ return (
656
+ <View>
657
+ <BannerAdView
658
+ codeid={'your_codeid'}
659
+ adWidth={320}
660
+ adHeight={50}
661
+ visible={showBannerView}
662
+ onAdRenderSuccess={(data: any) => {
663
+ console.log('Banner 广告渲染成功!', data);
664
+ }}
665
+ onAdError={(err: any) => {
666
+ console.log('Banner 广告加载失败!', err);
667
+ }}
668
+ />
669
+ </View>
670
+ );
671
+ };
672
+ ```
673
+
421
674
  # 6. 信息流广告
422
675
 
676
+ ## API
677
+
678
+ ### preloadFeedAd
679
+
680
+ 预加载信息流广告(Android 专用)
681
+
682
+ 在组件渲染前调用,提前加载广告数据,减少白屏时间。
683
+
684
+ | 参数 | 说明 | 类型 | 默认值 | 是否必填 |
685
+ | ------- | ------------ | ------ | ------ | -------- |
686
+ | appid | 应用 ID | string | - | 是 |
687
+ | codeid | 广告位 ID | string | - | 是 |
688
+ | adWidth | 广告宽度(dp) | string | '280' | 否 |
689
+
690
+ ```tsx
691
+ import { preloadFeedAd } from '@24jieqi/react-native-brayant-ad';
692
+
693
+ // 在页面进入前预加载
694
+ useEffect(() => {
695
+ preloadFeedAd({
696
+ appid: 'your_appid',
697
+ codeid: 'your_codeid',
698
+ adWidth: '375',
699
+ });
700
+ }, []);
701
+ ```
702
+
423
703
  ## 组件
424
704
 
425
705
  ### FeedAdView
@@ -437,6 +717,8 @@ const BannerAdPage = () => {
437
717
 
438
718
  ## 使用
439
719
 
720
+ ### 基础用法
721
+
440
722
  ```tsx
441
723
  import { FeedAdView } from '@24jieqi/react-native-brayant-ad';
442
724
  import { useEffect, useState } from 'react';
@@ -470,6 +752,42 @@ const RewardVideoPage = () => {
470
752
  };
471
753
  ```
472
754
 
755
+ ### 推荐用法(预加载)
756
+
757
+ ```tsx
758
+ import { FeedAdView, preloadFeedAd } from '@24jieqi/react-native-brayant-ad';
759
+ import { useEffect, useState } from 'react';
760
+
761
+ const RewardVideoPage = () => {
762
+ const [showFeedView, setShowFeedView] = useState(false);
763
+
764
+ // 页面进入时预加载广告
765
+ useEffect(() => {
766
+ preloadFeedAd({
767
+ appid: 'your_appid',
768
+ codeid: 'your_codeid',
769
+ }).then(() => {
770
+ // 预加载成功后显示组件
771
+ setShowFeedView(true);
772
+ });
773
+ }, []);
774
+
775
+ return (
776
+ <FeedAdView
777
+ codeid={'your_codeid'}
778
+ adWidth={375}
779
+ visible={showFeedView}
780
+ onAdLayout={(data: any) => {
781
+ console.log('Feed 广告加载成功!', data);
782
+ }}
783
+ onAdError={(err: any) => {
784
+ console.log('Feed 广告加载失败!', err);
785
+ }}
786
+ />
787
+ );
788
+ };
789
+ ```
790
+
473
791
  ## License
474
792
 
475
793
  MIT
@@ -122,6 +122,74 @@ public class AdManager extends ReactContextBaseJavaModule {
122
122
  loadTTFeedAd(codeId, width);
123
123
  }
124
124
 
125
+ /**
126
+ * 预加载信息流广告(FeedAd)
127
+ * 在组件渲染前调用,提前加载广告数据,减少白屏时间
128
+ * 与 loadFeedAd 的区别:此方法不依赖 Promise 回调,静默预加载
129
+ */
130
+ @ReactMethod
131
+ public void preloadFeedAd(ReadableMap options, final Promise promise) {
132
+ String codeId = options.getString("codeid");
133
+ if (codeId == null || codeId.isEmpty()) {
134
+ promise.reject(TAG, "codeid is required");
135
+ return;
136
+ }
137
+
138
+ float width = 0;
139
+ if (options.hasKey("adWidth")) {
140
+ width = Float.parseFloat(Objects.requireNonNull(options.getString("adWidth")));
141
+ }
142
+
143
+ // 检查 SDK 是否初始化
144
+ if (DyADCore.TTAdSdk == null) {
145
+ promise.reject(TAG, "TTAdSdk not initialized");
146
+ return;
147
+ }
148
+
149
+ // 如果已经有缓存的广告,直接返回成功
150
+ if (DyADCore.feedAd != null) {
151
+ promise.resolve(true);
152
+ return;
153
+ }
154
+
155
+ // 创建广告请求参数
156
+ float expressViewWidth = width > 0 ? width : 280;
157
+ float expressViewHeight = 0; // 自动高度
158
+
159
+ AdSlot adSlot = new AdSlot.Builder()
160
+ .setCodeId(codeId)
161
+ .setSupportDeepLink(true)
162
+ .setAdCount(1)
163
+ .setExpressViewAcceptedSize(expressViewWidth, expressViewHeight)
164
+ .setImageAcceptedSize(640, 320)
165
+ .setNativeAdType(AdSlot.TYPE_INTERACTION_AD)
166
+ .build();
167
+
168
+ // 请求广告
169
+ DyADCore.TTAdSdk.loadNativeExpressAd(
170
+ adSlot,
171
+ new TTAdNative.NativeExpressAdListener() {
172
+ @Override
173
+ public void onError(int code, String message) {
174
+ Log.d(TAG, "preloadFeedAd error: " + message);
175
+ promise.reject(TAG, "preload feed ad error: " + message);
176
+ }
177
+
178
+ @Override
179
+ public void onNativeExpressAdLoad(List<TTNativeExpressAd> ads) {
180
+ Log.d(TAG, "preloadFeedAd success");
181
+ if (ads == null || ads.isEmpty()) {
182
+ promise.reject(TAG, "preload feed ad: no ad content");
183
+ return;
184
+ }
185
+ // 缓存加载成功的广告
186
+ DyADCore.feedAd = ads.get(0);
187
+ promise.resolve(true);
188
+ }
189
+ }
190
+ );
191
+ }
192
+
125
193
  /**
126
194
  * 加载穿山甲的信息流广告
127
195
  *
@@ -2,6 +2,7 @@ package com.brayantad;
2
2
 
3
3
  import androidx.annotation.NonNull;
4
4
 
5
+ import com.brayantad.dy.banner.BannerAdModule;
5
6
  import com.brayantad.dy.banner.BannerAdViewManager;
6
7
  import com.brayantad.dy.drawFeed.DrawFeedViewManager;
7
8
  import com.brayantad.dy.drawFeed.DrawFeedViewModule;
@@ -29,6 +30,7 @@ public class BrayantAdPackage implements ReactPackage {
29
30
  modules.add(new RewardVideoModule(reactContext));
30
31
  modules.add(new FullScreenVideoModule(reactContext));
31
32
  modules.add(new DrawFeedViewModule(reactContext));
33
+ modules.add(new BannerAdModule(reactContext));
32
34
  return modules;
33
35
  }
34
36
 
@@ -70,6 +70,15 @@ public class DyADCore {
70
70
  public static CSJSplashAd splashAd;
71
71
  public static ReactContext reactContext;
72
72
 
73
+ // 开屏广告预加载状态管理
74
+ public static final int SPLASH_PRELOAD_IDLE = 0; // 未预加载
75
+ public static final int SPLASH_PRELOAD_LOADING = 1; // 预加载中
76
+ public static final int SPLASH_PRELOAD_SUCCESS = 2; // 预加载成功
77
+ public static final int SPLASH_PRELOAD_FAIL = 3; // 预加载失败
78
+ public static int splashPreloadStatus = SPLASH_PRELOAD_IDLE;
79
+ public static long splashPreloadTime = 0; // 预加载成功时间戳
80
+ public static final long SPLASH_PRELOAD_VALID_DURATION = 5 * 60 * 1000; // 预加载有效期5分钟
81
+
73
82
  public static void initSdk(Context context, String appId, Boolean debug) {
74
83
  if (TTAdSdk != null && Objects.equals(tt_appid, appId)) {
75
84
  //已初始化
@@ -0,0 +1,175 @@
1
+ package com.brayantad.dy.banner;
2
+
3
+ import android.util.Log;
4
+
5
+ import androidx.annotation.NonNull;
6
+
7
+ import com.brayantad.dy.DyADCore;
8
+ import com.bytedance.sdk.openadsdk.AdSlot;
9
+ import com.bytedance.sdk.openadsdk.TTAdNative;
10
+ import com.bytedance.sdk.openadsdk.TTNativeExpressAd;
11
+ import com.facebook.react.bridge.Promise;
12
+ import com.facebook.react.bridge.ReactApplicationContext;
13
+ import com.facebook.react.bridge.ReactContextBaseJavaModule;
14
+ import com.facebook.react.bridge.ReactMethod;
15
+ import com.facebook.react.bridge.ReadableMap;
16
+
17
+ import java.util.List;
18
+
19
+ /**
20
+ * Banner 广告预加载模块
21
+ * 提供 Banner 广告的预加载功能,减少白屏时间
22
+ */
23
+ public class BannerAdModule extends ReactContextBaseJavaModule {
24
+ public static final String TAG = "BannerAdModule";
25
+ private static ReactApplicationContext reactAppContext;
26
+
27
+ // Banner 广告缓存
28
+ private static TTNativeExpressAd bannerAdCache = null;
29
+ private static String bannerAdCacheCodeId = null;
30
+ private static long bannerAdCacheTime = 0;
31
+ private static final long CACHE_VALID_DURATION = 5 * 60 * 1000; // 缓存有效期 5 分钟
32
+
33
+ public BannerAdModule(ReactApplicationContext reactContext) {
34
+ super(reactContext);
35
+ reactAppContext = reactContext;
36
+ }
37
+
38
+ @NonNull
39
+ @Override
40
+ public String getName() {
41
+ return TAG;
42
+ }
43
+
44
+ /**
45
+ * 预加载 Banner 广告
46
+ * 在组件渲染前调用,提前加载广告数据
47
+ *
48
+ * @param options 包含 codeid, adWidth, adHeight
49
+ * @param promise 回调
50
+ */
51
+ @ReactMethod
52
+ public void preloadBannerAd(ReadableMap options, final Promise promise) {
53
+ String codeId = options.hasKey("codeid") ? options.getString("codeid") : null;
54
+ int adWidth = options.hasKey("adWidth") ? options.getInt("adWidth") : 320;
55
+ int adHeight = options.hasKey("adHeight") ? options.getInt("adHeight") : 50;
56
+
57
+ if (codeId == null || codeId.isEmpty()) {
58
+ promise.reject(TAG, "codeid is required");
59
+ return;
60
+ }
61
+
62
+ // 检查 SDK 是否初始化
63
+ if (DyADCore.TTAdSdk == null) {
64
+ promise.reject(TAG, "TTAdSdk not initialized");
65
+ return;
66
+ }
67
+
68
+ // 检查缓存是否有效
69
+ if (hasValidCache(codeId)) {
70
+ Log.d(TAG, "Using cached banner ad");
71
+ promise.resolve(true);
72
+ return;
73
+ }
74
+
75
+ // 清除旧缓存
76
+ clearCache();
77
+
78
+ // 创建广告请求参数
79
+ AdSlot adSlot = new AdSlot.Builder()
80
+ .setCodeId(codeId)
81
+ .setSupportDeepLink(true)
82
+ .setAdCount(1)
83
+ .setExpressViewAcceptedSize(adWidth, adHeight)
84
+ .build();
85
+
86
+ // 请求广告
87
+ DyADCore.TTAdSdk.loadBannerExpressAd(
88
+ adSlot,
89
+ new TTAdNative.NativeExpressAdListener() {
90
+ @Override
91
+ public void onError(int code, String message) {
92
+ Log.d(TAG, "preloadBannerAd error: " + message);
93
+ promise.reject(TAG, "preload banner ad error: " + message);
94
+ }
95
+
96
+ @Override
97
+ public void onNativeExpressAdLoad(List<TTNativeExpressAd> ads) {
98
+ Log.d(TAG, "preloadBannerAd success");
99
+ if (ads == null || ads.isEmpty()) {
100
+ promise.reject(TAG, "preload banner ad: no ad content");
101
+ return;
102
+ }
103
+ // 缓存广告
104
+ bannerAdCache = ads.get(0);
105
+ bannerAdCacheCodeId = codeId;
106
+ bannerAdCacheTime = System.currentTimeMillis();
107
+ promise.resolve(true);
108
+ }
109
+ }
110
+ );
111
+ }
112
+
113
+ /**
114
+ * 检查是否有有效的缓存广告
115
+ *
116
+ * @param codeId 广告位 ID
117
+ * @return true 如果缓存有效
118
+ */
119
+ @ReactMethod
120
+ public void hasPreloadedBannerAd(String codeId, Promise promise) {
121
+ promise.resolve(hasValidCache(codeId));
122
+ }
123
+
124
+ /**
125
+ * 获取缓存的广告(供 BannerAdView 使用)
126
+ *
127
+ * @param codeId 广告位 ID
128
+ * @return 缓存的广告,如果没有则返回 null
129
+ */
130
+ public static TTNativeExpressAd getCachedBannerAd(String codeId) {
131
+ if (hasValidCache(codeId)) {
132
+ TTNativeExpressAd cachedAd = bannerAdCache;
133
+ // 使用后清除缓存,避免重复使用
134
+ clearCache();
135
+ return cachedAd;
136
+ }
137
+ return null;
138
+ }
139
+
140
+ /**
141
+ * 清除缓存的广告
142
+ */
143
+ @ReactMethod
144
+ public void clearPreloadedBannerAd() {
145
+ clearCache();
146
+ }
147
+
148
+ /**
149
+ * 检查缓存是否有效
150
+ */
151
+ private static boolean hasValidCache(String codeId) {
152
+ if (bannerAdCache == null || bannerAdCacheCodeId == null) {
153
+ return false;
154
+ }
155
+ // 检查 codeId 是否匹配
156
+ if (!bannerAdCacheCodeId.equals(codeId)) {
157
+ return false;
158
+ }
159
+ // 检查缓存是否过期
160
+ long currentTime = System.currentTimeMillis();
161
+ return (currentTime - bannerAdCacheTime) < CACHE_VALID_DURATION;
162
+ }
163
+
164
+ /**
165
+ * 清除缓存
166
+ */
167
+ private static void clearCache() {
168
+ if (bannerAdCache != null) {
169
+ bannerAdCache.destroy();
170
+ bannerAdCache = null;
171
+ }
172
+ bannerAdCacheCodeId = null;
173
+ bannerAdCacheTime = 0;
174
+ }
175
+ }
@@ -9,6 +9,7 @@ import android.widget.RelativeLayout;
9
9
 
10
10
  import com.brayantad.R;
11
11
  import com.brayantad.dy.DyADCore;
12
+ import com.brayantad.dy.banner.BannerAdModule;
12
13
  import com.brayantad.utils.Utils;
13
14
  import com.bytedance.sdk.openadsdk.AdSlot;
14
15
  import com.bytedance.sdk.openadsdk.TTAdDislike;
@@ -109,6 +110,16 @@ public class BannerAdView extends RelativeLayout {
109
110
  mBannerAd.destroy();
110
111
  }
111
112
 
113
+ // 先检查是否有预加载的缓存广告
114
+ TTNativeExpressAd cachedAd = BannerAdModule.getCachedBannerAd(mCodeId);
115
+ if (cachedAd != null) {
116
+ mBannerAd = cachedAd;
117
+ showBannerAd(mBannerAd);
118
+ mIsAdLoading = false;
119
+ return;
120
+ }
121
+
122
+ // 没有缓存,正常加载
112
123
  // 创建广告请求参数AdSlot
113
124
  mAdSlot =
114
125
  new AdSlot.Builder()