Google Ads(Google 广告) Android 版的性能及其差,com.google.android.gms.ads.AdView 初始化已经赶上 WebView 了。如果 Activity 在 layout 中添加了 AdView 那就等着长时间的黑屏吧,在 Nexus 6P 上都需要好几秒的启动时间。
另外 Firebase 文档中建议每个 AdView 用不同的 adUnitId,这样如果希望方便在所有 Activity 中统一添加 AdView 就比较麻烦了,这里分享一种方法解决这个问题,同时能一定程度上缓解 AdViews 性能差带来的启动延时。
一. 解决 AdView 性能差带来的启动延时问题
简单实例代码如下,完整代码可见第二部分介绍:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_entrance);
……
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (isDestroryed) {
return;
}
try {
adView = new AdView(getApplicationContext());
adView.setAdUnitId(adUnitId);
adView.setAdSize(AdSize.SMART_BANNER);
AdRequest.Builder adBuilder = new AdRequest.Builder();
if (BuildConfig.DEBUG) {
adBuilder.addTestDevice("CAEC00A596FCCFC2D838832FBBACD8DB");
}
adLayout.addView(adView);
adView.loadAd(adBuilder.build());
adView.bringToFront();
} catch (Throwable e) {
// if exception, not show ad
adLayout.setVisibility(View.GONE);
}
}
}, 800);
}
不通过布局中添加 AdView 而是在代码中主动创建 AdView,并延时添加到布局中。
如果一定要在布局中添加也可以通过开始将 AdView 设置为 gone 或者 viewstub 引用公共广告布局,后期再去主动展示。
二. AdView 相关代码复用,同时 AdView 用不同的 adUnitId
1. 定义公共部分——公共广告布局
当然在开始前你是需要添加
compile 'com.google.firebase:firebase-ads:9.6.1'
等依赖以及 gradle plugin 的,具体请参考官方文档。
添加布局文件 layout_ad.xml,作为公共广告布局单元,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ad_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:orientation="vertical">
<!-- AdView will be added here -->
</LinearLayout>
其实就是一个空的 LinearLayout,后面用来存放 AdView。
2. 定义公共部分——Java 公共部分之BaseActivity
在 BaseActivity 中定义 initAdLayout(…) 函数,并绑定 AdView 生命周期。
public class BaseActivity extends Activity {
private AdView adView;
private boolean isDestroryed = false;
protected boolean initAdLayout(final String adUnitId) {
final ViewGroup adLayout = (ViewGroup) findViewById(R.id.ad_layout);
if (adLayout == null) {
return false;
}
adLayout.setVisibility(View.VISIBLE);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
if (isDestroryed) {
return;
}
try {
adView = new AdView(getApplicationContext());
adView.setAdUnitId(adUnitId);
adView.setAdSize(AdSize.SMART_BANNER);
AdRequest.Builder adBuilder = new AdRequest.Builder();
if (BuildConfig.DEBUG) {
adBuilder.addTestDevice("CAEC00A596FCCFC2D838832FBBACD8DB");
}
adLayout.addView(adView);
adView.loadAd(adBuilder.build());
adView.bringToFront();
} catch (Throwable e) {
// if exception, not show ad
adLayout.setVisibility(View.GONE);
}
}
}, 800);
return true;
}
@Override
protected void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
@Override
protected void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
@Override
protected void onDestroy() {
if (adView != null) {
adView.destroy();
}
isDestroryed = true;
super.onDestroy();
}
}
initAdLayout(…) 函数主要就是新建 AdView 添加到之前的 LinearLayout 中。这个过程是被延时了 800ms 的,为了防止影响初始化速度。
3. 引用——布局中添加公共广告布局
现在在你需要添加广告的布局中引用公共广告布局
<include android:id="@+id/ad_layout"
layout="@layout/layout_ad"/>
4. 引用——Java 中初始化广告
需要添加广告的 Activity 继承自 BaseActivity,在 onCreate 方法结束前调用 initAdLayout(String adUnitId) 方法。
而不需要添加广告的 Activity 继承自 BaseActivity 不调用 initAdLayout(…) 函数即可。
Samsung_p1e2jeb