Android基本知識

1枝冀、Android的Handler運行機制

1. Message

Message消息,理解為線程間交流的信息聂儒,處理數(shù)據(jù)后臺線程需要更新UI嫉入,則發(fā)送Message內(nèi)含一些數(shù)據(jù)給UI線程。

2. Handler

Handler處理者觉至,是Message的主要處理者剔应,負責(zé)Message的發(fā)送,Message內(nèi)容的執(zhí)行處理语御。后臺線程就是通過傳進來的 Handler對象引用來sendMessage(Message)峻贮。而使用Handler,需要implement 該類的 handleMessage(Message)方法应闯,它是處理這些Message的操作內(nèi)容纤控,例如Update UI。通常需要子類化Handler來實現(xiàn)handleMessage方法碉纺。

3. Message Queue

Message Queue消息隊列船万,用來存放通過Handler發(fā)布的消息刻撒,按照先進先出執(zhí)行。

在單線程模型下耿导,為了線程通信問題声怔,Android設(shè)計了一個Message Queue(消息隊列), 線程間可以通過該Message Queue并結(jié)合Handler和Looper組件進行信息交換碎节。

每個message queue都會有一個對應(yīng)的Handler。Handler會向message queue通過兩種方法發(fā)送消息:sendMessage或post抵卫。這兩種消息都會插在message queue隊尾并按先進先出執(zhí)行狮荔。但通過這兩種方法發(fā)送的消息執(zhí)行的方式略有不同:通過sendMessage發(fā)送的是一個message對象,會被 Handler的handleMessage()函數(shù)處理;而通過post方法發(fā)送的是一個runnable對象介粘,則會自己執(zhí)行殖氏。

4. Looper

Looper是每條線程里的Message Queue的管家。Android沒有Global的Message Queue姻采,而Android會自動替主線程(UI線程)建立Message Queue雅采,但在子線程里并沒有建立Message Queue。所以調(diào)用Looper.getMainLooper()得到的主線程的Looper不為NULL慨亲,但調(diào)用Looper.myLooper() 得到當(dāng)前線程的Looper就有可能為NULL。


2、面向?qū)ο蟮奶卣?/b>

對象唯一性和媳。

每個對象都有自身唯一的標識涵紊,通過這種標識,可找到相應(yīng)的對象蛉签。在對象的整個生命期中胡陪,它的標識都不改變,不同的對象不能有相同的標識碍舍。?[2]

抽象性柠座。

抽象性是指將具有一致的數(shù)據(jù)結(jié)構(gòu)(屬性)和行為(操作)的對象抽象成類。一個類就是這樣一種抽象片橡,它反映了與應(yīng)用有關(guān)的重要性質(zhì)妈经,而忽略其他一些無關(guān)內(nèi)容。任何類的劃分都是主觀的捧书,但必須與具體的應(yīng)用有關(guān)狂塘。?[2]

繼承性

繼承性是子類自動共享父類數(shù)據(jù)結(jié)構(gòu)和方法的機制鳄厌,這是類之間的一種關(guān)系荞胡。在定義和實現(xiàn)一個類的時候,可以在一個已經(jīng)存在的類的基礎(chǔ)之上來進行了嚎,把這個已經(jīng)存在的類所定義的內(nèi)容作為自己的內(nèi)容泪漂,并加入若干新的內(nèi)容廊营。?[2]

繼承性是面向?qū)ο蟪绦蛟O(shè)計語言不同于其它語言的最重要的特點,是其他語言所沒有的萝勤。

在類層次中露筒,子類只繼承一個父類的數(shù)據(jù)結(jié)構(gòu)和方法,則稱為單重繼承敌卓。

在類層次中慎式,子類繼承了多個父類的數(shù)據(jù)結(jié)構(gòu)和方法,則稱為多重繼承趟径。

多重繼承瘪吏,JAVA、VB蜗巧、NET掌眠、Objective-C均僅支持單繼承,注意在C++多重繼承時幕屹,需小心二義性蓝丙。

軟件開發(fā)中,類的繼承性使所建立的軟件具有開放性望拖、可擴充性渺尘,這是信息組織與分類的行之有效的方法,它簡化了對象说敏、類的創(chuàng)建工作量沧烈,增加了代碼的可重用性。

采用繼承性像云,提供了類的規(guī)范的等級結(jié)構(gòu)锌雀。通過類的繼承關(guān)系,使公共的特性能夠共享迅诬,提高了軟件的重用性腋逆。?[2]

多態(tài)性(多形性)

多態(tài)性是指相同的操作或函數(shù)、過程可作用于多種類型的對象上并獲得不同的結(jié)果侈贷。不同的對象惩歉,收到同一消息可以產(chǎn)生不同的結(jié)果,這種現(xiàn)象稱為多態(tài)性俏蛮。

多態(tài)性允許每個對象以適合自身的方式去響應(yīng)共同的消息撑蚌。

多態(tài)性增強了軟件的靈活性和重用性。



3搏屑、性能優(yōu)化總結(jié)2:leakcanary的使用(li)

1争涌、引入庫

2、操作APP辣恋,分析結(jié)果

3亮垫、如果是復(fù)雜的問題可以導(dǎo)出hprof文件到android studio 中繼續(xù)分析

我們啟動app模软,當(dāng)檢測到內(nèi)存泄漏的時候,會出現(xiàn)一個彈窗饮潦,然后手機桌面會出現(xiàn)一個Leaks的圖標

點擊即可看到內(nèi)存泄漏的原因:


4燃异、Serializable和Parcelable的區(qū)別

在使用內(nèi)存的時候,Parcelable 類比Serializable性能高继蜡,所以推薦使用Parcelable類回俐。

1.Serializable在序列化的時候會產(chǎn)生大量的臨時變量,從而引起頻繁的GC稀并。

2.Parcelable不能使用在要將數(shù)據(jù)存儲在磁盤上的情況仅颇。盡管Serializable效率低點,但在這種情況下稻轨,還是建議你用Serializable 灵莲。

實現(xiàn):

1.Serializable 的實現(xiàn)雕凹,只需要繼承 Serializable 即可殴俱。這只是給對象打了一個標記,系統(tǒng)會自動將其序列化枚抵。

2.Parcelabel 的實現(xiàn)线欲,需要在類中添加一個靜態(tài)成員變量 CREATOR,這個變量需要繼承Parcelable.Creator 接口汽摹。

