
ios的推送不同于安卓。我们的项目在前台、后台、杀死进程的三种情况都能收到通知。归更到底其实就一个问题:如何找到最上层的VC,来进行push *** 作。(这里我就不赘述极光推送的集成了,可以看官方文档,文档在手,天下我有。)
1.当杀死进程时
这个时候app收到通知了,因为程序已经完全退出了。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
}
这个方法肯定会走的,相当于重启了你的项目。launchOptions 的是否为nil 可以判断出有没有远程推送。这是知识点,你要知道。
2.在前台或者后台运行程序
这个时候点击消息横栏进来就直接调用极光代理。
以上的两种情况最终我们都会在点击横栏的代理中来处理
// iOS 10 Support---点击通知栏横幅调用
- (void)jpushNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler {
NSDictionary * userInfo = response.notification.request.content.userInfo
NSLog(@"--推送消息---%@",userInfo)
if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
//则是远程通知---处理远程通知并显示
[JPUSHService handleRemoteNotification:userInfo]
NSLog(@"yuancheng111")
}
[UIApplication sharedApplication].applicationIconBadgeNumber=0
[JPUSHService resetBadge]//清空JPush服务器中存储的badge值
completionHandler(UIBackgroundFetchResultNewData)
//这里可以根据收到的推送内容来跳转到指定的地方;
[self mastePushViewController:userInfo]
}
// push方法
- (void)mastePushViewController:(NSDictionary *)infoDic{
在这里我们需要进行跳转到指定页面的处理。那么就有一个问题,我们的项目工程里有的页面是presented出来的,那么久无法进行push。那么这里我们就要进行找topVC,并且这个topVC是需要我们进行处理的,是需要具有导航的(navigationController)。
//找当前VC
UIViewController * currentVC = [self getcurrentTopViewController]
NSLog(@"controllerName=%@",NSStringFromClass([currentVC class]))
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//跳转到指定页面
[currentVC.navigationController pushViewController:vc animated:YES]
})
}
//找到当前视图控制器
- (UIViewController *)getcurrentTopViewController {
UIViewController *blockViewController = [UIApplication sharedApplication].keyWindow.rootViewController
while (blockViewController.presentedViewController) {
blockViewController = blockViewController.presentedViewController
}
if (![blockViewController isKindOfClass:[UITabBarController class]] &&
![blockViewController isKindOfClass:[UINavigationController class]]) {
UIViewController *currentChildVC
if (blockViewController.childViewControllers.count) {
currentChildVC = blockViewController.childViewControllers.lastObject
}
while (currentChildVC) {
blockViewController = currentChildVC
if ([blockViewController isKindOfClass:[UITabBarController class]]) {
blockViewController = [(UITabBarController *)blockViewController selectedViewController]
}
if ([blockViewController isKindOfClass:[UINavigationController class]]) {
blockViewController = [(UINavigationController *)blockViewController topViewController]
}
}
}
if ([blockViewController isKindOfClass:[UITabBarController class]]) {
blockViewController = [(UITabBarController *)blockViewController selectedViewController]
}
if ([blockViewController isKindOfClass:[UINavigationController class]]) {
blockViewController = [(UINavigationController *)blockViewController topViewController]
}
return blockViewController
}
到这就已经处理了点击通知栏跳转到指定页面的功能。但是我在项目中遇到个比较坑的地方是 当我杀死进程后接受到通知后,点击通知栏打开app,并不能进行跳转。(在前台和app退到后台都没有问题),重新打开app肯定是到首页,我所找到的当前控制器也是,可就是
//跳转到指定页面
[currentVC.navigationController pushViewController:vc animated:YES]执行了但是并没有进行跳转。
然后我试了下
UIViewController * currentVC = [self getcurrentTopViewController]
NSLog(@"controllerName=%@",NSStringFromClass([currentVC class]))
self.tabBarController= (UITabBarController *)[UIApplication sharedApplication].delegate.window.rootViewController
if ([VCStr isEqualToString:@"app主页"]) {
[self.tabBarController.selectedViewController pushViewController:vc animated:YES]
}else{
[currentVC.navigationController pushViewController:vc animated:YES]
}
就可以进行跳转了。我tm就懵逼了。没弄明白是怎么回事(希望有大神能指点)。
需求是完成了,但是作为一个有追求的会写诗的码农,我觉得还是要好好研究下。
使用极光/友盟推送,APP程序杀死后为什么收不到推送
一般的推送讯息,注册了之后就可以进行推送的,因为已经上传了装置号,不过要保证程式退出了之后,但在后台有一个接收程序。
苹果系统和安卓不一样就在于安卓彻底关闭某一应用程式的程序以后接受不到讯息 一个是推送 一个是获取推送 安卓没有统一的伺服器为装置推送相关通知
在iOS系统上面如果使用极光的自定义讯息, 在app杀死之后是接收不到的.
在Android系统上面,极光推送实际上使用的还是socket长连线维持推送通道的, 当手机中的极光socket全部断开之后就无法接收推送了. 全部断开是指所有使用了极光SDK的app, 假设A,B都使用了极光SDK,那么当B杀死A保留的情况下,依然可以接收B的推送当AB全部关闭则无法接收.
android 极光推送与友盟推送哪个比较好
个人感觉极光比较好,因为极光毕竟开始就是主要做推送这块的。
android 友盟推送为什么解除安装重灌还是能收到推送appdelegate里有个方法,-(void)application:(UIApplication*)applicationdidReceiveRemoteNotification:(NSDictionary*)userInfo收到推送讯息后就会呼叫,你在这里读取讯息,再以通知的形式传送到你要处理的指定页面即可
1 Process.killProcess 和 System.exit(0) 两个都会 kill 掉当前进程。你可以打开 DDMS 查看进程号,或 adb shell 进入 shell 然后 ps 一下,进程确实被 kill 掉了。
2 如果是在第一个 Activity 调用 Process.killProcess 或 System.exit(0) 都会 kill 掉当前进程。
但是如果不是在第一个 Activity 中调用,如 ActivityA 启动 ActivityB ,你在 ActivityB 中调用
Process.killProcess 或 System.exit(0) 当前进程确实也被 kill 掉了,但 app 会重新启动,
又创建了一个新的进程。(这是我同事发现的)
这点还不是很明白,我估计 android os 认为 app 是被意外终止的(如内存不足),os 底层有监听服务,
app 被意外终止会自动重启。
3 在测试极光推送的时候,发现退出 app 后就收不到推送了。后来发现是调用了 System.exit(0) 的原因。
首先 service 也是在进程中的,在主线程中,所以 service 中如果有耗时 *** 作也要开启另外的线程来处理。
当调用 System.exit(0) 或 Process.killProcess 的时候进程被 kill 掉了,进程里的所有东西当然包括 service 肯定
也没了。由于极光推送 pushservice 被 kill 掉了,所以退出 app 后就收不到推送了。
4 还没完,戏剧性的事情发生了,刚退出 app 由于 kill 掉了进程,服务没了,所以收不到推送。但是过了大约1分钟左右居然又能推过来了。
原来是和 service 的 onStartCommand 的返回值有关
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("lelsie", "service onStartCommand")
return START_STICKY
//return START_NOT_STICKY
}
如果返回 START_STICKY 是说服务应该一直运行除非我们手动停止它。极光 pushservice 返回的肯定是 START_STICKY。
所以1分钟之内系统又重启了服务,当然会先为 app 创建一个新的进程,也就是重启了 app, 同样你可以在 DDMM 中查看进程的杀死与新进程的重建。
我在手机上截了 2 张图
第一个图是在调用了 Process.killProcess 或 System.exit(0) 之后的图,可以看到进程已不存在了,服务当然也不在了。显示正在重新启动。
第二个图是服务重启以后的正常状态,所以 1-2分钟后又能接收到推送了。
第三个图是 DDMS 截图
5 其实 Process.killProcess 或 System.exit(0) 都不应该直接调用, 进程是由 os 底层进行管理的,android 系统会自己进行处理回收进程。
退出应用你就直接 finish 掉 activity 就行了。
正常情况下 back 键退出应用以后 os 就会回收 app 进程, 但当 app 中有推送服务等需要长时间运行的服务时 os 就不会 kill 掉进程,也就是说应用将一直在线。 即使你手动 kill 掉进程, 进程也会自动重启。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)