ARouter的坑

navigation()是使用application的context去发起跳转的,有些场景要注意特别是使用Intent.FLAG_ACTIVITY_CLEAR_TOP

FLAG_ACTIVITY_NEW_TASK要慎用,要结合上下环境,因为等于是使用了新 task,导致很多变量的值都消失了。

在ARouter里还是使用navigation(this)靠谱, 并且withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP)
withFlags 只用一次

1
2
3
ARouter.getInstance().build(ARouterPathType.MainActivity)
.withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.navigation(this);

当出现
.withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.navigation();

会报错

1
Caused by: android.util.AndroidRuntimeException: Calling startActivity() from outside of an Activity  context requires the FLAG_ACTIVITY_NEW_TASK flag. Is this really what you want?

.withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
.navigation(this);
正常,Intent.FLAG_ACTIVITY_CLEAR_TOP生效 建议使用这种

.withFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK)
.navigation();
正常,Intent.FLAG_ACTIVITY_CLEAR_TOP生效

1
2
3
@Autowired(name = OpenSourceARouter.DataSetService)
@JvmField
internal var dataSetService: DataSetService? = null

kotlin使用注解要用@jvmField不然会报private不能注解的错误

ios os工程调用swift方法

按照网上的教程

1、新建一个oc工程

2、找到工程的embed asset Packs in Product Bundle,设置为Yes

3、新建一个swift文件,类似

1
2
3
4
5
6
7
import Foundation

public class TestSwift : NSObject {
func printLog() {
print("hello")
}
}

4、在调用处引用头文件

1
#import "TestSwiftWifthOc-Swift.h" //TestSwiftWifthOc为当前工程名字

然后就可以调用了

1
2
TestSwift *testSwift = [[TestSwift alloc]init];
[testSwift printLog];

5、但是有些xcode创建的工程会报错,比如我的macbook

6、进去TestSwiftWifthOc-Swift.h头文件里面看,系统帮我们创建了TestSwift类,但是没有方法,很奇怪

1
2
3
4
SWIFT_CLASS("_TtC16TestSwiftWifthOc9TestSwift")
@interface TestSwift : NSObject
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

7、最后找到了解决方法,在swift方法上加注解@objc,问题解决
、、、
import Foundation

public class TestSwift : NSObject {
@objc func printLog() {
print(“hello”)
}
}
、、、

RxJava多个api的处理

RxJava多个api的处理

merge 单独输出,统一结束回调,api同时出去

zip 封装在一起,最后统一输出和结束回调,api同时出去

flatMap 一个请求回来再进行下一个请求

ios storyboard的入门

0、如何让storyboard的ViewController控件绑定代码的ViewController

1
2
在storyboard里面创建了一个ViewController后,要在代码那边创建一个
自定义Controller去继承UIViewController,然后在storyboard里面选择对应的custom class为自定义Controller,就可以完成关联

1、如何让storyboard与代码进行事件交互。

1
2
3
在storyboard里拉出一个label和一个button,然后屏幕调出来两个界面,一个storyboard,一个controller的代码框
选中storyboard里的label,右键按住,拉到代码框的@interface @end中间,就会出现label的定义
选中storyboard里的button,右键按住,拉到代码框的@implementation @end中间,就会出现button的事件定义

1、出现Launch screens may not set custom classnames问题

1
2
图中所画的不要打勾
![](http://pd4ketimy.bkt.clouddn.com/15394960479910.jpg)

4、如何设定storyboard的入口

1
2
storyboradviewController里面设置,如下图,红色那个选项打勾
![](http://pd4ketimy.bkt.clouddn.com/15394966538273.jpg)

5、多个storyBoard,怎么设置特定的storyBoard

1
项目->info.plist->Main storyboard file base name 设置为指定的storyBoard即可

6、使用storyBoard生成viewController,关联viewController后,代码pushViewController 黑屏

1
2
3
4
5
6
7
8
SecondController *controller = [[SecondController alloc]init];
[self.navigationController pushViewController:controller animated:YES];

使用storyBoard创建的时候已经有了一个viewController实例,不应该在代码里再alloc init另外一个controller,解决方案就是要去storyBoard里面把viewController拿出来

UIStoryboard *main =[UIStoryboard storyboardWithName:@"LaunchScreen" bundle:nil];
SecondController *b = [main instantiateViewControllerWithIdentifier:@"SecondController"];
[self.navigationController pushViewController:b animated:YES];

7、回调的使用,
block
定义typeof
方法里面写

8、cocopad的安装使用

9、当改用cocoapods来管理依赖,
编译的时候提示 “ objc ld: library not found for -lPods”
这是因为打开的方式不对
之前打开的是.xcodeproj
用cocoapods后打开的是.xcworkspace

target -> Build Phases -> Link Binary With Libraries -> 添加.a文件

10、数据库fmdb->orm

11、UITable的使用

12、storyboard使用xib的自定义view
新建一个.h .m文件叫ItemView
新建一个.xib文件叫ItemView
在xib文件里,设置view customView为空 设置file’s Owner的custionView为ItemView
storyboard里拖出一个UIview,custom class指向ItemView
在ItemView.m里添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@property (strong, nonatomic) UIView *view;

// 初始化CustomView的时候添加xib上的view
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self){
[self addSubview:self.view];
}
return self;
}
// 获取xib中的view
- (UIView *)view{
if (!_view) {
_view = [[NSBundle mainBundle] loadNibNamed:@"ItemView" owner:self options:nil].lastObject;
}
return _view;
}

- (void)layoutSubviews{
[super layoutSubviews];
//设置大小
self.view.frame = self.bounds;
}

