【iOS-Android開發對比】 之 APP入口

來源:互聯網
上載者:User

標籤:android   ios   開發   

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

結構類型類代碼
//AndroidA.java Class A extends B implements C
//IOSA.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入口

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.