febsky 发表于 2018-12-24 09:47

2018-12-14-去掉麻花影视闪屏广告(完成)

本帖最后由 febsky 于 2019-1-2 17:56 编辑

目的:去掉每次启动的5秒等待

**因为版主说文章发的太分散了,所以整理了一下放到里第一片里面,这个系列也不再单独更新 [首页地址](https://www.52pojie.cn/thread-842708-1-1.html)**

妈的每次测试进入都要等待5秒,等五秒就算了,还要手动点击进入。5秒浪费人生宝贵时间。先把它干掉。

猜测一下好,这个玩意等待需要时间,等待完成,肯定要进入主Activity,获取下这个主要Activity的名字,MainActivity,然后在SplashActivity里面查找一下,发现是在h方法里面,那好说了,我们在他源码启动等待计时器的地方,直接调用这个h方法就行了。h方法签名如下:

```
    private void h() {
      if (this.f && !this.i) {   //要想调用h方法,这两个判断条件必须通过
            if (this.m != null) {
                this.m.cancel();
            }
            startActivity(new Intent(this, MainActivity.class));
            overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
            finish();
      }
    }
```

就是分析发现,g方法是启动定时器的地方,而g被f调用,那么我们直接在f里面调用h就行了,但是h里面会有if判断,让判断为true就行了。

这种方式很简单,但是发现还是会有个"大美女"一闪而过,我特么每次不想看到这个东西。我们来看下这个美女怎么出来的。

通过monitor分析,得到显示图片的ImageView 的id为:

`com.amahua.ompimdrt:id/splash_bg`

所以找到设置图片的地方就ok了,去SplashActivity里面看看,搜索splash_bg 得到 ,this.c ,然后搜索this.c

```
//根据变量名猜测这玩意就是设置广告的地方,直接把这个方法屏蔽掉。
    public void a(long j, List<AdsResponse> list, boolean z) {
      int i = 1;
      this.g = true;
      this.h = z;
      //从这个命名可以看出,这个项目用了mvp架构,
      //那么这个方法,从结构上猜测应该是网络请求之后的回调,
      //那么应该属于view的接口方法,那么应该在 SplashPresenter 里面调用。
      //根据继承关系查看,这个方法是在 com.mh.movie.core.mvp.a.ba.b 里面声明的
      ((SplashPresenter) this.b).e();
      ((SplashPresenter) this.b).g();
      if (!(list == null || list.isEmpty())) {
            int c = d.c(this, com.mh.movie.core.mvp.ui.b.w);
            int i2 = 0;
            if (this.e == null || !((AdsResponse) this.e.get(0)).getThumbnailUrl().equals(((AdsResponse) list.get(0)).getThumbnailUrl())) {
                d.a((Context) this, com.mh.movie.core.mvp.ui.b.q, new e().a((Object) list));
                while (i < list.size()) {
                  if (!TextUtils.isEmpty(((AdsResponse) list.get(i)).getThumbnailUrl())) {
                        Glide.with((FragmentActivity) this).load(((AdsResponse) list.get(i)).getThumbnailUrl()).preload();
                  }
                  i++;
                }
            } else {
                i2 = (c + 1) % list.size();
            }
            d.a((Context) this, com.mh.movie.core.mvp.ui.b.w, i2);
            this.d = (AdsResponse) list.get(i2);
            Glide.with((FragmentActivity) this).load(this.d.getThumbnailUrl()).apply(new RequestOptions().placeholder(this.c.getDrawable())).into(this.c);
            com.mh.movie.core.mvp.ui.b.c = d.b(this.r, "is_first_partner");
      }
      f();//倒计时在这个方法调用的g方法里面。所以如果屏蔽当前方法,那么这个启动主界面的操作必须手动调用
    }
```

直接在a方法里面打断点,然后运行项目观察调用堆栈

```Smali
.method public a(JLjava/util/List;Z)V
    .locals 2
    .annotation system Ldalvik/annotation/Signature;
      value = {
            "(J",
            "Ljava/util/List<",
            "Lcom/mh/movie/core/mvp/model/entity/response/AdsResponse;",
            ">;Z)V"
      }
    .end annotation
#只是为了查看调用堆栈,断点打在下面这行就行
    const/4 p1, 0x1

    .line 332
    iput-boolean p1, p0, Lcom/mh/movie/core/mvp/ui/activity/SplashActivity;->g:Z
    ##。。。。。 省略无用代码
```

结果如下:

```
a:332, SplashActivity (com.mh.movie.core.mvp.ui.activity)
# $1 理论上来说是这个类里面的第一个匿名内部类
a:122, SplashPresenter$1 (com.mh.movie.core.mvp.presenter)
a:103, SplashPresenter$1 (com.mh.movie.core.mvp.presenter)
a:69, b (com.mh.movie.core.mvp.model.a)
##....省略无用堆栈
```

根据特征码,可以定位到如下方法:

```
    public void a(LoginRequest loginRequest, boolean z) {
      ((a) this.c).a(loginRequest).compose(a(this.f, this.d, z)).subscribe(new com.mh.movie.core.mvp.model.a.b<LoginResponse>(this.e, new com.google.gson.b.a<BaseResponse<LoginResponse>>() {
      }.getType()) {
            public void a(LoginResponse loginResponse) {
                com.mh.movie.core.mvp.ui.b.a(loginResponse.getUserInfo());
                if (loginResponse.getUserInfo().getUserType() == 0) {
                  d.a(SplashPresenter.this.f.getBaseContext(), com.mh.movie.core.mvp.ui.b.i, false);
                }
                com.mh.movie.core.mvp.ui.b.a(SplashPresenter.this.f.getBaseContext(), loginResponse.getUserInfo().getToken());
                com.mh.movie.core.mvp.ui.b.a(SplashPresenter.this.f.getBaseContext(), loginResponse.getUid());
                d.a(SplashPresenter.this.f, com.mh.movie.core.mvp.ui.b.f, XMLUtils.bean2Json(loginResponse.getUserInfo()));
                d.a(SplashPresenter.this.f, com.mh.movie.core.mvp.ui.b.h, loginResponse.getUid());
                com.mh.movie.core.mvp.ui.b.a(loginResponse.getUrlMap());
                com.mh.movie.core.mvp.ui.b.a(true);
                //看下面这一行,就是调用显示广告的额地方,理论上来说直接屏蔽这行就行了,其实仔细分析下,第三个参数,从名字上来看说是要不要加载广告
                ((b) SplashPresenter.this.d).a(loginResponse.getUid(), loginResponse.getAdsList(), loginResponse.isBootadSwitch());
                SplashPresenter.this.f();
                SplashPresenter.this.j();
                SplashPresenter.this.i();
                SplashPresenter.this.k();
            }
            //省略代码
}
```

我们尝试修改第三个参数为false。找到loginResponse.isBootadSwitch() 方法,然后让她永远返回false就好了:

```smali
.method public isBootadSwitch()Z
    .locals 1

    .line 77
    #iget-boolean v0, p0, Lcom/mh/movie/core/mvp/model/entity/response/LoginResponse;->bootadSwitch:Z
const/4 v0, 0x0
    return v0
.end method

```

发现没起作用。。。。

然后我们把尝试下,把 a的调用注释点也即是 下面这行代码,注释掉:

```
((b) SplashPresenter.this.d).a(loginResponse.getUid(), loginResponse.getAdsList(),
```

发现还是有闪屏广告,我擦嘞。。。。想一下,那这个地方的广告应该是有缓存,就是在没有网的情况下也可以显示。ok,继续去看 SplashActivity,如果存在这种情况肯定在这个Activity初始化的时候就有了。

继续搜索,this.c

```

    public void b(@Nullable Bundle bundle) {
      this.k = (TextView) findViewById(R.id.button_enter);
      this.l = (ViewPager) findViewById(R.id.features);
      this.c = (ImageView) findViewById(R.id.splash_bg);
      this.o = (TextView) findViewById(R.id.tv_start);
      this.c.setOnClickListener(this.j);
      com.jakewharton.rxbinding.view.b.a(this.k).a(1, TimeUnit.SECONDS).a(new aw(this));
      //下面的都删了就行
      /*int c = d.c(this, com.mh.movie.core.mvp.ui.b.w);
      e eVar = new e();
      String a = d.a(this, com.mh.movie.core.mvp.ui.b.q);
      if (a != null) {
            this.e = (List) eVar.a(a, new com.google.gson.b.a<List<AdsResponse>>() {
            }.getType());
            this.d = (AdsResponse) this.e.get((c + 1) % this.e.size());
            Glide.with((FragmentActivity) this).load(this.d.getThumbnailUrl()).apply(new RequestOptions().placeholder(R.mipmap.launch_screen)).into(this.c);
      }*/
    }
```

然后把a方法里面的广告加载都删除了:

```java
   /*public void a(long j, List<AdsResponse> list, boolean z) {
      int i = 1;
      this.g = true;
      this.h = z;
      ((SplashPresenter) this.b).e();
      ((SplashPresenter) this.b).g();
      if (!(list == null || list.isEmpty())) {
            int c = d.c(this, com.mh.movie.core.mvp.ui.b.w);
            int i2 = 0;
            if (this.e == null || !((AdsResponse) this.e.get(0)).getThumbnailUrl().equals(((AdsResponse) list.get(0)).getThumbnailUrl())) {
                d.a((Context) this, com.mh.movie.core.mvp.ui.b.q, new e().a((Object) list));
                while (i < list.size()) {
                  if (!TextUtils.isEmpty(((AdsResponse) list.get(i)).getThumbnailUrl())) {
                        Glide.with((FragmentActivity) this).load(((AdsResponse) list.get(i)).getThumbnailUrl()).preload();
                  }
                  i++;
                }
            } else {
                i2 = (c + 1) % list.size();
            }
            d.a((Context) this, com.mh.movie.core.mvp.ui.b.w, i2);
            this.d = (AdsResponse) list.get(i2);
            Glide.with((FragmentActivity) this).load(this.d.getThumbnailUrl()).apply(new RequestOptions().placeholder(this.c.getDrawable())).into(this.c);
            com.mh.movie.core.mvp.ui.b.c = d.b(this.r, "is_first_partner");
      }*/
      f();
    }
```


总结一下去掉闪屏广告:

1. 去掉从缓存里面加载广告
2. 去掉请求广告api成功的显示广告
3. 去掉延迟启动主界面 (MainActivity)


好了,世界从此干净了。。。


最后说一点,每次启动到MainActivity都会问我要不要登陆。我不想看到它。

```

    @Subscriber(tag = "sign_up_success")
    public void signupSuccess(String str) {
      this.p = "";
      if (com.mh.movie.core.mvp.ui.b.H > 0) {
            CustomToast.makeTitleText(this.r, "新手奖励", String.format("恭喜你获得新会员奖励:%s麻花币,快去看看吧!", new Object[]{Integer.valueOf(com.mh.movie.core.mvp.ui.b.H)})).show();
      }
    }
   
   
public void f() {
    if (this.d || com.mh.movie.core.mvp.ui.b.H <= 0) {
      g();
      return;
    }
    if (this.h == null) {
      this.h = new RequestPermissionDialog(this.r, 3, 2);
      this.h.a("新手奖励");
      this.h.b(String.format("恭喜你获得新会员奖励:%s麻花币,麻花币可以兑换特权和奖品哦!", new Object[]{Integer.valueOf(com.mh.movie.core.mvp.ui.b.H)}));
      this.h.a(new RequestPermissionDialog.a() {
            public void a() {
                MainActivity.this.h.dismiss();
                MainActivity.this.startActivity(new Intent(MainActivity.this.r, RegistActivity.class));
            }

            public void b() {
                MainActivity.this.h.dismiss();
                MainActivity.this.g();
            }
      });
    }
    this.h.show();
}
```

把这个方法注释了。就行了。这篇文章是开始,没啥技术含量~

yiwai2012 发表于 2018-12-25 10:06

febsky 发表于 2018-12-24 13:43
理论上来说可以,但是有可能看在splash页面有很多初始化操作,贸然跳过,遗漏初始化操作,有可能引起不必 ...

表哥说得极是 贸然跳过 可能导致黑屏白屏 或者直接进不去

febsky 发表于 2018-12-24 13:43

知更鸟的传说 发表于 2018-12-24 13:27
原则上来说 是不是可以启动直接跳main尼

理论上来说可以,但是有可能看在splash页面有很多初始化操作,贸然跳过,遗漏初始化操作,有可能引起不必要的bug

babyxinloveyou 发表于 2018-12-24 10:13

谢谢了 ,学习了

sensMe 发表于 2018-12-24 10:24

小白虽然不懂,,还是支持一波~

lxm808 发表于 2018-12-24 10:27

好东东,学习了

好学小老头 发表于 2018-12-24 10:38

还是支持一波

CoinKing_Mario 发表于 2018-12-24 10:38

求个破解vip的APK

SteveFan 发表于 2018-12-24 10:40

厉害了厉害了厉害了

qeh8902 发表于 2018-12-24 10:41

学习了,很受用

幻象 发表于 2018-12-24 10:41

现在遇到一个软件,修改了dex文件后打开软件后有个弹窗提示软件损坏需要重新安装,我找到了一个弹窗的类,但是但是我找不到是哪里调用的这个弹窗类,怎么往下进行呢?软件是Yandex浏览器

Martin.Ma 发表于 2018-12-24 10:44

感谢楼主分享
页: [1] 2 3 4 5 6 7 8 9
查看完整版本: 2018-12-14-去掉麻花影视闪屏广告(完成)