13、给非UiButton的控件加点击事件

1
2
3
4
5
6
7
8
[_mIBSetDeviceTime setUserInteractionEnabled:YES];
[_mIBSetDeviceTime addGestureRecognizer:[[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(clickCategory:)]];

-(void)clickCategory:(UITapGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer view] == _mIBSetDeviceTime) {
NSLog(@"_mIBSetDeviceTime");//判断是哪个控件的点击
}
}

14、fragment如果要使用kotlin的 apply plugin: ‘kotlin-android-extensions’

那么必须放在onActivityCreated后才能生效
onCreateView里面的是为空的

模块化

  1. implementation 要换成api
  2. 分别换成debugApi,releaseApi,androidTestImplementation,testImplementation
  3. 吧utils,constant,公共方法按照module分离,放在该在的模块内,注意通信机制,注意引用
  4. 注意在module中id不是final,switch(id)改成if else,而butterknife要用R2.id.xxx, apply plugin: ‘com.jakewharton.butterknife’
  5. aroute 里面的path在不同的module要写成不一样的module方式,比如/app/a,/module/bkugo
  6. apply plugin: ‘com.alibaba.arouter’
  7. app是否有引用具体的module
  8. Constant,Eventbus,startActivity

关于在闲鱼上被骗的经历

1、一定不能使用微信或者支付宝单独支付,要用闲鱼上交易,因为即使发生问题,也有订单号等交易痕迹
2、面交测试实物时要淡定,尽量拖时间测试,如果对方要求尽快面交,这其中多半是有问题,如果对方不同意花多时间测试,那就取消交易
3、面交前要先做功课,尽量用现场能看到的东西,比如id号,imei码等识别出这机器是什么类型的机器
4、搜索东西的时候一定是要信用高,并且是自用的,能提供购买渠道或者检测图证据为先,如果以各种理由塘塞的,建议取消交易
5、尽量在交谈中留下对方电话号码,微信号,淘宝号等可以证明身份的东西,以便后面出了问题追溯

gradle-wrapper.properties设置gradle 4.4报错 Connect to d29vzk4ow07wi7.cloudfront.net:443 xxx

gradle-wrapper.properties设置gradle 4.4后报错。。。Connect to d29vzk4ow07wi7.cloudfront.net:443

尝试过:
1、本来是想下gradle3.3,然后一直gradle下载不了,改成gradle4.4后发现报错
2、怀疑是网络问题,从as上下载链接https://downloads.gradle.org/distributions/gradle-3.3-all.zip来看,直接使用浏览器是可以下载了,并且是不翻墙的情况
3、尝试过翻墙,设置代理,结果一样报超时

后来上网找答案,搜索关键词Connect to d29vzk4ow07wi7.cloudfront.net:443,,,
有一种解决方案很靠谱,在项目build.gradler 的jcenter()前添加上mavenCentral();
尝试了一下,居然解决了问题,看来是访问不到jcenter.

具体为什么加了mavenCentral()在jcenter()前面就行了,没有深究。后来想通了,as旧版本默认资源放放到mavenCentral,而新版本放到了jcenter()。。

Charles将指定的请求改为固定返回值,开发调试专用

####看了之后 https://blog.csdn.net/u014115673/article/details/54984084 发现确实是经验之谈,不用自己写在代码里,直接连上手机代理,懒就直接复制过来了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
方法一:本地映射
Charles进行抓包
选择某一个网络请求 > 鼠标右键 Save Response...
如果该请求返回的是一个json串,保存文件时需要保存rename.json
需要更改的请求点击右键 Map Local.. 指定到本地保存的renam.json.
通过在本地更改rename.json就可以自动的更改请求的返回值。

方法二:打断点
选择某一个网络请求 > 鼠标右键 Breakpoints
然后点击 Execute 执行,然后编辑返回值
缺点:容易请求超时。还没等你调整完返回数据,app那边已经请求超时了。

方法三:远端映射
App内部的请求映射到远端写好的接口。推荐一个东东 Mocky:http://www.mocky.io/。

方法四:rewrite
菜单栏 Tools —> Rewrite
根据自己的需求重写…。
推荐网址:http://www.cnblogs.com/wonyun/p/5586746.html

aspectj接入后发现一些问题

android aop切面使用aspectj在混淆方面发现比较麻烦的事情

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
在每一个被hook的文件生成类似下列的代码
private static final b ajc$tjp_0 = null;
static {
ajc$preClinit();

}

private static void ajc$preClinit() {
e eVar = new e("DialogUtils.java", DialogUtils.class);
ajc$tjp_0 = eVar.a(c.a, eVar.a("9", "showYesterdayEarningPopup", "com.kalengo.loan.utils.DialogUtils", "android.app.Activity:boolean:com.kalengo.loan.bean.UserAssetsInfoBean", "activity:isNewUser:userAssetsInfoBean", "", "void"), 83);
ajc$tjp_1 = eVar.a(c.a, eVar.a("9", "showSimpleTipsPopup", "com.kalengo.loan.utils.DialogUtils", "android.app.Activity:int:com.kalengo.loan.callback.DoCallback", "activity:type:callBack", "", "void"), Opcodes.I2C);

}

在被hook的方法插入:
KAspect.aspectOf().onDialogUtilsMethod(e.a(ajc$tjp_3, null, null, context));

####由此可见,被hook的方法和被hook的类是不能被混淆的,虽然aspectj是编译期间做的植入,但是为了不嵌入代码,使用了反射的方式,这导致混淆会有一定影响。

后面不打开混淆来检查是否是这样的方式,从代码的跳转看有没有可能直接指定植入代码,否则调研其他aop框架