【iOS-Android开发对照】之 APP入口

[图片 Android vs iOS]

提纲

  1. 对照分析iOS,Android的入口,

  2. iOS,Android的界面单元

  3. 为什么要有那样的生命周期

  4. 继承和抽象类怎么写,比如工厂模式

  5. 对象的强弱。iOS的特色

程序入口 (Entry Point)

#首先来看iOS应用的入口:

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

和全部C程序一样。main函数是Objective-C程序的入口。

虽然这个main方法返回 int,但它并不会真正返回。它会一直存在于内存中,直到用户或者系统将其强制终止.

上面的UIApplicationMain其来自 UIKit,是一个非常重要的函数。

说一下參数,前两个參数大家都懂。

第三个參数,是UIApplication类名或者是其子类名。假设是nil,则默认使用UIApplication类名。

第四个參数,是AppDelegate类作为应用的托付对象,用来监听应用生命周期相关的托付方法。

这个UIApplication的核心作用是提供了iOS程序执行期间的控制和协作工作。

它创建了App的几个核心对象如: UIApplicationDelegate UIWindow, UIView,来处理一下过程:

  1. 程序入口main函数创建UIApplication实例和UIApplication代理实例。

  2. 从可用Storyboard文件载入用户界面

  3. 调用AppDelegate自己定义代码来做一些初始化设置

  4. 将app放入Main Run Loop环境中来响应和处理与用户交互产生的事件

这个UIApplication对象在启动时就设置 Main Run Loop,而且使用它来处理事件和更新基于view的界面, Main Run Loop就是应用程序的主线程。

[图片 iOS, swift, Android举牌]

说说Swift的入口:

在Swift语言其中,编译器不会再去寻找 main 函数作为程序的入口,而是一个main.swift文件.

该文件里的第一行代码就默觉得是程序的入口, 能够加入例如以下代码:

UIApplicationMain(C_ARGC, C_ARGV, nil,
NSStringFromClass(AppDelegate))

没错,就是之前提到的UIApplicationMain

这里 C_ARGC, C_ARGV 全局变量 就是main函数中的

argc, argv。

另外,能够在Swift文件里加入 @UIApplicationMain 标签注明项目入口。这样做会让编译器忽略main.swift入口文件。而将标注有@UIApplicationMain标签的文件当做入口文件。

#再来看看Android的:

Android程序你找不到显式的main方法

虽然java也有main方法,可Android似乎却找不到main。

对于这个问题。有非常多解释。

Stackoverflow上有解释说没有main是由于不须要main,系统生成activity并调用其方法,应用默认启动已经把main取代了,因此不须要用main方法。

那么程序的入口在哪里? 我们从Application開始看.

每一个Android程序的包中。都有一个manifest文件声明了它的组件。我们能够看到例如以下代码:

<manifest  ...
<application ...
<activity android:name=".MainActivity" android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>

在这个xml写成的manifest文件里,<application/> 标签在最外层。

其中,这个标记了android.intent.category.LAUNCHER 的 <activity/> 就是程序启动的默认界面。

可是它们不是真正的入口。

Android应用程序的真正入口为 ActivityThread.main方法

这是一个隐式的入口,代码做了一定简化例如以下:

public static void main(String[] args) {
//一些检測预设值...
Looper.prepareMainLooper();// 创建消息循环Looper
ActivityThread thread = new ActivityThread();
thread.attach(false);
if (sMainThreadHandler == null) {
sMainThreadHandler = thread.getHandler(); // UI线程的Handler
}
AsyncTask.init();
Looper.loop(); // 执行消息循环
throw new RuntimeException("Main thread loop unexpectedly exited");
}

#深入一下:

继承关系:

java.lang.Object
↳ android.content.Context
↳ android.content.ContextWrapper
↳ android.app.Application

Android的最底层是Linux Kernel, iOS是XNU Kernel,它们有什么差别呢?

Activity与UIViewController

