5. 工程文件结构
自行打开项目工程查看...
6. 界面绘制
6.1 独立界面
Android的Activity和iOS的UIViewController,是差不多的概念,都是界面的控制器,可以在其中添加View,处理触屏事件。
特性 | Activity | UIViewController |
---|---|---|
生命周期 | onCreate onStart onResume 运行态 onPause onStop onDestroy |
viewDidLoad viewWillAppear viewDidAppear 运行态 viewWillDisAppear viewDidDisAppear viewDidUnload |
栈管理 | Activity启动模式(使用简单): standard,singleTop,singleTask,singleInstance |
UINavigationController 使用灵活 |
6.2 layout.xml vs storyborad & xib
Android主要使用xml文件来配置界面布局,灵活方便,提供5种布局方式:
FrameLayout、LinearLayout、RelativeLayout、ConstraintLayout、AbsoluteLayou。还可以通过代码动态修改布局。
也支持可视化的界面编辑,但很少用。
iOS一般通过代码来实现界面,其第3方库masonry提供了约束布局方案,和Android的ConstraintLayout非常相似。
也提供了可视化的界面编辑stroryboard和xib,但非常容易导致代码冲突,一般不用,除非单人项目。
6.4 分辨率适配
Android屏幕尺寸众多,适配略有麻烦。一般是用10801092的标注图,像素值/3density。有时个别机器需要单独适配。
iOS机型少,适配比较简单。尺寸是以宽度为基准,根据标注图的尺寸来做等比缩放。而间距则是根据以下公式来计算:
// 转换像素
#define RELAXW(x) (((x) / 1.5 * (ScreenWidth / 375.0)) / 2.0)
#define RELAXH(x) (((x) / 1.5 * (ScreenHeight / 667.0)) / 2.0)
6.5 动画
- Android动画有3种:View动画、属性动画和帧动画。可以xml配置,也可以代码配置,或者混编。
- iOS动画,有UIKit动画和Core Animation。
7. 数据存储与传递
7.1 key-value简单存储
Android的SharePreferrences和iOS的UserDefault,都提供了key-value式的简单存储。
其中前者的加载机制是一次性加载整个文件到内存,所以单文件不要存太多数据,并且value不适合存储JSON。
另外,iOS的keyChain,也是key-value存储,其中的数据在app卸载后仍然保留,通常用于存储密码和重要信息。
7.2 数据库
- Android和iOS都支持sqlite数据库。
- Android有room、realm、greenDao等sqlite开源库。
- iOS有FMDB、realm、WCDB、LKDBHelper等sqlite开源库。
7.3 文件存储
Andoird的文件可以存内置存储,也可以存sd卡,并且sd卡数据分了私有目录和公共目录两种。公共需要权限,通常用于应用间通信。
iOS的文件都存沙盒。
7.4 对象序列化
Android有两种序列化方式:Java原生的Serializable和Android特有的Parcelable。
特性 | Serializable | Parcelable |
---|---|---|
易用性 | 简单,创建版本号即可 | 复杂,要实现4个方法 |
效率 | 低(使用反射多,产生临时变量多) | 高 |
应用场景 | 文件缓存、网络传输 | Intent |
iOS序列化方式有NSArchiver、NSPropertyListSerialization(支持NSData、NSDate、NSNumber、NSString、NSArray、NSDictionary)等。
7.5 应用间数据共享
方式 | Android | iOS |
---|---|---|
网络 | Yes | Yes |
剪切板 | Yes | yes |
Content Provider | Yes | No |
Service | Yes | No |
本地socket | Yes | ? |
URL Scheme ? | Yes | |
CoreCFMessagePort | No | Yes |
CFNotificationCenter | No | Yes |
8. 线程与同步
8.1 主线程与Looper(runloop)
- Android的主线程会默认启动一个Looper,Looper自带一个消息队列,其启动后会循环“等待消息->处理消息”。所有投递到消息队列的消息,都会在Looper所在的线程里依次同步执行。
- 其它子线程,也可以通过以下代码来启动一个Looper:
Looper.prepare();
Looper.loop();
iOS的主线程会默认启动runLoop,其功能和Android的Looper是类似的。
8.2 线程构建
Android子线程实现方式有:
Thread、 ExecutorServie线程池、handler、asyncTask、HandlerThread。
iOS子线程实现方式有:
NSThread、gcd、NSOperation。其中gcd提供了同步异步、串行并行的封装,可以很简单的使用。
8.3 线程同步
Android的线程同步方式主要是Object的wait、notify方法。
final Object obj = new Object();
new Thread(){
@Override
public void run() {
//业务处理1
synchronized (obj) {
try {
obj.notifyAll();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//业务处理2
iOS的NSCondition也提供了一样的功能,用法也很类似,比如调用前要加锁。
__block NSCondition *condition = [[NSCondition alloc] init];
NSLog(@"111111 currentThread:%@", [NSThread currentThread]);
dispatch_queue_t serialQueue = dispatch_queue_create("Dan-serial",
DISPATCH_QUEUE_CONCURRENT);
dispatch_async(serialQueue, ^{
[NSThread sleepForTimeInterval:0.5];
//处理业务1
NSLog(@"222222 currentThread:%@", [NSThread currentThread]);
[condition lock];
[condition signal];
[condition unlock];
});
[condition lock];
[condition wait];
[condition unlock];
//处理业务2
NSLog(@"333333");
8.4 多线程数据安全
都支持synchronized同步代码块、Locker、信号量semaphore等。
iOS有个gcd的方法dispatch_once,可以做到代码只执行一次,通常用于单例实现。
Android的单例:
private static ActivityMgr sInstance;
public static ActivityMgr getInstance() {
if (sInstance == null) {
synchronized (ActivityMgr.class) {
if (sInstance == null) {
sInstance = new ActivityMgr();
}
}
}
return sInstance;
}
iOS的单例:
+ (instancetype)sharedInstance {
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
8.4 线程池
- Android的线程池ExecutorServie可以灵活设置线程并发数和线程队列。
- iOS的gcd提供了简单的多线程调用方式,而NSOperation则可以灵活设置线程并发数等。
网友评论