Android巧妙关闭SDK中的Activity

如何关闭SDK中Activity

因为博主最近一直在做商业化相关的工作,需要写用于公司内部所有项目的广告SDK。
而广告SDK内部需要集成几家广告平台的SDK,这就避免不了和很多第三方SDK打交道。

但是第三方广告SDK给提供的接口总是无法满足我们产品的需求,这就需要我们去想各种千奇百怪的方法。
这篇文章的出现也是因为我们之前遇到的一个问题而引发出来。

一 、需求是这样的:

我们有一个广告位需要显示Admob插屏广告,插屏广告的接口非常的简单,概括起来基本就一个load() ,一个show()方法。
插屏广告和原生广告不同,原生广告我们能够拿到广告物料,自己去组装View。但是插屏广告当调用show()方法后,会直接启动Admob 自己的Activity显示广告。
但是当我们点击广告后,发现这个Activity不会消失,这就造成了很不好的体验。正常我们希望广告点击跳转GP,或者浏览器后,广告页面也会随之消失。
这样当用户回到应用后,不会再看到这个页面。

所以就有了这个需求:虽然Admob SDK内部插屏广告点击后,页面不会消失,但是我们需要让这个Activity关掉。

二 、那么如何做到关闭 SDK 中的Activity呢?

其实可以有两个方法可以解决这个问题:

1 、注册 ActivityLifecycleCallbacks 。
关于 ActivityLifecycleCallbacks 在之前的文章中有介绍。《Android 监听应用集成的SDK中的 Activity》总的来说就是 注册 ActivityLifecycleCallbacks 监听应用内所有 Activity的生命周期,
在回调方法中拿到插屏广告Activity 的对象,用成员变量保存起来,在点击广告的回调中将其关闭。

具体代码如下:

public class ActivityManager implements Application.ActivityLifecycleCallbacks {

    private Activity activity;

    public void registerActivityLifecycleCallbacks() {
        AdApplication.getApp().registerActivityLifecycleCallbacks(this);
    }

    public void closeAdActivity() {
        if (activity != null) {
            activity.finish();
        }
    }


    @Override
    public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
        if(activity instanceof com.google.android.gms.ads.AdActivity) {
            this.activity = activity;
        }
    }

    @Override
    public void onActivityStarted(Activity activity) {

    }

    @Override
    public void onActivityResumed(Activity activity) {

    }

    @Override
    public void onActivityPaused(Activity activity) {

    }

    @Override
    public void onActivityStopped(Activity activity) {

    }

    @Override
    public void onActivitySaveInstanceState(Activity activity, Bundle outState) {

    }

    @Override
    public void onActivityDestroyed(Activity activity) {

    } 
 }

2 、第二种方法:

利用Actvity launchMode。

我们都知道Activity 有四种 launchMode 。
分别是: standard singleTop singleTask singleInstance。
这里我们需要用到 singleTask 。简单来讲就是利用 singleTask 原理,将插屏Activity 关掉。

我们知道,当我们将Activity 的 launchMode 设置为 singleTask, 启动这个Activity 后 ,那么这个Activity在其所在的任务栈中,只会存在一个实例。
当 Activity A 的 launchMode 为 singleTask 时,如果 Activity A 上面还有 Activity B 在前台。这时再次启动 Activity A 。并不会重新创建 Activity A ,
而是会将 Activity B 下面的 Activity A 重新调起,并且 Activity B 会被排除任务栈。

知道了原理,接下来就简单了。
(1)、 先在 manifest 中声明 插屏广告的Activity,并且指定其任务栈, launchMode 为 singleTask 。
我们假设其为 AdActivity :

        <activity
            android:name=".AdActivity"
            android:singleTask="singleTask"
            android:taskAffinity="com.demo.ad"/>

(2)、 然后我们声明一个空 Activity , 同样声明其 singleTask 为 singleTask,并且让其与 AdActivity 在同一个任务栈:

        <activity
            android:name=".EmptyActivity"
            android:launchMode="singleTask"
            android:taskAffinity="com.demo.ad"/>

(3)、 接下来,在启动 AdActivity 之前,先启动 EmptyActivity 。
让 EmptyActivity 先一步 AdActivity 启动起来。当需要关闭 AdActivity 时,只需要再次启动 EmptyActivity 就可以了。
这正是利用了 singleTask 的原理。

(4)、 这时 EmptyActivity 还在,但是 EmptyActivity 是空的,完全是为了配合关闭 AdActivity 存在的。所以需要将其finish。
只需要在 EmptyActivity 中,重写 onNewIntent() 方法,然后调用 finish() 就可以了。

    /**
     * onNewIntent 第一次启动Activity时不会调用该方法。
     * @param intent
     */
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        finish();
    }

如果希望保险一点,可以设置EmptyActivity为透明的,不会出现白屏的情况。

三、注意
值得注意的是,如果从商业化的角度来讲,并不建议这样做。
因为商业化是需要很多统计数据的,如果我们点击 AdActivity 跳转后,如果 AdActivity 是通过调用 startActivityForResult 跳转广告页面,
并且重写了 onActivityResult 方法,需要得到一些数据。
如果我们强行关闭了这个 AdActivity ,会让 AdActivity 得不到需要的数据,可能会影响广告收入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值