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();
}
```
把这个方法注释了。就行了。这篇文章是开始,没啥技术含量~ febsky 发表于 2018-12-24 13:43
理论上来说可以,但是有可能看在splash页面有很多初始化操作,贸然跳过,遗漏初始化操作,有可能引起不必 ...
表哥说得极是 贸然跳过 可能导致黑屏白屏 或者直接进不去 知更鸟的传说 发表于 2018-12-24 13:27
原则上来说 是不是可以启动直接跳main尼
理论上来说可以,但是有可能看在splash页面有很多初始化操作,贸然跳过,遗漏初始化操作,有可能引起不必要的bug 谢谢了 ,学习了 小白虽然不懂,,还是支持一波~ 好东东,学习了 还是支持一波 求个破解vip的APK 厉害了厉害了厉害了 学习了,很受用 现在遇到一个软件,修改了dex文件后打开软件后有个弹窗提示软件损坏需要重新安装,我找到了一个弹窗的类,但是但是我找不到是哪里调用的这个弹窗类,怎么往下进行呢?软件是Yandex浏览器 感谢楼主分享