public class MyParcelable implements Parcelable {

? ? private int mData;

? ? public int describeContents() {

? ? ? ? return 0;

? ? }

? ? public void writeToParcel(Parcel out, int flags) {

? ? ? ? out.writeInt(mData);

? ? }

? ? public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {

? ? ? ? public MyParcelable createFromParcel(Parcel in) {

? ? ? ? ? ? return new MyParcelable(in);

? ? ? ? }

? ? ? ? public MyParcelable[] newArray(int size) {

? ? ? ? ? ? return new MyParcelable[size];

? ? ? ? }

? ? };

? ? private MyParcelable(Parcel in) {

? ? ? ? mData = in.readInt();

? ? }

}

5李丰,什么是內(nèi)存泄漏,android在什么情況下容易產(chǎn)生內(nèi)存泄漏

說到內(nèi)存泄漏就不得不提內(nèi)存溢出逼泣。

內(nèi)存溢出 out of memory趴泌,是指程序在申請內(nèi)存時,沒有足夠的內(nèi)存空間供其使用拉庶,出現(xiàn)out of memory嗜憔;比如申請了一個integer,但給它存了long才能存下的數(shù),那就是內(nèi)存溢出氏仗。

內(nèi)存泄露 memory leak吉捶,是指程序在申請內(nèi)存后,無法釋放已申請的內(nèi)存空間皆尔,一次內(nèi)存泄露危害可以忽略呐舔,但內(nèi)存泄露堆積后果很嚴重。內(nèi)存溢出導(dǎo)致了內(nèi)存泄漏慷蠕。

在Android中常見的內(nèi)存泄漏原因:

1. 資源釋放問題

程序代碼的問題珊拼,長期保持某些資源,如Context流炕、Cursor杆麸、IO流的引用搁进,資源得不到釋放造成內(nèi)存泄露。

2. 對象內(nèi)存過大問題

保存了多個耗用內(nèi)存過大的對象(如Bitmap昔头、XML文件)饼问,造成內(nèi)存超出限制。

3. static關(guān)鍵字的使用問題

static是Java中的一個關(guān)鍵字揭斧,當(dāng)用它來修飾成員變量時莱革,那么該變量就屬于該類,而不是該類的實例讹开。所以用static修飾的變量盅视,它的生命周期是很長的,如果用它來引用一些資源耗費過多的實例(Context的情況最多)旦万,這時就要謹慎對待了闹击。

4. 線程導(dǎo)致內(nèi)存溢出

線程產(chǎn)生內(nèi)存泄露的主要原因在于線程生命周期的不可控。

5成艘,數(shù)據(jù)庫游標忘記回收等

那么針對上面的問題我們怎么避免呢

1)圖片過大導(dǎo)致OOM

Android 中用bitmap時很容易內(nèi)存溢出赏半,比如報如下錯誤:Java.lang.OutOfMemoryError :

bitmap size exceeds VM budget。

解決方法:

方法1: 等比例縮小圖片

方法2:對圖片采用軟引用淆两,及時地進行recyle()操作

SoftReference<Bitmap> bitmap = new SoftReference<Bitmap>(pBitmap);

2)查詢數(shù)據(jù)庫沒有關(guān)閉游標

程序中經(jīng)常會進行查詢數(shù)據(jù)庫的操作断箫,但是經(jīng)常會有使用完畢Cursor后沒有關(guān)閉的情況。如果我們的查詢結(jié)果集比較小秋冰,對內(nèi)存的消耗不容易被發(fā)現(xiàn)仲义,只有在常時間大量操作的情況下才會出現(xiàn)內(nèi)

存問題,這樣就會給以后的測試和問題排查帶來困難和風(fēng)險剑勾。

3)構(gòu)造Adapter時埃撵,沒有使用緩存的 convertView

在使用ListView的時候通常會使用Adapter,那么我們應(yīng)該盡可能的使用ConvertView虽另。為什么要使用convertView?(con what)

當(dāng)convertView為空時暂刘,用setTag()方法為每個View綁定一個存放控件的ViewHolder對象。當(dāng) convertView 不為空洲赵,重復(fù)利用已經(jīng)創(chuàng)建的 view 的時候鸳惯,使用 getTag()方法獲取綁定的ViewHolder對象,這樣就避免了findViewById對控件的層層查詢叠萍,而是快速定位到控件芝发。

4)Bitmap對象不再使用時調(diào)用recycle()釋放內(nèi)存

有時我們會手工的操作Bitmap對象,如果一個Bitmap對象比較占內(nèi)存苛谷,當(dāng)它不再被使用的時

候辅鲸,可以調(diào)用Bitmap.recycle()方法回收此對象的像素所占用的內(nèi)存,但這不是必須的腹殿,視情況而定独悴。

6例书、 簡述下Android JNI調(diào)用過程

1)安裝和下載Cygwin,下載AndroidNDK

2)在ndk項目中JNI接口的設(shè)計

3)使用C/C++實現(xiàn)本地方法

4)JNI生成動態(tài)鏈接庫.so文件

5)將動態(tài)鏈接庫復(fù)制到j(luò)ava工程刻炒,在java工程中調(diào)用决采,運行java工程即可


7、插件化坟奥、熱修復(fù) 树瞭、熱更新的理解

插件化 – apk 分為宿主和插件部分,插件在需要的時候才加載進來

熱修復(fù) – 更新的類或者插件粒度較小的時候爱谁,我們會稱之為熱修復(fù)晒喷,一般用于修復(fù)bug

熱更新 – 2016 Google 的 Android Studio 推出了Instant Run 功能 同時提出了3個名詞

“ 熱部署” – 方法內(nèi)的簡單修改,無需重啟app和Activity访敌。

“暖部署” – app無需重啟凉敲,但是activity需要重啟,比如資源的修改寺旺。

“冷部署” – app需要重啟爷抓,比如繼承關(guān)系的改變或方法的簽名變化等。

站在app開發(fā)者角度的“熱”是指在不發(fā)版的情況來實現(xiàn)更新

而Google提出的“熱”是指值是否需要重新啟動迅涮。 - 同時在開發(fā)插件化的時候也有兩種情景

一種是插件與宿主apk沒有交互废赞,只是在用戶使用到的時候進行一次吊起

還有一種是與宿主有很多的交互

你認為android熱更新框架哪個好:

1.阿里的熱更新框架已經(jīng)開源 了徽龟。但已經(jīng)很久沒有更新過新版本了叮姑。當(dāng)前的版本只支持到了 Android 4.4。由于 5.0 起新的 ART 虛擬機据悔、更嚴格的 SELinux 策略以及對 64 位的支持之類的事传透,使得 Xposed 都在開發(fā)上做了很多調(diào)整。我不知道 Dexposed 現(xiàn)在是否支持极颓,但至少阿里沒有開源朱盐。