Android的Activity和Fragment是最主要的界面组成,而IOS是UIViewController。差点儿全部的View和空间都会放在Activity和UIViewController中。

在之上有不少扩展的:

Android: FragmentActivity, AppCompatActivity

IOS: UITableViewController, UICollectionViewController

我们对照一下继承关系:

Android: Activity->ContextThemeWrapper->ContextWrapper->Context

IOS: UIViewController->UIResponder->NSObject

IOS差点儿全部的基类都是NSObject,Android中也有Object,一般作为Model层对象的基类。

生命周期

这方面资料非常多,我简单说一下:

Android的Activity, onCreate() 中初始化操作, onResume()中能够加一些改变界面和状态的操作;

IOS的UIViewController, -viewDidLoad 中初始化操作, -viewWillAppear 中能够加一些改变界面和状态的操作;

对照一下:

Activity: onCreate() –> onStart() –> onResume( )–> 执行态 –> onPause() –> onStop() –> onDestroy()

UIViewController: -viewDidLoad –> -viewWillAppear –> -viewDidAppear –> 执行态 –> -viewWillDisappear –> -viewDidDisappear

这里补充一个Android的

Fragment:* *onAttach() –> onCreate() –> onCreateView() –> onActivityCreate() –> onStart() –> onResume( )–> 执行态 –> onPause() –> onStop() –> onDestroyView() –> onDestroy() –> onDetach()

Android与IOS都使用 堆栈 的数据结构 存储Activity和UIViewController.

Android关于Activity的堆栈, 能够搜索taskAffinitylaunchMode。同一应用全部Activity具有相同的亲和性(taskAffinity),可通过Itent FLAG设置。也可在AndroidManifest中设置.

IOS中的UINavigationController通过堆栈来UIViewController.

界面跳转与传值

Android: Activity能够使用Intent,Fragment使用Bundle。 对于界面回调传值。通过startActivityForResult()启动和onActivityResult()接收。

IOS: 在初始化UIViewController对象时,直接给对象中的变量赋值。 对于界面回调传值,能够自己定义接口(Delegate),也能够使用通知(Notification)

结构类型

类代码

//Android
A.java Class A extends B implements C
//IOS
A.h @interface A : B
A.m @implementation A <C>

强引用和弱引用

Android:

有四种引用类型,强引用(StrongReference),软引用(SoftReference),弱引用(WeakReference),虚引用(Phantom Reference)。

一般创建的对象都是强引用。所以当内存空间不足时,Java虚拟机宁愿抛出OOM异常。也不会任意回收强引用的对象。

对于软引用。内存空间足够,垃圾回收器就不会回收它,能够做图片的缓存。

对于弱应用,使用场景比如:在Activity中使用Handler时,一方面须要将其定义为静态内部类形式,这样能够使其与外部类(Activity)解耦,不再持有外部类的引用,同一时候由于Handler中的handlerMessage一般都会多少须要訪问或改动Activity的属性。此时。须要在Handler内部定义指向此Activity的WeakReference,使其不会影响到Activity的内存回收同一时候,能够在正常情况下訪问到Activity的属性。

IOS:

使用__weak, __strong用来修饰变量,默认声明一个对象 __strong。

在强引用中,有时会出现循环引用的情况,这时就须要弱引用来帮忙(__weak)。

强引用持有对象,弱引用不持有对象。

强引用能够释放对象,但弱引用不能够。由于弱引用不持有对象,当弱引用指向一个强引用所持有的对象时,当强引用将对象释放掉后,弱引用会自己主动的被赋值为nil,即弱引用会自己主动的指向nil。

私有和公有

IOS中有-``+方法。-相当于Android中的private,

+相当于Android中的public static。

对于全局变量,IOS是放在AppDelegate中或者使用#define声明在.h中。

Android相同,放在Application中 或者类中使用public static。

当然。都能够使用单例类。

基本控件

对照一些经常使用的

