Bugly 技術乾貨系列內容主要涉及移動開發方向。是由 Bugly 邀請騰訊內部各位技術大咖,經過平常工做經驗的總結以及感悟撰寫而成,內容均屬原創。轉載請標明出處。css
怎樣能在最快的時間內,實現一個最新版本號 android app 的 pad 化呢?從拿到一個大型手機 app 代碼開始開發到第一個其全新 pad 版本號的公佈,咱們用了不到3個月時間給出了一份愜意的答案。html
採用最新版本號手機 APP(以後稱爲 MyApp)代碼。實現其 Pad 化,爲平板和大屏手機用戶提供更好的體驗。java
爲實現 MyApp 的 Pad 化工做。需要咱們首先來了解一下 MyApp 項目經典頁面的構成以及 Pad 化後的頁面結構的變化。android
現在主流手機 APP 主頁一般採用標籤欄加標籤內容方式顯示。而經過主頁進入的二級頁面所有採用全屏方式展現。web
比方手機 QQ,微信,支付寶等等都是採用 Tab 欄方式爲主,進入一個詳細功能後,全屏打開。咱們項目也是如此。微信
如下看一下 MyApp 項目手機端的頁面構成圖。markdown
左側是一個 Tab 欄(區域1)加 Tab Content(區域2)構成的頁面。右側是在 TabContent 中點擊詳細功能後進入的一個功能詳情頁面(全屏區域3)。
查看代碼,發現除 TabContent 區域2,從主頁開始到其它全屏顯示的頁面所有採用 Android Activity 組件實現。經統計得出大概有幾百個 Activity。架構
這些 Activity還包括比方Web進程。peak 進程(圖片選擇查看)等其它非主進程 Activity。app
瞭解了手機 MyApp 頁面構成後,還要來看 Pad 化後 UI 結構的變化,經過對照來探索 Pad 化最佳的實現方案。ide
如下是咱們的 PAD 版本號頁面結構圖。
由於 Pad 平板的空間要遠大於手機空間。因此。在主頁中 Pad 所展現的內容要比手機不少其它。經過觀察設計圖發現。整個頁面分爲了3塊區域,與手機端頁面的1,2,3區域一一對應。Tab 欄被移到了左側1區,Tab Content 被移到了中間2區。而在2區打開的 Details 頁面則要求在3區展現,而再也不是像手機 APP 同樣全屏展現。
經過了解 MyApp 項目經典頁面構成和 pad 版頁面結構的變化,以及高速Pad 化的原則,咱們開始了對手機 APP pad 化實現方案的漫漫探索。
首先想到的是,既然手機APP頁面主要是由Activity構成。那麼咱們能不能把 Activity 縮小。讓多個 Activity 在同一屏幕顯示呢。很是快咱們的方案1出來了。
方案1。假設把設計圖的整個頁面稱爲主 Activity,主 Activity 全屏顯示不變,在主 Activiy 中打開的新 Activity (稱爲A)縮小顯示在設計圖3區,咱們就可以實現 Pad 設計的要求。那麼咱們詳細實現步驟爲:
1。A類 Activity 繼承 Base Activity
2。改動 Base Activity 的 window 的起始座標x和寬度 width,讓其恰好位於3區。
3,A類 Activity 背景改成透明
4,讓在A類 Activity 繼續打開的 Activity。反覆1,2,3,4步驟。
但是很是快就發現了問題。
1. 在當前 Tab 打開 Activity A,切換 Tab 後 A Activity 仍然顯示。
2. 每個 Tab 打開的 Activity,都處於同一個 Activity 棧中,按打開前後順序加入,點擊返回鍵也是順序退出的。這樣每個 Tab 中打開的Activity 都混在一塊兒了,而不是彼此獨立。致使 back 鍵出現故障。
既然直接顯示 Actvity 有問題,想一想反正都是顯示UI佈局,能不能把 A 類 Activity 的根佈局拉出來掛載在主 Activity 右側?從而咱們推導出了方案2。
方案2:在主 Activity 啓動 A 類 Activity 時,獲取 A 的根佈局。加入到主 Activity 在右側3區預留的一個空佈局中。
詳細實現步驟爲:
1,重寫主 Activity 的 startActivity 方法。
2。使用 LocalActivityManager 啓動 A 類 Aactivity 返回 window 對象。
3,經過 Window 對象 window.getDecorView()返回打開 Activity 的佈局並 Add 到主 Actvity 上。
4,重寫主 Activity 的 Back 邏輯,在點擊返回鍵時 remove 掉掛載的 decorView。
但是在 Demo 上一測試,就發現了很是多問題。
1. 用 mat 查看到 A 類 Activity 是怎麼也釋放不掉的,由於 LocalActivityManager 已經抓住了 A 類 Activity 的 parent。
2. 直接拿出 A 類 Activity 的 decorView,已經讓A類 Activity 喪失了 Activity 的一切特性,包括生命週期,返回邏輯,ActivityResult,以及啓動其它 Activity 等功能。
會致使以前正常執行的A類 Activity 出現大量問題。
既然直接拿到根視圖沒實用。那該怎麼作纔好呢?怎麼作才幹使 A 類 Activity 的頁面掛載在主 Activity 右側。又能保證 A 的生命週期和 Activity 行爲呢?通過你們一番思考討論後。能不能利用插件的思想,把 A 類 Activity 中的生命週期方法以及繼承自 Activity 類的方法都拿出來了,在適當時候本身調用呢?這樣就保證了原來 A 中的代碼不會出現故障,不需要改動 A 中的不論什麼代碼。但是用什麼作容器(代理)比較好了?以後咱們想到了用 Fragment,。由於 Fragment 可以做爲所屬 Activity 的一個塊存在於不論什麼位置,而且 Fragment 有本身的生命週期,並受所屬 Activity 的生命週期影響。它就像一個子 Activity 同樣。簡直是絕佳容器。而且 Fragment 比較輕量。自己由 Activity 來管理(而不像 Activity 由 Android 系統服務管理),在不一樣的佈局結構中重用 Fragment 可以優化屏幕空間和用戶體驗。
注意。如下所說的把 Activity 轉換爲 Fragment 並不是直接把 Activity 變爲 Fragment,這會付出巨大代價。而是以一個空的 Fragment 爲容器來承載 Activity。
最終方案3順利出爐。
方案3,把 Activity 轉換爲 Fragment。使用 Fragment 模擬 Activity 的方法。
而後把 Fragment 直接加入到主 Activity 的右側佈局中。
實現的詳細步驟爲:
1,新增 BasePadActivity,讓所有 Activity 繼承 BasePadActivity,重寫 StartActivity 方法。在該方法中手動 New 出A類 Activity,並把主 Activity 的上下文對象 Context 傳遞給它。
2,建立 MyFragment,持有A類 Activity 實例引用,在 MyFragment 生命週期中直接調用A類 Activity 生命週期方法,並把A類 Activity 的視圖傳遞給 Fragment 使用。
3,A類 Activity 中繼承自 Activity 的方法所有重寫,詳細實現由步驟1中的獲得的主 Activity 上下文 context 處理。這樣A類 Activity 已經成爲一個普通實例化對象,再也不由 Android 系統管理。
該方案有較多長處,由於繼承 base。不只能迅速將大量 Activity 快換爲 Fragment。而且轉換後,使原來A類 Activity 的功能邏輯維持正常。
而且由於A類 Activity 的上下文事實上使用了主 Activity 的上下文對象,需要在A類 Activity 獲取 Resouce。Window,Asset 對象等都能經過主 Activity 的 context 進行獲取。
該方案實現後,最初測試好像一切正常,但是不就後也發現了若干問題:
1. 原 Activity 本身定義 TitleBar 出現故障。
2. 每個 Tab 標籤中打開的 Fragment,由於都屬於一個主 Activity,致使它們僅僅有一個 Fragment 棧,Back 返回時會出現與方案1類似的問題。
3. 雖然 Activity 轉換爲 Fragment 後,大部分行爲都進行了模擬,但是另外一些重要行爲沒有作處理,比方說 Activity 的啓動模式。Back 鍵,onActivityResult 等等,這些還要進行無缺。
4. 對於聲明爲多進程的 Activity。轉換爲 Fragment 後失去了多進程的特性。由於這些 Fragment 屬於主 Activity,主 Activity 是屬於手Q進程的。
該方案雖然也有諸多問題,但是通過調研和測試,發現基本都是能解決的。出於該方案的長處,以及對其出現的問題的解決難易評估,最終決定在該方案基礎上進行優化和無缺。那麼對上述出現的若干問題該怎樣解決呢?
設置本身定義 TitleBar,是 Activity 所提供的接口,查看手機APP代碼,大部分 Activity 都繼承了 TitleBarActivity。經過
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_commen_title);
來定義 TitleBar 的樣式。因此改成 Fragment 以後致使大量 Activity titlebar 顯示不出。甚至 crash。
那麼能不能實現一個本身定義的 window 對象繼承 android.view.Window,經過 getWindow()獲得的是咱們本身定義的 Window 對象,它可以處理本身定義 Titlebar 的使用。
Pad 版本號主頁也是分爲多個 Tab 標籤欄的,每個標籤欄中對 Fragment 的操做應該是相互獨立的。
Android中Fragment都是由 FragmentManager 來管理的。
Fragment 的加入,替換,移除等操做都是由 FragmentManager 中對象 FragmentTransaction 來記錄和執行。每個 Activity 中僅僅有一個 FragmentManager 實例。經過代碼
Activity.java
final FragmentManagerImpl mFragments = new FragmentManagerImpl(); public FragmentManager getFragmentManager() { return mFragments; }
獲取。假設把設計圖中的整個頁面稱爲主 Activity,用主 Activity 中一個 FragmentManager 來管理所有標籤欄的 Fragment 顯然會引發混亂,那麼可否實現每個標籤頁中都有一個 FragmentManager 的實例來管理當前標籤中所有 Activity 轉換的 Fragment?
無缺 Fragment 的 Activity 行爲。比方還需要模擬 Activity 的啓動模式、Activity result、startActivity、finish、onBackPressed 等等。
在回答這個問題以前。要先問一個問題,爲何不都轉換爲 Fragment 呢?
以前研究手機 APP 項目代碼發現,不少Activity都是設計成屬於其它進程,比方 Web 進程。這樣設計的緣由:
其一是這類 Activity 功能都是屬於同一模塊。出現 crash 也不會讓整個QQ崩潰。
另一個重要緣由是,Android 平臺對每個進程都有內存限制。使用多進程就可以使APP所使用的內存加大幾倍。其它進程可以分擔主進程的內存壓力。大大減小內存溢出致使的 crash。
因此不能輕易把這些 Activity 轉換爲 Fragment。由於轉換爲 Fragment,就失去了 Activity 多進程的特性,違背了以前設計初衷,大大添加了APP的內存壓力。
那麼這種狀況下可否讓多個 Activity 在同一屏幕顯示,能不能讓從主 Activity 打開的新 Activity 變爲透明,而且讓其大小和位置恰好覆蓋設計圖的區域3。同一時候讓屬於主 Activity 的區域1,和區域2接收事件。這樣既讓 Acitvity 擁有多進程的特性,又讓他們看起來就像是在同一個 Activity 中操做。咦,這不是咱們的方案1嗎? 對的,由於以上種種緣由,對於多進程的 Activity,咱們仍是要依照方案1來處理。
那麼怎樣解決解決方式1中的問題。
在每個標籤頁打開的多進程 Activity,應該僅僅與本標籤頁有關聯,在切換到其它標籤後。這些 Activity 應該隱藏起來,又一次再切換 Tab 回到該標籤時,以前在該標籤打開的這些 Activity 應該又一次顯示。
而且每個 Tab 的 Activitys 都應該有一個 Activity 棧來管理。
這該怎樣實現呢?經過閱讀http://developer.android.com/guide/components/tasks-and-back-stack.html瞭解到
一個 app 中一般包括若干個 Activitys,咱們可以把這些 Activity 分爲若干類。讓每一類都屬於同一個 Task,以多任務的方式把這些 Activity 分爲若干組。
比方把在 Tab1欄內打開的多進程 Activity 放入一個Task中。把Tab2中打開的多進程 Activity 放入另一個 Task 中。切換 tab 時,僅僅需要讓兩個 task 交替移到前臺顯示或後臺隱藏就能夠,而且每個Task中都維護着一個 Activity 棧。該想法彷佛能解決問題。
那麼看到這裏你們又會有另一個疑問了?既然能解決方式1中的問題,爲何不直接所有使用方案1呢?還要把Activity轉爲Fragment幹嗎?
1。實現的問題,使用多Task的實現方式,在Android中需要聲明Activity的TaskAffinity,而 TaskAffinity 不能在代碼中動態聲明。而僅僅能寫在配置文件裏,致使不一樣Tab打開的同一個Activity可能需要在配置文件裏聲明兩次,由於它們的 TaskAffinity 要不同,而同一個Activity是不能聲明兩次的。因此僅僅有寫一個空的 Activity 繼承它。致使大量空Activity產生,而且在代碼中啓動 Activity 前還要重定向到繼承的Activity。比較麻煩。多進程 Activity 畢竟仍是少數,因此可以這麼作。
但所有這樣實現明顯不太可取。
2。體驗的問題,當切換 Tab,把 Task 移入前臺,會有一個延時。而且這個延時並不肯定,致使切回 tab,會先顯示底部的頁面,而後 task 中Activity 才覆蓋上來。
3。機型的問題,極少數機型多是由於廠家定製的緣由,在多個 Activity 顯示在同一屏幕時會有一個問題,在接收左側主 Activity 的事件時,A類 Activity 會消失。通過緣由查找,發現A類 Activity 的 task 本身主動回到了後臺。應該是系統源代碼被改動了。這種話基本無法用了。
通過你們若干分析討論,咱們基本理清楚了方案3所遇到問題的大體解決版本號,通過均衡考慮,使用如下解決方式是眼下 Pad 化最好的解決方式。
對 MyApp pad 化的整個流程以及會遇到的問題理清楚以後。通過思考和你們的討論肯定了咱們手機端 APP Pad 化的架構方案:
1,轉換 APP 主進程的 Activity 爲 Fragment,轉換過程儘可能不改動原來 Activity 的不論什麼代碼。
2,讓轉換後的 Fragment 模擬 Activity 的行爲。保持 Fragment 和原來 Activity 的行爲一致。
3,使用 LocalActivityManager 實現每個 Tab 標籤 Fragments 操做的獨立性。
4,多進程 Activity(包括插件 Activity)不轉換爲 Fragment,實現多任務分屏顯示。
實現 BasePadActivity 爲所有 Activity 基類,對 Activity 轉換爲 Fragment 的操做在 BasePadActivity 中實現,利用類似插件的想法。以Fragment爲殼,把真正詳細的實現從 Activity 中搬入 Fragment,而不需要改動原 Activity 的不論什麼代碼。經過重寫 StartActivity 方法。讓原來去 startActivity 的動做變爲加入一個新的 Fragment 動做,並調用 addToBackStatck()方法加入到 Fragment 棧中。
如下給出部分僞代碼的實現 。注意如下代碼都是僞代碼,很是多僅僅有方法而無實現, 這裏主要是講思路 。
BasePadActivity.java public class BasePadActivity extends Activity{ /** * 經過重寫startActivityForResult來將Fragment轉換爲Activity */ @Override public void startActivityForResult(Intent intent) { if (isfragment && !isNewProcessActivty()){ //多進程Activity不轉換爲Fragment //初始化activity,注意該Activity是咱們本身實例化出來的 BasePadActivity activity =(BasePadActivity)newInstance(intent); activity.attachBaseContext(getBaseContext()) activity.onCreate(intent.getExtras()); //模擬Activity的onCreate activity.addMyFragment(); } } } public class MyFragment extends Fragment { @Override public View onCreateView() { View contentView = getWindow().getDecorView(); //Fragment的View爲Activity的decorView return contentView; } @Override public void onResume() { super.onResume(); BasePadActivity.this.onResume(); //模擬Activity } @Override public void onPause() { super.onPause(); BasePadActivity.this.onPause(); //模擬Activity onPause } ........ ........ } }
代碼巧妙實現了所有繼承 BasePadActivity 的 Activity 轉換爲Fragment 的過程,固然這裏僅僅展現了轉換一小部分。其它細節問題並無在代碼中列出來。當打開 Activity 的過程轉換爲打開 Fragment 的過程後。咱們需要讓 Fragment 模擬 Activity 的行爲。
模擬 Activity 的 finish 方法
BasePadActivity.java public void finish() { if (bActivityToFragment) { removeTopFragment(); //移除Fragment棧中最頂層Fragment } }
模擬 Activity 的 onActivityResult,在當前 Fragment 被 finish 去觸發
private void removeTopFragment() { if(popBackStackImmediate()){ //成功把頂層Fragment,從Fragment棧中移出。handleSetResult(requestCode,false); } } private void handleSetResult(int requestCode){ //觸發上層Fragment的onActivityResult topFragment.onActivityResult(requestCode, resultCode, data); }
模擬 Activity 的返回事件,當把 Activity 轉換爲 Fragment 時。其返回事件已經由該 Fragment 所屬的 Activity 接收。所以需要處理其所屬真正 Activity 的返回事件。經過 FragmentManager 可以管理該 Activity 中所有 Fragment。
BasePadActivity.java public void onBackPressed() { if(isActivityForFragment()){ //,爲Fragment所屬Activity if(!handleFragmentBackEvent()){ //先處理Fragment自己的返回事件。比方想先關閉當前Fragment菜單。 finishTopFragment(); //最後finish該Fragment } } }
模擬 Activity 的啓動方式,經過獲取 intent.getFlags()值。來推斷 Activity 的啓動模式,經過
public boolean hasFlagClearTop(int flags){ return (flags & Intent.FLAG_ACTIVITY_CLEAR_TOP )!=0 ; } public boolean hasFlagNewTask(int flags){ return (flags & Intent.FLAG_ACTIVITY_NEW_TASK )!=0 ; }
來推斷 Flag 中是否包括對應啓動方式值。來對 Fragment 的打開作對應處理。這裏會略微麻煩一點。故不做代碼說明了。
在不改變原來 Activity 代碼的狀況下。經過改變 Window 對象,本身實現對 Fragment 佈局的控制。實現本身定義 Titlebar。
BasePadActivity.java
public Window getWindow() { if(customWindow==null){ //本身定義的window,主要爲了解決很是多Activity繼承IphoneTitleBar的問題 customWindow = new Window4FragmentTitle(mContext); } return customWindow; } Window4FragmentTitle.java public class Window4FragmentTitle extends Window{ @Override public void setContentView(View view, LayoutParams params) { if (mContentParent == null) { installDecor(); } mContentParent.addView(view, params); } @Override public void setFeatureInt(int featureId, int value) { if(featureId != FEATURE_CUSTOM_TITLE){ return; } FrameLayout titleContainer = (FrameLayout) findViewById(android.R.id.title); if (titleContainer != null) { mLayoutInflater.inflate(value, titleContainer); } } }
經過 Window4FragmentTitle 調用 setFeatureInt(int)方法,會把本身定義的 Title 佈局嵌入到咱們建立的佈局 mDecor 中,而後把 mDecor 放入 Fragment,實現本身定義 Titlebar 在 Fragment 中的顯示。
使用 LocalActivityManager 實現標籤佈局,使每個 Tab 中都有一個 Acitvity 對象。而每個 Activity 中都會有一個 FragmentManager 對該 Tab 的 Frament 棧進行管理。這樣每個 Tab 的 Fragments 相互獨立,互不影響。
主Activity
addFrame(Tab1Content.class, mTabs[1]); //Tab1 addFrame(Tab2Content.class, mTabs[2]); //Tab2 ..... public void addFrame(){ mTabHost.setup(getLocalActivityManager()); TabSpec tabSpec = mTabHost.newTabSpec("").setIndicator(tab).setContent(new Intent(this, clz)); mTabHost.addTab(tabSpec); }
經過 setContent(new Intent(this, clz) ,把每個標籤欄內容以子 Activity 的方式加入進來。
前面說過。對於多進程的 Activity。爲了保持其模塊化以及分擔主進程內存壓力的特色,通過你們討論,不把他們轉換爲 Fragment,那麼就需要解決多個 Activity 一塊兒展現的問題。通過研究,得出的有效實現方式是:讓在每個標籤欄內打開的 Activity 透明化,而且讓其大小和位置恰好居於設計圖3區,同一時候能讓處於該 Activity 下方的左側區域的主Activity 接收點擊事件。
1,Activity 透明化實現,在配置文件裏聲明 Activity 的 theme 爲透明
2,定義 Activity 的大小和位置。
在 Activity 的 onCreate 方法中實現
WindowManager.LayoutParams layoutParams = window.getAttributes(); layoutParams.gravity = Gravity.RIGHT | Gravity.TOP; //位置居於右側 layoutParams.width = mActivity.getRightPanelWidth(); //寬度爲右側區域寬度
* 3,讓左側主 Activity 接收事件*
經過設置 window 的 WindowManager.LayoutParams 的 flag 爲 FLAG_NOT_TOUCH_MODAL 可以讓顯示在透明 Activity 左側下方的主 Activity 接收事件。
新打開的 Activity 位於右區,左區爲主 Activity 顯示區域。左區和右區能同一時候接收用戶點擊事件,看起來就好像同一個 Activity 同樣。
但是由於在當前 Tab 打開的位於右區的 Activity,是尾隨當前Tab的,在切換 Tab 後,應該消失。比方 Tab1中打開的 Actvity。切換到Tab2時應該隱藏掉。又一次再切換回 Tab1時讓其又一次顯示。保留現場。該功能要怎樣實現呢?通過對 Android 特性的理解以及思考。發現可以是用多任務分屏顯示方式實現不一樣 Tab 多進程 Activitys 的顯示和隱藏。讓不一樣Tab打開的 Activitys 分屬於不一樣 Task,每個 task 擁有一個 Activity 棧來管理當中 Activity,切換 tab 要作的就是不一樣 Task 的切換。
這樣邏輯很是清楚,也符合高速 Pad 化的原則。那麼詳細該怎麼實現呢?
爲每個 Tab 打開的第一個 Activity 提供一個不一樣的 TaskAffinity
首先咱們來了解。什麼是 TaskAffinity?
在某些狀況下。Android 需要知道一個 Activity 屬於哪一個 Task,這是經過任務共用性(TaskAffinity)完畢的。TaskAffinity 爲執行一個或多個Activity 的 task 提供一個獨特的名稱,當使用 Intent.FLAG_ACTIVITY_NEW_TASK 標誌的 Activity,併爲該 Activity 聲明一個獨特的 TaskAffinity 時,該 Activity 再也不執行在啓動它的 Task 裏。而是會又一次啓動一個新的 Task,新的 task 管理一個新的 Activity 棧。而打開的這個 Activity 則位於棧底。
瞭解了 TaskAffinity,咱們在配置文件裏爲打開的多進程 Activity 設置相關 tab 的 TaskAffinity 值
如下展現對 web 進程 Activity 的處理
<activity android:name=" BrowserActivity1" android:process=":web" android:taskAffinity="com.tab1. BrowserActivity1" android:theme="@style/Default.Transparent" /> <activity android:name=" BrowserActivity2" android:process=":web" android:taskAffinity="com.tab2.BrowserActivity2" android:theme="@style/Default.Transparent"/> ........
在不一樣 Tab 打開的 BrowserActivity,都爲它們設置了不一樣的 TaskAffinity,在代碼中當發現打開的頁面是 Web 頁面時,則在哪一個Tab打開。頁面重定向到設置了對應 TaskAffinity 的 Activity上。
public void startActivityForResult(Intent intent) { if(isBrowserActivity(intent)){ //純打開QQBrowserActivity int curTab = getTabIndex(); //獲取當前Tab索引 Class<?> c = getBrowserMap().get(curTab); //取出對應打開的Activity redirectAndOpenInNewTask() //重定向 } ...... ...... }
這樣就爲在不一樣 Tab 打開的 Activity 建立了不一樣的 Task。而後在切換Tab時經過發送廣播動態的顯示和隱藏 Task。
public void onTabSelected(int curTabIndex) { Intent i = new Intent("action"); i.putExtra("cur_Tab_Id",curTabIndex); //切換到當前Tab的索引 sendBroadcast(i); }
在 Task 的根 Activity 中接收廣播,處理 Task 顯示和隱藏邏輯
public void onReceive(Context context, Intent intent) { int tab = intent.getIntExtra(CUR_TAB_ID,-1); if(tabIndex>=0 && tabIndex == tab){ moveTaskToFront(mActivity.getTaskId()); //移動當前Task移入後臺 }else{ moveTaskToBack(); //把該Activity所屬Task移動到前臺 } }
到這裏基本上攻克了多進程 Activity 與主 Activity 同屏顯示所帶來的問題。
經過上述方案。以及一些問題的巧妙解決。最終實現了 MyApp Pad 化的高速開發,而且 MyApp for Pad 第一個版本號的公佈上線。到現在6到7個版本號的迭代,一直都是穩定執行的。該方案的長處是,僅僅要維護好架構,其它開發人員在對單個頁面改造時。不需要管它是真正 Activity 仍是 Fragment,僅僅要知道這些頁面表現的都是 Activity 的行爲,就和在手機 APP 上開發是同樣的。
經過 MyApp Pad 化開發方案的實現,咱們想咱們這個方法可否夠寫成一個通用的手機 App Pad 化組件。爲公司的其它Android產品Pad化提供技術支持。就算你的 APP 佈局並不是 Tab 方式,咱們開放出一個 Base Activity。其它 App 的 Activity 經過繼承 Base,就能本身主動轉換爲Fragment,而且能爲多進程 Activity 提供處理方案。
但這確定需要考慮不少其它的狀況。和解決不少其它問題。路漫漫其修遠兮。吾將上下而求索。
期待無缺的 Android App PAD 組件能與你們見面。
假設你認爲內容意猶未盡。假設你想了解不少其它相關信息。請掃描如下二維碼。關注咱們的微信公衆帳號,可以獲取不少其它技術類乾貨,還有精彩活動與你分享~
騰訊 Bugly是一款專爲移動開發人員打造的質量監控工具。幫助開發人員高速,便捷的定位線上應用崩潰的狀況以及解決方式。智能合併功能幫助開發同窗把天天上報的數千條 Crash 依據根因合併分類。每日日報會列出影響用戶數最多的崩潰,精準定位功能幫助開發同窗定位到出問題的代碼行,實時上報可以在公佈後高速的瞭解應用的質量狀況,適配最新的 iOS, Android 官方操做系統。鵝廠的project師都在使用,快來加入咱們吧。