2.在本地動態(tài)執(zhí)行遠端下發(fā)的代碼是極度危險的行為。利用此方法執(zhí)行非法代碼等或用于繞過 Google Play 等市場的審查是違反相關(guān)協(xié)議的菠隆,也是對用戶極度不負責(zé)任的行為兵琳。

3.在一些訪問非常密集的地方使用熱更新可能會對效率產(chǎn)生相對比較大的影響,應(yīng)該避免使用.

4.我們可以對 Java 的 ScriptEngine 進行一些封裝成為一個 HotPatch 類使得它更適合做熱更新的工作骇径。

5.首先,檢查熱更新補丁的管道一定要建立在 https 上躯肌,因為下發(fā)代碼是極其危險的,如果被劫持破衔,后果是無法想象的清女。其次,請求時最好自動帶上 Android 版本、手機型號晰筛、地區(qū)嫡丙、版本號等信息拴袭,以方便更精確地下發(fā),千萬不能下發(fā)錯曙博。

6.Java在運行時加載對應(yīng)的類是通過ClassLoader來實現(xiàn)的拥刻,ClassLoader本身是一個抽象來,Android中使用PathClassLoader類作為Android的默認的類加載器

7.我們的如果想做hotpatch父泳,一定要保證我們的hotpacth dex文件出現(xiàn)在dexElements列表的前面泰佳。

二.常用的熱更新技術(shù)框架:

基于QQ空間的HotFix →→ 要使用到android dex分包方案→拆分dex的項目的話,可以參考一下谷歌的multidex方案實現(xiàn).

大眾點評的NuWa←項目補丁自動化做的很完整

alibaba/AndFix

阿里巴巴的DexPosed

dalvik_patch實現(xiàn)multidex

使用React-Native實現(xiàn)app熱部署的一次實踐

alibaba/AndFix


7尘吗、activity生命周期圖解

鎖定屏與解鎖屏幕 只會調(diào)用onPause()逝她,而不會調(diào)用onStop方法,開屏后則調(diào)用onResume()睬捶。在實際操作中會有所出入黔宛,比如在三星手機測試的時候鎖定手機調(diào)用了onPause()和onStop()方法,解鎖時候調(diào)用的是:onRestart()擒贸,onStart()和 onResume()方法臀晃。

介紹不同場景下Activity生命周期的變化過程

啟動Activity:

onCreate()—>onStart()—>onResume(),Activity進入運行狀態(tài)介劫。

Activity退居后臺:

當(dāng)前Activity轉(zhuǎn)到新的Activity界面或按Home鍵回到主屏: onPause()—>onStop()徽惋,進入停滯狀態(tài)。

Activity返回前臺:

onRestart()—>onStart()—>onResume()座韵,再次回到運行狀態(tài)险绘。

Activity退居后臺,且系統(tǒng)內(nèi)存不足誉碴,

系統(tǒng)會殺死這個后臺狀態(tài)的Activity宦棺,若再次回到這個Activity,則會走onCreate()–>onStart()—>onResume()

鎖定屏與解鎖屏幕

只會調(diào)用onPause(),而不會調(diào)用onStop方法黔帕,開屏后則調(diào)用onResume()

Activity銷毀但Task如果沒有銷毀掉代咸,當(dāng)Activity重啟時這個AsyncTask該如何解決?

比如屏幕旋轉(zhuǎn)這個例子成黄,在重建Activity的時候呐芥,會回調(diào)

Activity.onRetainNonConfigurationInstance()

重新傳遞一個新的對象給AsyncTask,完成引用的更新

若Activity已經(jīng)銷毀,此時AsynTask執(zhí)行完并返回結(jié)果,會報異常么?

當(dāng)一個App旋轉(zhuǎn)時奋岁,整個Activity會被銷毀和重建思瘟。

當(dāng)Activity重啟時,AsyncTask中對該Activity的引用是無效的厦取,因此onPostExecute()就不會起作用

若AsynTask正在執(zhí)行潮太,折會報 view not attached to window manager 異常

同樣也是生命周期的問題,在 Activity 的onDestory()方法中調(diào)用Asyntask.cancal方法,讓二者的生命周期同步

內(nèi)存不足時,系統(tǒng)會殺死后臺的Activity,如果需要進行一些臨時狀態(tài)的保存,在哪個方法進行

Activity的 onSaveInstanceState() 和 onRestoreInstanceState()并不是生命周期方法,不同于 onCreate()铡买、onPause()等生命周期方法更鲁,它們并不一定會被觸發(fā)。

當(dāng)應(yīng)用遇到意外情況(如:內(nèi)存不足奇钞、用戶直接按Home鍵)由系統(tǒng)銷毀一個Activity澡为,onSaveInstanceState() 會被調(diào)用。

但是當(dāng)用戶主動去銷毀一個Activity時景埃,例如在應(yīng)用中按返回鍵媒至,onSaveInstanceState()就不會被調(diào)用。除非該activity是被用戶主動銷毀的

通常onSaveInstanceState()只適合用于保存一些臨時性的狀態(tài)谷徙,而onPause()適合用于數(shù)據(jù)的持久化保存拒啰。


8、介紹Activity 四中l(wèi)aunchMode:

我們可以在AndroidManifest.xml配置的android:launchMode屬性為以下四種之一完慧。

1谋旦、standard

standard模式是默認的啟動模式,不用為配置android:launchMode屬性即可屈尼,當(dāng)然也可以指定值為standard册着。standard啟動模式,不管有沒有已存在的實例脾歧,都生成新的實例甲捏。

2、 singleTop

我們在上面的基礎(chǔ)上為指定屬性android:launchMode=”singleTop”鞭执,系統(tǒng)就會按照singleTop啟動模式處理跳轉(zhuǎn)行為司顿。跳轉(zhuǎn)時系統(tǒng)會先在棧結(jié)構(gòu)中尋找是否有一個Activity實例正位于棧頂,如果有則不再生成新的蚕冬,而是直接使用免猾。如果系統(tǒng)發(fā)現(xiàn)存在有Activity實例,但不是位于棧頂是辕,重新生成一個實例囤热。 這就是singleTop啟動模式,如果發(fā)現(xiàn)有對應(yīng)的Activity實例正位于棧頂获三,則重復(fù)利用旁蔼,不再生成新的實例。

3疙教、 singleTask

如果發(fā)現(xiàn)有對應(yīng)的Activity實例棺聊,則使此Activity實例之上的其他Activity實例統(tǒng)統(tǒng)出棧,使此Activity實例成為棧頂對象贞谓,顯示到幕前限佩。

4、singleInstance

這種啟動模式比較特殊,因為它會啟用一個新的棧結(jié)構(gòu)祟同,將Acitvity放置于這個新的棧結(jié)構(gòu)中作喘,并保證不再有其他Activity實例進入。

LaunchMode使用場景

singleTop適合接收通知啟動的內(nèi)容顯示頁面晕城。

例如泞坦,某個新聞客戶端的新聞內(nèi)容頁面,如果收到10個新聞推送砖顷,每次都打開一個新聞內(nèi)容頁面是很煩人的贰锁。

singleTask適合作為程序入口點。

例如瀏覽器的主界面滤蝠。不管從多少個應(yīng)用啟動瀏覽器豌熄,只會啟動主界面一次,其余情況都會走onNewIntent物咳,并且會清空主界面上面的其他頁面房轿。

singleInstance應(yīng)用場景:

鬧鈴的響鈴界面。 你以前設(shè)置了一個鬧鈴:上午6點所森。在上午5點58分囱持,你啟動了鬧鈴設(shè)置界面,并按 Home 鍵回桌面焕济;在上午5點59分時纷妆,你在微信和朋友聊天;在6點時晴弃,鬧鈴響了掩幢,并且彈出了一個對話框形式的 Activity(名為 AlarmAlertActivity) 提示你到6點了(這個 Activity 就是以

SingleInstance

加載模式打開的),你按返回鍵上鞠,回到的是微信的聊天界面际邻,這是因為 AlarmAlertActivity 所在的 Task 的棧只有他一個元素, 因此退出之后這個 Task 的椛盅郑空了世曾。如果是以 SingleTask 打開 AlarmAlertActivity,那么當(dāng)鬧鈴響了的時候谴咸,按返回鍵應(yīng)該進入鬧鈴設(shè)置界面轮听。


9、Activity啟動Service的兩種方式

startService:生命周期和調(diào)用者不同.啟動后若調(diào)用者未調(diào)用stopService而直接退出,Service仍會運行

bindService:生命周期與調(diào)用者綁定,調(diào)用者一旦退出,Service就會調(diào)用unBind->onDestory


10岭佳、Fragment是什么?你曾經(jīng)遇到哪些有關(guān)Fragment的問題?

Fragment可以作為Activity界面的一部分組成出現(xiàn)

其作用是:碎片整理血巍,局部刷新。

一個Activity中可以同時出現(xiàn)多個Fragment,并一個Fragment也可以在多個Activity中使用.在Activity中可以添加,刪除,替換Fragment.Fragment可以響應(yīng)自己的輸入時間,并且有自己的生命周期,但其生命周期受Activity影響.

Fragment生命周期

onAttach():執(zhí)行該方法時珊随,F(xiàn)ragment與Activity已經(jīng)完成綁定述寡,該方法有一個Activity類型的參數(shù)柿隙,代表綁定的Activity,這時候你可以執(zhí)行諸如mActivity = activity的操作鲫凶。

onCreate():初始化Fragment优俘。可通過參數(shù)savedInstanceState獲取之前保存的值掀序。

onCreateView():初始化Fragment的布局帆焕。加載布局和findViewById的操作通常在此函數(shù)內(nèi)完成,但是不建議執(zhí)行耗時的操作不恭,比如讀取數(shù)據(jù)庫數(shù)據(jù)列表叶雹。

onActivityCreated():執(zhí)行該方法時,與Fragment綁定的Activity的onCreate方法已經(jīng)執(zhí)行完成并返回换吧,在該方法內(nèi)可以進行與Activity交互的UI操作折晦,所以在該方法之前Activity的onCreate方法并未執(zhí)行完成,如果提前進行交互操作沾瓦,會引發(fā)空指針異常满着。

onStart():執(zhí)行該方法時,F(xiàn)ragment由不可見變?yōu)榭梢姞顟B(tài)贯莺。

onResume():執(zhí)行該方法時风喇,F(xiàn)ragment處于活動狀態(tài),用戶可與之交互缕探。

onPause():執(zhí)行該方法時魂莫,F(xiàn)ragment處于暫停狀態(tài),但依然可見爹耗,用戶不能與之交互耙考。

onSaveInstanceState():保存當(dāng)前Fragment的狀態(tài)。該方法會自動保存Fragment的狀態(tài)潭兽,比如EditText鍵入的文本倦始,即使Fragment被回收又重新創(chuàng)建,一樣能恢復(fù)EditText之前鍵入的文本山卦。

onStop():執(zhí)行該方法時鞋邑,F(xiàn)ragment完全不可見。

onDestroyView():銷毀與Fragment有關(guān)的視圖怒坯,但未與Activity解除綁定炫狱,依然可以通過onCreateView方法重新創(chuàng)建視圖。通常在ViewPager+Fragment的方式下會調(diào)用此方法剔猿。

onDestroy():銷毀Fragment。通常按Back鍵退出或者Fragment被回收時調(diào)用此方法嬉荆。

onDetach():解除與Activity的綁定归敬。在onDestroy方法之后調(diào)用。


11、是否使用過本地廣播,和全局廣播有什么區(qū)別?

本地廣播在本應(yīng)用范圍內(nèi)傳播,不用擔(dān)心隱私數(shù)據(jù)泄露,不用擔(dān)心別的應(yīng)用偽造廣播.相比全局廣播,本地廣播更高效.

注冊廣播的幾種方法?

1.靜態(tài)注冊:在清單文件中注冊汪茧, 常見的有監(jiān)聽設(shè)備啟動椅亚,常駐注冊不會隨程序生命周期改變

2.動態(tài)注冊:在代碼中注冊,隨著程序的結(jié)束舱污,也就停止接受廣播了

補充一點:有些廣播只能通過動態(tài)方式注冊呀舔,比如時間變化事件、屏幕亮滅事件扩灯、電量變更事件媚赖,因為這些事件觸發(fā)頻率通常很高,如果允許后臺監(jiān)聽珠插,會導(dǎo)致進程頻繁創(chuàng)建和銷毀惧磺,從而影響系統(tǒng)整體性能

為什么Android引入廣播機制?

a:從MVC的角度考慮(應(yīng)用程序內(nèi)) 其實回答這個問題的時候還可以這樣問,android為什么要有那4大組件捻撑,現(xiàn)在的移動開發(fā)模型基本上也是照搬的web那一套MVC架構(gòu)磨隘,只不過是改了點嫁妝而已。

android的四大組件本質(zhì)上就是為了實現(xiàn)移動或者說嵌入式設(shè)備上的MVC架構(gòu)

它們之間有時候是一種相互依存的關(guān)系顾患,有時候又是一種補充關(guān)系番捂,引入廣播機制可以方便幾大組件的信息和數(shù)據(jù)交互。

b:程序間互通消息(例如在自己的應(yīng)用程序內(nèi)監(jiān)聽系統(tǒng)來電)

c:效率上(參考UDP的廣播協(xié)議在局域網(wǎng)的方便性)

d:設(shè)計模式上(反轉(zhuǎn)控制的一種應(yīng)用江解,類似監(jiān)聽者模式)

12白嘁、了解IntentServices嗎?

IntentService是Service的子類,是一個異步的膘流,會自動停止的服務(wù)絮缅,很好解決了傳統(tǒng)的Service中處理完耗時操作忘記停止并銷毀Service的問題

生成一個默認的且與線程相互獨立的工作線程執(zhí)行所有發(fā)送到onStartCommand()方法的Intent,可以在onHandleIntent()中處理.

串行隊列,每次只運行一個任務(wù),不存在線程安全問題,所有任務(wù)執(zhí)行完后自動停止服務(wù),不需要自己手動調(diào)用stopSelf()來停止.


13、如何提升Service進程優(yōu)先級

在AndroidManifest.xml文件中對于intent-filter可以通過android:priority = “1000”這個屬性設(shè)置最高優(yōu)先級呼股,1000是最高值耕魄,如果數(shù)字越小則優(yōu)先級越低,同時適用于廣播彭谁。

14吸奴、數(shù)據(jù)存儲相關(guān)

ContentProvider的主要還是用于數(shù)據(jù)共享,其可以對Sqlite缠局,SharePreferences则奥,F(xiàn)ile等進行數(shù)據(jù)操作用來共享數(shù)據(jù)。而sql的可以理解為數(shù)據(jù)庫的一門語言狭园,可以使用它完成CRUD等一系列的操作

文件存儲:

通過Java.io.FileInputStream和java.io.FileOutputStream這兩個類來實現(xiàn)對文件的讀寫读处,java.io.File類則用來構(gòu)造一個具體指向某個文件或者文件夾的對象。

SharedPreferences:

SharedPreferences是一種輕量級的數(shù)據(jù)存儲機制唱矛,他將一些簡單的數(shù)據(jù)類型的數(shù)據(jù)罚舱,包括boolean類型井辜,int類型,float類型管闷,long類型以及String類型的數(shù)據(jù)粥脚,以鍵值對的形式存儲在應(yīng)用程序的私有Preferences目錄(/data/data/<包名>/shared_prefs/)中,這種Preferences機制廣泛應(yīng)用于存儲應(yīng)用程序中的配置信息包个。

SQLite數(shù)據(jù)庫:

當(dāng)應(yīng)用程序需要處理的數(shù)據(jù)量比較大時刷允,為了更加合理地存儲、管理碧囊、查詢數(shù)據(jù)树灶,我們往往使用關(guān)系數(shù)據(jù)庫來存儲數(shù)據(jù)。Android系統(tǒng)的很多用戶數(shù)據(jù)呕臂,如聯(lián)系人信息鸳吸,通話記錄斤寂,短信息等,都是存儲在SQLite數(shù)據(jù)庫當(dāng)中的,所以利用操作SQLite數(shù)據(jù)庫的API可以同樣方便的訪問和修改這些數(shù)據(jù)张遭。

ContentProvider:

主要用于在不同的應(yīng)用程序之間實現(xiàn)數(shù)據(jù)共享的功能锨阿,不同于sharepreference和文件存儲中的兩種全局可讀寫操作模式恳不,內(nèi)容提供其可以選擇只對哪一部分數(shù)據(jù)進行共享望忆,從而保證我們程序中的隱私數(shù)據(jù)不會有泄漏的風(fēng)險

如何將打開res aw目錄中的數(shù)據(jù)庫文件?

復(fù)制的基本方法是使用getResources().openRawResource方法獲得res aw目錄中資源的 InputStream對象,然后將該InputStream對象中的數(shù)據(jù)寫入其他的目錄中相應(yīng)文件中阐虚。

在Android SDK中可以使用SQLiteDatabase.openOrCreateDatabase方法來打開任意目錄中的SQLite數(shù)據(jù)庫文件序臂。


15、如何將SQLite數(shù)據(jù)庫(dictionary.db文件)與apk文件一起發(fā)布?

可以將dictionary.db文件復(fù)制到Eclipse Android工程中的res aw目錄中实束。所有在res aw目錄中的文件不會被壓縮奥秆,這樣可以直接提取該目錄中的文件∠滩樱可以將dictionary.db文件復(fù)制到res -> raw目錄中


16构订、如何保證Service在后臺不被kill

Service設(shè)置成START_STICKY kill 后會被重啟(等待5秒左右),重傳Intent避矢,保持與重啟前一樣

通過 startForeground將進程設(shè)置為前臺進程悼瘾, 做前臺服務(wù),優(yōu)先級和前臺應(yīng)用一個級別?审胸,除非在系統(tǒng)內(nèi)存非常缺亥宿,否則此進程不會被 kill

雙進程Service: 讓2個進程互相保護**,其中一個Service被清理后砂沛,另外沒被清理的進程可以立即重啟進程

QQ黑科技: 在應(yīng)用退到后臺后烫扼,另起一個只有 1 像素的頁面停留在桌面上,讓自己保持前臺狀態(tài)尺上,保護自己不被后臺清理工具殺死

在已經(jīng)root的設(shè)備下材蛛,修改相應(yīng)的權(quán)限文件,將App偽裝成系統(tǒng)級的應(yīng)用 Android4.0系列的一個漏洞圆到,已經(jīng)確認可行

用C編寫守護進程(即子進程) : Android系統(tǒng)中當(dāng)前進程(Process)fork出來的子進程怎抛,被系統(tǒng)認為是兩個不同的進程卑吭。當(dāng)父進程被殺死的時候,子進程仍然可以存活马绝,并不受影響豆赏。*鑒于目前提到的在Android->- Service層做雙守護都會失敗*,我們可以fork出c進程富稻,多進程守護掷邦。死循環(huán)在那檢查是否還存在,具體的思路如下(Android5.0以上的版本不可行)

用C編寫守護進程(即子進程)椭赋,守護進程做的事情就是循環(huán)檢查目標進程是否存在抚岗,不存在則啟動它。

在NDK環(huán)境中將1中編寫的C代碼編譯打包成可執(zhí)行文件(BUILD_EXECUTABLE)哪怔。主進程啟動時將守護進程放入私有目錄下宣蔚,賦予可執(zhí)行權(quán)限,啟動它即可认境。

聯(lián)系廠商胚委,加入白名單


17、mipmap文件夾和drawable文件夾的區(qū)別

它只是用來放啟動圖標的,好處就是叉信,你只用放一個mipmap圖標亩冬,它就會給你各種版本(比如平板,手機)的apk自動生成相應(yīng)分辨率的圖標硼身,以節(jié)約空間硅急。


18、ListView卡頓的原因以及優(yōu)化策略

重用converView: 通過復(fù)用converview來減少不必要的view的創(chuàng)建佳遂,另外Infalte操作會把xml文件實例化成相應(yīng)的View實例营袜,屬于IO操作,是耗時操作讶迁。

減少findViewById()操作: 將xml文件中的元素封裝成viewholder靜態(tài)類连茧,通過converview的setTag和getTag方法將view與相應(yīng)的holder對象綁定在一起,避免不必要的findviewbyid操作

避免在 getView 方法中做耗時的操作: 例如加載本地 Image 需要載入內(nèi)存以及解析 Bitmap 巍糯,都是比較耗時的操作啸驯,如果用戶快速滑動listview,會因為getview邏輯過于復(fù)雜耗時而造成滑動卡頓現(xiàn)象祟峦。用戶滑動時候不要加載圖片罚斗,待滑動完成再加載,可以使用這個第三方庫glide

Item的布局層次結(jié)構(gòu)盡量簡單宅楞,避免布局太深或者不必要的重繪

盡量能保證 Adapter 的 hasStableIds() 返回 true 這樣在 notifyDataSetChanged() 的時候针姿,如果item內(nèi)容并沒有變化袱吆,ListView 將不會重新繪制這個 View,達到優(yōu)化的目的

在一些場景中距淫,ScollView內(nèi)會包含多個ListView绞绒,可以把listview的高度寫死固定下來。 由于ScollView在快速滑動過程中需要大量計算每一個listview的高度榕暇,阻塞了UI線程導(dǎo)致卡頓現(xiàn)象出現(xiàn)蓬衡,如果我們每一個item的高度都是均勻的,可以通過計算把listview的高度確定下來彤枢,避免卡頓現(xiàn)象出現(xiàn)

使用 RecycleView 代替listview: 每個item內(nèi)容的變動狰晚,listview都需要去調(diào)用notifyDataSetChanged來更新全部的item,太浪費性能了缴啡。RecycleView可以實現(xiàn)當(dāng)個item的局部刷新壁晒,并且引入了增加和刪除的動態(tài)效果,在性能上和定制上都有很大的改善

ListView 中元素避免半透明: 半透明繪制需要大量乘法計算业栅,在滑動時不停重繪會造成大量的計算秒咐,在比較差的機子上會比較卡。 在設(shè)計上能不半透明就不不半透明式镐。實在要弄就把在滑動的時候把半透明設(shè)置成不透明反镇,滑動完再重新設(shè)置成半透明。

盡量開啟硬件加速: 硬件加速提升巨大娘汞,避免使用一些不支持的函數(shù)導(dǎo)致含淚關(guān)閉某個地方的硬件加速歹茶。當(dāng)然這一條不只是對 ListView。

ViewHolder為什么要被聲明成靜態(tài)內(nèi)部類

這個是考靜態(tài)內(nèi)部類和非靜態(tài)內(nèi)部類的主要區(qū)別之一你弦。非靜態(tài)內(nèi)部類會隱式持有外部類的引用惊豺,就像大家經(jīng)常將自定義的adapter在Activity類里,然后在adapter類里面是可以隨意調(diào)用外部activity的方法的禽作。

當(dāng)你將內(nèi)部類定義為static時尸昧,你就調(diào)用不了外部類的實例方法了,因為這時候靜態(tài)內(nèi)部類是不持有外部類的引用的旷偿。聲明ViewHolder靜態(tài)內(nèi)部類烹俗,可以將ViewHolder和外部類解引用。

大家會說一般ViewHolder都很簡單萍程,不定義為static也沒事吧幢妄。確實如此,但是如果你將它定義為static的茫负,說明你懂這些含義蕉鸳。萬一有一天你在這個ViewHolder加入一些復(fù)雜邏輯,做了一些耗時工作,那么如果ViewHolder是非靜態(tài)內(nèi)部類的話潮尝,就很容易出現(xiàn)內(nèi)存泄露榕吼。

如果是靜態(tài)的話,你就不能直接引用外部類勉失,迫使你關(guān)注如何避免相互引用羹蚣。 所以將 ViewHolder內(nèi)部類 定義為靜態(tài)的,是一種好習(xí)慣


19戴质、Android中的動畫有哪些?

逐幀動畫(Drawable Animation):

加載一系列Drawable資源來創(chuàng)建動畫度宦,簡單來說就是播放一系列的圖片來實現(xiàn)動畫效果踢匣,可以自定義每張圖片的持續(xù)時間

補間動畫(Tween Animation):

Tween可以對View對象實現(xiàn)一系列簡單的動畫效果告匠,比如位移,縮放离唬,旋轉(zhuǎn)后专,透明度等等。但是它并不會改變View屬性的值输莺,只是改變了View的繪制的位置戚哎,比如,一個按鈕在動畫過后嫂用,不在原來的位置型凳,但是觸發(fā)點擊事件的仍然是原來的坐標。

屬性動畫(Property Animation):

動畫的對象除了傳統(tǒng)的View對象嘱函,還可以是Object對象甘畅,動畫結(jié)束后,Object對象的屬性值被實實在在的改變了

Android動畫原理

Animation框架定義了透明度往弓,旋轉(zhuǎn)疏唾,縮放和位移幾種常見的動畫,而且控制的是整個View

實現(xiàn)原理是每次繪制視圖時View所在的ViewGroup中的drawChild函數(shù)獲取該View的Animation的Transformation值

然后調(diào)用canvas.concat(transformToApply.getMatrix())函似,通過矩陣運算完成動畫幀槐脏,如果動畫沒有完成,繼續(xù)調(diào)用invalidate()函數(shù)撇寞,啟動下次繪制來驅(qū)動動畫

動畫過程中的幀之間間隙時間是繪制函數(shù)所消耗的時間顿天,可能會導(dǎo)致動畫消耗比較多的CPU資源,最重要的是蔑担,動畫改變的只是顯示牌废,并不能相應(yīng)事件


20、View繪制相關(guān)

SurfaceView和View的區(qū)別

SurfaceView中采用了雙緩存技術(shù)钟沛,在單獨的線程中更新界面

View在UI線程中更新界面

介紹下自定義view的基本流程

1畔规、 明確需求,確定你想實現(xiàn)的效果

2恨统、確定是使用組合控件的形式還是全新自定義的形式叁扫,組合控件即使用多個系統(tǒng)控件來合成一個新控件三妈,你比如titilebar,這種形式相對簡單莫绣,參考

3畴蒲、如果是完全自定義一個view的話,你首先需要考慮繼承哪個類对室,是View呢模燥,還是ImageView等子類。

4掩宜、根據(jù)需要去復(fù)寫View#onDraw蔫骂、View#onMeasure、View#onLayout方法

5.根據(jù)需要去復(fù)寫dispatchTouchEvent牺汤、onTouchEvent方法

6辽旋、根據(jù)需要為你的自定義view提供自定義屬性,即編寫attr.xml,然后在代碼中通過TypedArray等類獲取到自定義屬性值

7檐迟、需要處理滑動沖突补胚、像素轉(zhuǎn)換等問題


21、談?wù)刅iew的繪制流程

measure()方法追迟,layout()溶其,draw()三個方法主要存放了一些標識符,來判斷每個View是否需要再重新測量敦间,布局或者繪制瓶逃,主要的繪制過程還是在onMeasure,onLayout每瞒,onDraw這個三個方法中

1.onMesarue() 為整個View樹計算實際的大小金闽,即設(shè)置實際的高(對應(yīng)屬性:mMeasuredHeight)和寬(對應(yīng)屬性: mMeasureWidth),每個View的控件的實際寬高都是由父視圖和本身視圖決定的剿骨。

2.onLayout() 為將整個根據(jù)子視圖的大小以及布局參數(shù)將View樹放到合適的位置上代芜。

3.onDraw() 開始繪制圖像,繪制的流程如下

首先繪制該View的背景

調(diào)用onDraw()方法繪制視圖本身 (每個View都需要重載該方法浓利,ViewGroup不需要實現(xiàn)該方法)

如果該View是ViewGroup挤庇,調(diào)用dispatchDraw ()方法繪制子視圖

繪制滾動條

自定義View執(zhí)行invalidate()方法,為什么有時候不會回調(diào)onDraw()

自定義一個view時,重寫onDraw贷掖。調(diào)用view.invalidate(),會觸發(fā)onDraw和computeScroll()嫡秕。前提是該view被附加在當(dāng)前窗口.

view.postInvalidate(); //是在非UI線程上調(diào)用的

自定義一個ViewGroup,重寫onDraw苹威。onDraw可能不會被調(diào)用昆咽,原因是需要先設(shè)置一個背景(顏色或圖)。表示這個group有東西需要繪制了,才會觸發(fā)draw掷酗,之后是onDraw调违。因此,一般直接重寫dispatchDraw來繪制viewGroup.自定義一個ViewGroup,dispatchDraw會調(diào)用drawChild.


22泻轰、事件傳遞機制

談?wù)則ouch事件的傳遞流程

所有Touch事件都被封裝成了MotionEvent對象技肩,包括Touch的位置、時間浮声、歷史記錄以及第幾個手指(多指觸摸)等虚婿。

事件類型分為ACTION_DOWN, ACTION_UP, ACTION_MOVE, ACTION_POINTER_DOWN, ACTION_POINTER_UP, ACTION_CANCEL,每個事件都是以ACTION_DOWN開始ACTION_UP結(jié)束泳挥。

對事件的處理包括三類然痊,分別為傳遞——dispatchTouchEvent()函數(shù)、攔截——onInterceptTouchEvent()函數(shù)羡洁、消費——onTouchEvent()函數(shù)和OnTouchListener()

簡單來說:

事件從Activity.dispatchTouchEvent()開始傳遞玷过,只要沒有被停止或攔截,從最上層的View(ViewGroup)開始一直往下(子View)傳遞筑煮。子View可以通過onTouchEvent()對事件進行處理。

事件由父View(ViewGroup)傳遞給子View粤蝎,ViewGroup可以通過onInterceptTouchEvent()對事件做攔截真仲,停止其往下傳遞。

如果事件從上往下傳遞過程中一直沒有被停止初澎,且最底層子View沒有消費事件秸应,事件會反向往上傳遞,這時父View(ViewGroup)可以進行消費碑宴,如果還是沒有被消費的話软啼,最后會到Activity的onTouchEvent()函數(shù)。

如果View沒有對ACTION_DOWN進行消費延柠,之后的其他事件不會傳遞過來祸挪。

= OnTouchListener優(yōu)先于onTouchEvent()對事件進行消費。

上面的消費即表示相應(yīng)函數(shù)返回值為true贞间。

View中setOnTouchListener中的onTouch,onTouchEvent,onClick的執(zhí)行順序

onTouch優(yōu)于onTouchEvent,onTouchEvent優(yōu)于onClick


23贿条、什么是Dalvik虛擬機

Dalvik虛擬機是Android平臺的核心。

它可以支持.dex格式的程序的運行

.dex格式是專為Dalvik設(shè)計的一種壓縮格式

可以減少整體文件尺寸

提高I/O操作的速度

適合內(nèi)存和處理器速度有限的系統(tǒng)

Dalvik虛擬機和JVM有什么區(qū)別

Dalvik 基于寄存器增热,而 JVM 基于棧整以。基于寄存器的虛擬機對于更大的程序來說峻仇,在它們編譯的時候公黑,花費的時間更短。

Dalvik執(zhí)行.dex格式的字節(jié)碼,而JVM執(zhí)行.class格式的字節(jié)碼

Android為每個應(yīng)用程序分配的內(nèi)存大小是多少

一般是16m或者24m,但是可以通過android:largeHeap申請更多內(nèi)存

Dalvik?

  Android4.4及以前使用的都是Dalvik虛擬機凡蚜,我們知道Apk在打包的過程中會先將java等源碼通過javac編譯成.class文件奠骄,但是我們的Dalvik虛擬機只會執(zhí)行.dex文件,這個時候dx會將.class文件轉(zhuǎn)換成Dalvik虛擬機執(zhí)行的.dex文件番刊。Dalvik虛擬機在啟動的時候會先將.dex文件轉(zhuǎn)換成快速運行的機器碼含鳞,又因為65535這個問題,導(dǎo)致我們在應(yīng)用冷啟動的時候有一個合包的過程芹务,最后導(dǎo)致的一個結(jié)果就是我們的app啟動慢蝉绷,這就是Dalvik虛擬機的JIT特性(Just In Time)。

ART?

  ART虛擬機是在Android5.0才開始使用的Android虛擬機枣抱,ART虛擬機必須要兼容Dalvik虛擬機的特性熔吗,但是ART有一個很好的特性AOT(ahead of time),這個特性就是我們在安裝APK的時候就將dex直接處理成可直接供ART虛擬機使用的機器碼佳晶,ART虛擬機將.dex文件轉(zhuǎn)換成可直接運行的.oat文件桅狠,ART虛擬機天生支持多dex,所以也不會有一個合包的過程轿秧,所以ART虛擬機會很大的提升APP冷啟動速度中跌。

