Android 解决 GMS/Firebase AdView 启动慢的性能问题及 AdView 共用问题

2017年2月12日07:51:09 发表评论 22 views

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(…) 函数即可。

  • yiisaa
  • 这是我的微信扫一扫
  • weinxin
  • zhengweiqiangcom
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: