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

【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] 

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 06:14:36

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

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

qt5.3已经全面支持移动开发,除了mac,windows,linux,还支持ios,android,wp,meego等移动平台,本教程是作者根据自己的经验,从头讲怎么样在ios上发布自己的app,由于目前国内相关文章还比较少,可能文章里有所疏漏,或者并非最优方法. 软件准备:qt5.3 , xcode 5.1.1 编译环境: Mac os Qt5.3下载地址http://qt-project.org选择对应的Mac ox版本,支持iOS和android的版本,安装过程省略 Xcode在app

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

qt5.3已经全面支持移动开发,除了mac,windows,linux.还支持ios,android,wp,meego等移动平台,本教程是作者依据自己的经验,从头讲怎么样在ios上公布自己的app.因为眼下国内相关文章还比較少,可能文章里有所疏漏,或者并不是最优方法. 软件准备:qt5.3 , xcode 5.1.1 编译环境: Mac os Qt5.3下载地址http://qt-project.org选择相应的Mac ox版本号,支持iOS和android的版本号.安装过程省略 Xcode在a

Ios/Android h5 唤起本地APP

纠结两天(浏览器中唤起本地APP),一直找不到解决方案,今天总算基本搞定. ps:吐槽一下 魔窗那篇文章,为什么就不直接把js代码开源开源,混淆后的代码看得我好恼火 参考文章:魔窗解决方案.京东解决方案 首先是判断浏览器 // 判断浏览器 var Navigator = navigator.userAgent; var ifChrome = Navigator.match(/Chrome/i) != null && Navigator.match(/Version\/\d+\.\d+(\.

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

App WidgetsApp Widgets are miniature application views that can be embedded in other applications (such as the Home screen) and receive periodic updates. These views are referred to as Widgets in the user interface, and you can publish one with an Ap

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

在做搜芽的过程中,发现那个外包人缘做的不行,因为启动的时候会停顿,然后白屏一会,联想到几个月前我在我的三僚企业通信软件里面拉起9K-Mail的时候也会黑屏,所以决定学习一下.解决一下.这不,万能的网络还是非常有用的. 在这里总结一下. (参考及转载:http://www.2cto.com/kf/201409/339293.html) 欢迎页启动的线程由于请求和处理的数据量过大而,导致欢迎页在出现之前界面上会有一个短暂的白色闪屏停留,当然白色闪屏的停留是因为 application 的主题样式an

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

一.安装路径在哪? Android应用安装涉及到如下几个目录: system/app系统自带的应用程序,无法删除.data/app用户程序安装的目录,有删除权限.安装时把apk文件复制到此目录.data/data存放应用程序的数据.data/dalvik-cache将apk中的dex文件安装到dalvik-cache目录下(dex文件是dalvik虚拟机的可执行文件,其大小约为原始apk文件大小的四分之一).APP安装过程:复制APK安装包到data/app目录下,解压并扫描安装包,把dex文件

Android开发智能车载App(1)---android控件及属性介绍

1.展示文本控件 TextView 属性名称 描述 android:text 设置显示文本. android:textSize 设置文字大小,推荐度量单位"sp",如"15sp" android:textStyle 设置字形[bold(粗体) 0, italic(斜体) 1, bolditalic(又粗又斜) 2] 可以设置一个或多个,用"|"隔开 android:gravity 设置文本位置,如设置成"center",文本将

对ios、android开发程序员的14条忠告

————————本文摘自千锋教育(http://www.mobiletrain.org/)对ios\android开发程序员的14条忠告————————— 1.不要害怕在工作中学习. 只要有电脑,就可以通过电子阅读器阅读报纸和大多数书籍.如果你只是做好自己的本职工作以及分配的任务,那是学不到很多东西的.如果你盲目地要求更多的工作,也是不可能提升自己的.放慢脚步,先将一些基础的知识捡起来. 2.在事业上勇往直前,自己为自己负责. 大概只有十分之一的人才能得到导师的特殊照顾,如果你是十分之九中的一员

利用Mono?For?Android开发的恶意软件

近期AVL移动安全团队首次发现一款使用Mono for Android开发的恶意APP,该应用除了使用C#语言开发,还加入了Lua环境,可以执行恶意Lua脚本. Mono for Android简介 Mono for Android由Novell推出,是业界首个使用Microsoft Visual Studio 为Android平台开发Microsoft.Net应用程序的解决方案,该程序利用C#语法能进行开发基于Android和iOS的应用. Mono for Android由Mono内核运行时