3.總結(jié)

Dalvik虛擬機執(zhí)行的是dex字節(jié)碼,ART虛擬機執(zhí)行的是本地機器碼

ART優(yōu)點:

  加快APP冷啟動速度

  提升GC速度

  提供功能全面的Debug特性

ART缺點:

  APP安裝速度慢菇篡,因為在APK安裝的時候要生成可運行.oat文件

  APK占用空間大漩符,因為在APK安裝的時候要生成可運行.oat文件


24、如何解決方法數(shù)65k問題?

使用Android Studio 的gradle 可以構(gòu)建MutilDex


25驱还、Android Binder機制原理

Binder是Android系統(tǒng)進程間通信(IPC)方式之一嗜暴,Binder框架定義了四個角色:Server,Client议蟆,ServiceManager(以后簡稱SMgr)以及Binder驅(qū)動闷沥。

其中Server,Client咐容,SMgr運行于用戶空間舆逃,驅(qū)動運行于內(nèi)核空間。這四個角色的關(guān)系和互聯(lián)網(wǎng)類似:Server是服務(wù)器疟丙,Client是客戶終端颖侄,SMgr是域名服務(wù)器(DNS),驅(qū)動是路由器享郊。


26览祖、AMS與WMS

Android的framework層主要是由WMS、AMS還有View所構(gòu)成炊琉,AMS和WMS都屬于Android中的系統(tǒng)服務(wù)

AMS統(tǒng)一調(diào)度所有應(yīng)用程序的Activity

WMS控制所有Window的顯示與隱藏以及要顯示的位置

AMS

基礎(chǔ)了解

作用

統(tǒng)一調(diào)度所有應(yīng)用程序的Activity的生命周期

啟動或殺死應(yīng)用程序的進程

啟動并調(diào)度Service的生命周期

注冊BroadcastReceiver展蒂,并接收和分發(fā)Broadcast

啟動并發(fā)布ContentProvider

調(diào)度task

處理應(yīng)用程序的Crash

查詢系統(tǒng)當(dāng)前運行狀態(tài)



WMS

基礎(chǔ)了解

WindowManagerService服務(wù)的實現(xiàn)是相當(dāng)復(fù)雜的又活,畢竟它要管理的整個系統(tǒng)所有窗口的UI,而在任何一個系統(tǒng)中锰悼,窗口管理子系統(tǒng)都是極其復(fù)雜的柳骄。

作用

為所有窗口分配Surface』悖客戶端向WMS添加一個窗口的過程耐薯,其實就是WMS為其分配一塊Suiface的過程,一塊塊Surface在WMS的管理下有序的排布在屏幕上丝里。Window的本質(zhì)就是Surface曲初。

管理Surface的顯示順序、尺寸杯聚、位置

管理窗口動畫

輸入系統(tǒng)相關(guān):WMS是派發(fā)系統(tǒng)按鍵和觸摸消息的最佳人選臼婆,當(dāng)接收到一個觸摸事件,它需要尋找一個最合適的窗口來處理消息幌绍,而WMS是窗口的管理者颁褂,系統(tǒng)中所有的窗口狀態(tài)和信息都在其掌握之中,完成這一工作不在話下傀广。


27颁独、ProGuard簡介

因為Java代碼是非常容易反編碼的,況且Android開發(fā)的應(yīng)用程序是用Java代碼寫的主儡,為了很好的保護Java源代碼奖唯,我們需要對編譯好后的class文件進行混淆。

ProGuard是一個混淆代碼的開源項目糜值,它的主要作用是混淆代碼,殊不知ProGuard還包括以下4個功能坯墨。

壓縮(Shrink):檢測并移除代碼中無用的類寂汇、字段、方法和特性(Attribute)捣染。

優(yōu)化(Optimize):對字節(jié)碼進行優(yōu)化骄瓣,移除無用的指令。

混淆(Obfuscate):使用a耍攘,b榕栏,c,d這樣簡短而無意義的名稱蕾各,對類扒磁、字段和方法進行重命名。

預(yù)檢(Preveirfy):在Java平臺上對處理后的代碼進行預(yù)檢式曲,確保加載的class文件是可執(zhí)行的妨托。

總而言之缸榛,根據(jù)官網(wǎng)的翻譯:Proguard是一個Java類文件壓縮器、優(yōu)化器兰伤、混淆器内颗、預(yù)校驗器。壓縮環(huán)節(jié)會檢測以及移除沒有用到的類敦腔、字段均澳、方法以及屬性。優(yōu)化環(huán)節(jié)會分析以及優(yōu)化方法的字節(jié)碼符衔≌仪埃混淆環(huán)節(jié)會用無意義的短變量去重命名類、變量柏腻、方法纸厉。這些步驟讓代碼更精簡,更高效五嫂,也更難被逆向(破解)颗品。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沃缘,隨后出現(xiàn)的幾起案子躯枢,更是在濱河造成了極大的恐慌,老刑警劉巖槐臀,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锄蹂,死亡現(xiàn)場離奇詭異,居然都是意外死亡水慨,警方通過查閱死者的電腦和手機得糜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晰洒,“玉大人朝抖,你說我怎么就攤上這事〉海” “怎么了治宣?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長砌滞。 經(jīng)常有香客問我侮邀,道長,這世上最難降的妖魔是什么贝润? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任绊茧,我火速辦了婚禮,結(jié)果婚禮上题暖,老公的妹妹穿的比我還像新娘按傅。我一直安慰自己捉超,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布唯绍。 她就那樣靜靜地躺著拼岳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪况芒。 梳的紋絲不亂的頭發(fā)上惜纸,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天,我揣著相機與錄音绝骚,去河邊找鬼耐版。 笑死,一個胖子當(dāng)著我的面吹牛压汪,可吹牛的內(nèi)容都是我干的粪牲。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼止剖,長吁一口氣:“原來是場噩夢啊……” “哼腺阳!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起穿香,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤亭引,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后皮获,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焙蚓,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年洒宝,在試婚紗的時候發(fā)現(xiàn)自己被綠了购公。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡雁歌,死狀恐怖君丁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情将宪,我是刑警寧澤,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布橡庞,位于F島的核電站较坛,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏扒最。R本人自食惡果不足惜丑勤,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望吧趣。 院中可真熱鬧法竞,春花似錦耙厚、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呆细,卻和暖如春型宝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背絮爷。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工趴酣, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人坑夯。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓岖寞,卻偏偏與公主長得像,于是被迫代替她去往敵國和親柜蜈。 傳聞我的和親對象是個殘疾皇子仗谆,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容