Android IOS
TextView UILabel
TextEdit UITextField UITextView
ImageView UIImageView
Button UIButton
Switch UISwitch
ListView TableView
GridView CollectionView

对照一下继承:

Android Views -> View

IOS Views -> UIView -> UIResponder -> NSObject

Java实际上不论什么对象都是直接或间接继承自Object,写extends Object和不写extends是等价的。

因此 Android和IOS的对象, 本质上都是从顶级的Object继承来的。

Amazing~

关于继承和抽象类

App启动的堆栈原理

怎样写工厂模式

App的启动程序入口

文章和代码一样,也须要不断去梳理,不断迭代。

參考

iOS

http://www.jianshu.com/p/aa50e5350852

http://www.cnblogs.com/ydhliphonedev/archive/2012/07/30/2615801.html

http://swifter.tips/uiapplicationmain/

http://blog.ibireme.com/2015/05/18/runloop/

http://swifter.tips/uiapplicationmain/

Android

http://www.cnblogs.com/lwbqqyumidi/p/4151833.html

https://sites.google.com/site/terrylai14/home/android-context-yuan-li

http://blog.csdn.net/chenzheng_java/article/details/6215986

http://blog.csdn.net/chenzheng_java/article/details/6216621

http://blog.csdn.net/bboyfeiyu/article/details/38555547

其它

Android 程序入口 application onCreate()后都做了什么,这里有个歪果仁打印出了onCreate后堆栈显示的日志:

MainActivity.onCreate(Bundle) line: 12
Instrumentation.callActivityOnCreate(Activity, Bundle) line: 1047
ActivityThread.performLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2627
ActivityThread.handleLaunchActivity(ActivityThread$ActivityRecord, Intent) line: 2679
ActivityThread.access$2300(ActivityThread, ActivityThread$ActivityRecord, Intent) line: 125
ActivityThread$H.handleMessage(Message) line: 2033
ActivityThread$H(Handler).dispatchMessage(Message) line: 99
Looper.loop() line: 123
ActivityThread.main(String[]) line: 4627
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]
Method.invoke(Object, Object...) line: 521
ZygoteInit$MethodAndArgsCaller.run() line: 868
ZygoteInit.main(String[]) line: 626
NativeStart.main(String[]) line: not available [native method]

