APP启动和广告

11 9月
  • 启动流程 & 优化
  • 启动监控
  • 启动屏广告
  • 闪屏广告

启动流程 & 优化

APP启动可以分成三个阶段:main函数执行前,main函数执行后,首屏渲染完成后

main函数执行前

main函数执行前,系统会加载二进制文件(APP的.o文件集合),动态链接,初始化runtime,加载一些类等操作,简而言之就是IOS执行了APP的装载和链接等工作。想让APP启动快,在此期间可以减少动态链接库的数量(苹果支持最多6个非系统提供的动态链接库合并成1个),减少启动后不使用的类和方法。

main函数执行后

main函数就是创建一个UIApplication对象(内含系统功能)和一个UIApplicationDelegate(程序员在里面实现业务逻辑):

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

int main(int argc, char * argv[]) {
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

创建一个UIApplication对象用于处理APP生命周期,内存告警,UI展示,方向,openURL等,可以用UIApplicationDelegate获得这些功能的控制权。

APP的生命周期有:

Not running:未启动
Inactive:过渡的中间状态,除启动时外,还有双击home键,出现应用列表,此时APP既不是前台运行,也不是进入后台
Active:运行中,系统会分配更多的资源
Background:系统分配较少资源
Suspended:内存不足,系统kill APP

UIApplicationDelegate中可以获得这些生命周期的控制权:

main函数执行后,是从main函数开始执行到delegate提供的didFinishLaunchingWithOptions生命周期回调执行结束。想让APP启动快,在此期间可以针对业务进行梳理,将那些直到开始使用才需要初始化的功能剔除出去。

首屏渲染完成后

首屏渲染完成后主要是,非首屏其他业务服务模块的初始化,注册,配置文件的读取等。这个阶段用户已经能看到首屏了,所以主要处理的是会卡住主线程的操作,以免影响用户交互。

启动监控

上面写的感觉写了和没写一样,具体还是要靠系统工具为我们提供分析报告。可以用xcode的Time Profiler工具,它的原理是:定时(设成0.01s,太长不精确,太短本身又耗性能)抓取主线程上的方法调用堆栈,计算一段时间里各个方法的耗时。

如果对检查精度要求较高,也可以自己hook一下objc_msgSend方法来掌握所有方法的执行耗时。它的原理是:objc_msgSend是Objective-C所有方法的必经之路。

当然objc_msgSend本身是汇编语言写的(因为所有方法都会调用,所以要保证最高的性能要求),改造门槛高。内部逻辑是:先获取对象的对应类的信息,再获取方法的缓存,根据方法的selector查找函数指针,经过异常错误处理后,最后跳到对应函数的实现。

启动屏广告

在main函数执行前,IOS启动APP时有个系统提供的启动屏(Launch Screen),等系统ready后,启动屏自动消失,执行main函数,显示APP的业务首屏。

可以将启动屏(Launch Screen)贴张广告图片增加收入:

1.删除项目中的默认的storyboard文件

2.删除项目中info.plist里的【Launch screen interface file base name】:【LaunchScreen】字段

3.点击项目名,进入General tab,点击【App Icons and Launch Images】的【Use Asset Catalog】,弹出窗点击【Migrate】。在项目的Assets.xcassets里就会出现LaunchImage的配置。

4.勾上为iPhone配置启动图的配置项

5.将不同尺寸的广告图片拖进Assets.xcassets中对应的机型中。

这样启动屏(Launch Screen)就能显示我们添加的广告图片了。

闪屏广告

随着IOS速度越来越快,启动屏时间变的越来越短。所以光靠启动屏不能满足日常广告的曝光时长。

现在的做法是:启动屏(Launch Screen)仍旧贴广告图片,等启动屏消失后,APP的首屏UIWindow里addSubView显示同样的图片,过段时间再让广告图片消失。

这样对用户来说是无感知的,以为广告图片显示的时间变长了。

做法很简单,先创建个UIImageView:

#import "SplashView.h"

@interface SplashView()
@property(nonatomic, strong, readwrite)UIButton *button;   // 广告图片右上角显示【跳过】按钮
@end

@implementation SplashView
- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.image = [UIImage imageNamed:@"icon.bundle/splashscreen.jpg"];
        [self addSubview:({
            _button = [[UIButton alloc] initWithFrame:CGRectMake(330, 100, 60, 40)];
            _button.backgroundColor = [UIColor lightGrayColor];
            [_button setTitle:@"跳过" forState:UIControlStateNormal];
            [_button addTarget:self action:@selector(_removeSplashView) forControlEvents:UIControlEventTouchUpInside];
            _button;
        })];
        self.userInteractionEnabled = YES;
    }
    return self;
}

- (void)_removeSplashView{
    [self removeFromSuperview];
}
@end

在UIApplicationDelegate的didFinishLaunchingWithOptions生命周期里加上闪屏广告:

#import "SplashView.h"

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    ...

    // 添加闪屏
    [self.window addSubview:({
        SplashView *splashView = [[SplashView alloc] initWithFrame:self.window.bounds];
        splashView;
    })];
    
    return YES;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注