【iOS-Android开发对照】 之 APP入口的更多相关文章

  1. qt-qml移动开发之在ios上开发和部署app流程简单介绍

    qt5.3已经全面支持移动开发,除了mac,windows,linux.还支持ios,android,wp,meego等移动平台,本教程是作者依据自己的经验,从头讲怎么样在ios上公布自己的app.因 ...

  2. 基于Android开发的天气预报app(源码下载)

    原文:基于Android开发的天气预报app(源码下载) 基于AndroidStudio环境开发的天气app -系统总体介绍:本天气app使用AndroidStudio这个IDE工具在Windows1 ...

  3. Ios/Android h5 唤起本地APP

    纠结两天(浏览器中唤起本地APP),一直找不到解决方案,今天总算基本搞定. ps:吐槽一下 魔窗那篇文章,为什么就不直接把js代码开源开源,混淆后的代码看得我好恼火 参考文章:魔窗解决方案.京东解决方 ...

  4. (转)Android开发出来的APP在手机的安装路径是?

    一.安装路径在哪? Android应用安装涉及到如下几个目录: system/app系统自带的应用程序,无法删除.data/app用户程序安装的目录,有删除权限.安装时把apk文件复制到此目录.dat ...

  5. Android开发之创建App Widget和更新Widget内容

    App WidgetsApp Widgets are miniature application views that can be embedded in other applications (s ...

  6. Android开发之定义app在手机的安装位置

    定义app在手机的安装位置,可以通过在清单文件中添加属性 android:installLocation="" 该属性有三个值:auto(自动),preferExternal(外部 ...

  7. android 开发 实现一个app的引导页面,使用ViewPager组件(此引导的最后一页的Button会直接写在最后一页布局里,跟随布局滑进滑出)

    基本ViewPager组件使用方式与我之前写的https://blog.csdn.net/qq_37217804/article/details/80332634 这篇博客一致. 下面我们将重点详细解 ...

  8. android 开发 实现一个app的引导查看页面(使用ViewPager组件)

    我们安装完app后第一次打开app,通常都会有一个翻页图片形式的app引导简介说明.下面我们来实现这个功能.ViewPager这个组件与ListView和RecyclerView在使用上有很高的相似处 ...

  9. Android开发之解决APP启动白屏或者黑屏闪现的问题

    在做搜芽的过程中,发现那个外包人缘做的不行,由于启动的时候会停顿,然后白屏一会,联想到几个月前我在我的三僚企业通信软件里面拉起9K-Mail的时候也会黑屏,所以决定学习一下.解决一下.这不,万能的网络 ...

  10. Android 开发之修改 app 的字体大小(老人模式)

    新的需求(可参见 微信和QQ改变字体): app 字体不随着系统字体大小变化 app 设置中有设置字体大小的开关,变大以后,整个 app 字体变大. 解决方案:(字体需要采用 dp 为单位,不能使用 ...

随机推荐

  1. Emmet Documentation

    src:http://docs.emmet.io/cheat-sheet/ Emmet Documentation Syntax   Child: > nav>ul>li <n ...

  2. C# 两时间,时间间隔

    #region 返回时间差        public static string DateDiff(DateTime DateTime1, DateTime DateTime2)        {  ...

  3. Duplicate Symbol链接错的原因总结和解决方法-b

    duplicate symbol是一种常见的链接错误,不像编译错误那样可以直接定位到问题的所在.但是经过一段时间的总结,发现这种错误总是有一些规律可以找的.例如,我们有如下的最简单的两个类代码: // ...

  4. 【技术贴】关闭CMD错误提示声音

    关掉后,整个世界清静多了. cmd打开后 1. 禁用“嘀嘀”声的设备来源,这是由beep驱动服务所提供,可以将beep驱动的启动类型设置为禁用,可以打开CMD窗口,运行以下命令:永久禁用错误声音 sc ...

  5. PS命令删除所有EXCHANGE2013内用户邮件

    因为在测试的时间产生了大量测试邮件,所以在正式上线前,要删除所有用户的邮件. 命令如下: Get-Mailbox | Search-Mailbox  -DeleteContent

  6. linux使用su切换用户提示 Authentication failure的解决方法& 复制文件时,报cp: omitting directory `XXX'

    linux使用su切换用户提示 Authentication failure的解决方法:这个问题产生的原因是由于ubtun系统默认是没有激活root用户的,需要我们手工进行操作,在命令行界面下,或者在 ...

  7. [转贴]实践:C++平台迁移以及如何用C#做C++包装层

    终于有个C++ 如何调用C#类库的文章,收藏之 在前面,我们看过OpenTK与MOgre,这二个项目都是C#项目,但是他的实现都是C++.他们简单来说就是一个包装层.常见的包装方式有二种,一 种就是我 ...

  8. [转贴]WebService的简单实现 C++

    WebService的简单实现 一.socket主机创建和使用过程 1.socket()//创建套接字 2.Setsockopt()//将套接字属性设置为允许和特定地点绑定 3.Bind()//将套接 ...

  9. C++ Primer 随笔 Chapter 4 数组和指针

    1.数组:数组是由类型名.标识符和维数组成的符合数据类型,类型名规定了存放在数组中的元素类型,维数规定数组中包含元素的个数而标识符就是数组的名称.例如: int  arr[10]; 其中 int 是类 ...

  10. POJ_3666_Making_the_Grade_(动态规划)

    描述 http://poj.org/problem?id=3666 给一串坡的高度,现在要调整某些点,使整个坡单调不降或单调不升.调整的花费为原高度与先高度的差的绝对值,问最小花费(可单增可单降). ...