3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

Android面试复习资料整理

發(fā)布時(shí)間:2023/12/20 Android 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Android面试复习资料整理 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Activity鞏固和復(fù)習(xí)

1. 什么是Activity

四大組件之一,通常一個(gè)用戶交互界面對(duì)應(yīng)一個(gè)activity。activity是Context的子類,同時(shí)實(shí)現(xiàn)了window.callback和keyevent.callback,可以處理與窗體用戶交互的事件。
開(kāi)發(fā)中常用的有FragmentActivity、ListActivity、TabActivity(Android 4.0被Fragment取代)

2. Activity的4種狀態(tài)

  • running:用戶可以點(diǎn)擊,activity處于棧頂狀態(tài)。
  • paused:activity失去焦點(diǎn)的時(shí)候,被一個(gè)非全屏的activity占據(jù)或者被一個(gè)透明的activity覆蓋,這個(gè)狀態(tài)的activity并沒(méi)有銷毀,它所有的狀態(tài)信息和成員變量仍然存在,只是不能夠被點(diǎn)擊。(除了內(nèi)存緊張的情況,這個(gè)activity有可能被回收)
  • stopped:這個(gè)activity被另外一個(gè)activity完全覆蓋,但是這個(gè)activity的所有狀態(tài)信息和成員變量仍然存在(除了內(nèi)存緊張)
  • killed:這個(gè)activity已經(jīng)被銷毀,其所有的狀態(tài)信息和成員變量已經(jīng)不存在了。

3. Activity生命周期

生命周期的基本介紹
  • onCreate:當(dāng)Activity第一次啟動(dòng)調(diào)用
  • onDestroy:當(dāng)Activity銷毀的時(shí)候調(diào)用
  • onStart:當(dāng)Activity變成可見(jiàn)調(diào)用
  • onStop:當(dāng)Activity不可見(jiàn)調(diào)用
  • onResume:當(dāng)Activity可以交互調(diào)用這個(gè)方法 當(dāng)界面上的按鈕被點(diǎn)擊的時(shí)候調(diào)用
  • onPause:當(dāng)Activity不可以交互調(diào)用這個(gè)方法 當(dāng)界面上的按鈕不可以點(diǎn)擊
  • onRestart:當(dāng)界面重新啟動(dòng)的時(shí)候調(diào)用
生命周期流程
  • Activity啟動(dòng):調(diào)用的依次順序是:onCreate —> onStart —> onResume —> onPause —> onStop —> onDestroy,還有一個(gè)onRestart,其中onRestart是在Activity被onStop后,但是沒(méi)有被onDestroy,在再次啟動(dòng)此Activity時(shí)調(diào)用的(而不再調(diào)用onCreate)方法;如果被onDestroy了,則是調(diào)用onCreate方法。
  • 點(diǎn)擊Home鍵回到主界面(Activity不可見(jiàn)):onPause —> onStop
  • 當(dāng)我們?cè)俅位氐皆瑼ctivity時(shí): onRestart —> onStart —> onResume
  • 退出當(dāng)前Activity時(shí): onPause —> onStop —> onDestroy

4. Activity任務(wù)棧

  • 有序地管理Activity的先進(jìn)后出的一種數(shù)據(jù)結(jié)構(gòu)
  • 安全退出:任務(wù)棧中所有的Activity都出棧

5. Activity的啟動(dòng)模式

  • standard 標(biāo)準(zhǔn)模式:

    特點(diǎn):此模式不管有沒(méi)有已存在的實(shí)例,都生成新的實(shí)例。每次調(diào)用startActivity()啟動(dòng)Activity時(shí)都會(huì)創(chuàng)建一個(gè)新的Activity放在棧頂,每次返回都會(huì)銷毀實(shí)例并出棧,可以重復(fù)創(chuàng)建。

  • singleTop 單一頂部模式/棧頂復(fù)用模式:

    特點(diǎn):會(huì)檢查任務(wù)棧棧頂?shù)腁ctivity,如果發(fā)現(xiàn)棧頂已經(jīng)存在實(shí)例,就不會(huì)創(chuàng)建新的實(shí)例,直接復(fù)用,此時(shí)會(huì)調(diào)用onNewIntent。但如果不在棧頂,那么還是會(huì)創(chuàng)建新的實(shí)例。
    應(yīng)用場(chǎng)景:瀏覽器書(shū)簽的頁(yè)面,流氓的網(wǎng)站,避免創(chuàng)建過(guò)多的書(shū)簽頁(yè)面

  • singleTask 單一任務(wù)模式/棧內(nèi)復(fù)用模式:

    特點(diǎn):這種模式不會(huì)檢查任務(wù)棧的棧頂,檢查當(dāng)前任務(wù)棧,如果發(fā)現(xiàn)有實(shí)例存在,直接復(fù)用。任務(wù)棧中只有一個(gè)實(shí)例存儲(chǔ)(把當(dāng)前activity上面的所有的其它activity都清空,復(fù)用這個(gè)已經(jīng)存在的activity)
    應(yīng)用場(chǎng)景:瀏覽器瀏覽頁(yè)面的Activity,播放器播放的activity。

  • singleInstance 單一實(shí)例模式(用得比較少)

    特點(diǎn):系統(tǒng)會(huì)為這個(gè)Activity單獨(dú)創(chuàng)建一個(gè)任務(wù)棧,這個(gè)任務(wù)棧里面只有一個(gè)實(shí)例存在并且保證不再有其它activity實(shí)例進(jìn)入。
    應(yīng)用場(chǎng)景:來(lái)電頁(yè)面。

6. Scheme跳轉(zhuǎn)協(xié)議

概念

Android中的scheme是一種頁(yè)面內(nèi)跳轉(zhuǎn)協(xié)議,是一種非常好的實(shí)現(xiàn)機(jī)制,通過(guò)定義自己的scheme協(xié)議,可以非常方便跳轉(zhuǎn)app中的各個(gè)頁(yè)面;通過(guò)scheme協(xié)議,服務(wù)器可以定制化告訴app跳轉(zhuǎn)哪個(gè)頁(yè)面,可以通過(guò)通知欄消息定制化跳轉(zhuǎn)頁(yè)面,可以通過(guò)H5頁(yè)面跳轉(zhuǎn)頁(yè)面等。

應(yīng)用場(chǎng)景
  • 通過(guò)服務(wù)器下發(fā)跳轉(zhuǎn)路徑跳轉(zhuǎn)相應(yīng)頁(yè)面
  • 通過(guò)在H5頁(yè)面的錨點(diǎn)跳轉(zhuǎn)相應(yīng)的頁(yè)面
  • 根據(jù)服務(wù)器下發(fā)通知欄消息,App跳轉(zhuǎn)相應(yīng)的頁(yè)面(包括另外一個(gè)APP的頁(yè)面,作為推廣使用)

7. 參考文章

Android面試(一):Activity面試你所需知道的一切

android-Scheme與網(wǎng)頁(yè)跳轉(zhuǎn)原生的三種方式

Fragment

1. 什么是Fragment

Fragment,俗稱碎片,自Android 3.0開(kāi)始被引進(jìn)并大量使用。作為Activity界面的一部分,Fragment的存在必須依附于Activity,并且與Activity一樣,擁有自己的生命周期,同時(shí)處理用戶的交互動(dòng)作。同一個(gè)Activity可以有一個(gè)或多個(gè)Fragment作為界面內(nèi)容,并且可以動(dòng)態(tài)添加、刪除Fragment,靈活控制UI內(nèi)容,也可以用來(lái)解決部分屏幕適配問(wèn)題。

2. Fragment為什么被稱為第五大組件

首先Fragment的使用次數(shù)是不輸于其他四大組件的,而且Fragment有自己的生命周期,比Activity更加節(jié)省內(nèi)存,切換模式也更加舒適,使用頻率不低于四大組件。

3. Fragment的生命周期

![Fragment的生命周期](https://upl
oad-images.jianshu.io/upload_images/2570030-bb960a5fce263a3f.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

4. Fragment創(chuàng)建/加載到Activity的兩種方式

  • 靜態(tài)加載

  • 創(chuàng)建Fragment的xml布局文件
  • 在Fragment的onCreateView中inflate布局,返回
  • 在Activity的布局文件中的適當(dāng)位置添加fragment標(biāo)簽,指定name為Fragment的完整類名(這時(shí)候Activity中可以直接通過(guò)findViewById找到Fragment中的控件)
  • 動(dòng)態(tài)加載(需要用到事務(wù)操作,常用)

  • 創(chuàng)建Fragment的xml布局文件

  • 在Fragment的onCreateView中inflate布局,返回

    @Nullable @Override public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {return inflater.inflate(R.layout.activity_main, container, false); }
  • 在Activity中通過(guò)獲取FragmentManager(SupportFragmentManager),通過(guò)beginTransaction()方法開(kāi)啟事務(wù)

  • 進(jìn)行add()/remove()/replace()/attach()/detach()/hide()/addToBackStack()事務(wù)操作(都是對(duì)Fragment的棧進(jìn)行操作,其中add()指定的tag參數(shù)可以方便以后通過(guò)findFragmentByTag()找到這個(gè)Fragment)

  • 提交事務(wù):commit()

    示例代碼:

    @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, new TestFragment(), "test").commit();TestFragment f = (TestFragment) getSupportFragmentManager().findFragmentByTag("test"); }

5. Fragment通信問(wèn)題

  • 通過(guò)findFragmentByTag或者getActivity獲得對(duì)方的引用(強(qiáng)轉(zhuǎn))之后,再相互調(diào)用對(duì)方的public方法。

    優(yōu)點(diǎn):簡(jiǎn)單粗暴
    缺點(diǎn):引入了“強(qiáng)轉(zhuǎn)”的丑陋代碼,另外兩個(gè)類之間各自持有對(duì)方的強(qiáng)引用,耦合較大,容易造成內(nèi)存泄漏

  • 通過(guò)Bundle的方法進(jìn)行傳值,在添加Fragment的時(shí)候進(jìn)行通信

    @Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Fragment fragment = new TestFragment();Bundle bundle = new Bundle();bundle.putString("key", "value");//Activity中對(duì)fragment設(shè)置一些參數(shù)fragment.setArguments(bundle);getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, fragment, "test").commit(); }

    優(yōu)點(diǎn):簡(jiǎn)單粗暴
    缺點(diǎn):只能在Fragment添加到Activity的時(shí)候才能使用,屬于單向通信

  • 利用eventbus進(jìn)行通信

    優(yōu)點(diǎn):實(shí)時(shí)性高,雙向通信,Activity與Fragment之間可以完全解耦
    缺點(diǎn):反射影響性能,無(wú)法獲取返回?cái)?shù)據(jù),EventBUS難以維護(hù)

  • 利用接口回調(diào)進(jìn)行通信(Google官方推薦)

    //MainActivity實(shí)現(xiàn)MainFragment開(kāi)放的接口 public class MainActivity extends FragmentActivity implements FragmentListener {@overridepublic void toH5Page() {//...其他處理代碼省略} } //Fragment的實(shí)現(xiàn) public class MainFragment extends Fragment {//接口的實(shí)例,在onAttach Activity的時(shí)候進(jìn)行設(shè)置public FragmentListener mListener;//MainFragment開(kāi)放的接口public static interface FragmentListener {//跳到h5頁(yè)面void toH5Page();}@Overridepublic void onAttach(Activity activity) {super.onAttach(activity);//對(duì)傳遞進(jìn)來(lái)的Activity進(jìn)行接口轉(zhuǎn)換if (activity instance FragmentListener){mListener = ((FragmentListener) activity);}}...其他處理代碼省略 }

    優(yōu)點(diǎn):既能達(dá)到復(fù)用,又能達(dá)到很好的可維護(hù)性,并且性能得到保證
    缺點(diǎn):假如項(xiàng)目很大了,Activity與Fragment的數(shù)量也會(huì)增加,這時(shí)候?yàn)槊繉?duì)Activity與Fragment交互定義交互接口就是一個(gè)很麻煩的問(wèn)題(包括為接口的命名,新定義的接口相應(yīng)的Activity還得實(shí)現(xiàn),相應(yīng)的Fragment還得進(jìn)行強(qiáng)制轉(zhuǎn)換)

  • 通過(guò)Handler進(jìn)行通信(其實(shí)就是把接口的方式改為Handler)

    優(yōu)點(diǎn):既能達(dá)到復(fù)用,又能達(dá)到很好的可維護(hù)性,并且性能得到保證
    缺點(diǎn):Fragment對(duì)具體的Activity存在耦合,不利于Fragment復(fù)用和維護(hù),沒(méi)法獲取Activity的返回?cái)?shù)據(jù)

  • 通過(guò)廣播/本地廣播進(jìn)行通信

    優(yōu)點(diǎn):簡(jiǎn)單粗暴
    缺點(diǎn):大材小用,存在性能損耗,傳播數(shù)據(jù)必須實(shí)現(xiàn)序列化接口

  • 父子Fragment之間通信,可以使用getParentFragment()/getChildFragmentManager()的方式進(jìn)行

  • 6. FragmentPageAdapter和FragmentPageStateAdapter的區(qū)別

    • FragmentPageAdapter在每次切換頁(yè)面的時(shí)候,是將Fragment進(jìn)行分離,適合頁(yè)面較少的Fragment使用以保存一些內(nèi)存,對(duì)系統(tǒng)內(nèi)存不會(huì)多大影響

      @Override public void destroyItem(ViewGroup container, int position, Object object) {if (mCurTransaction == null) {mCurTransaction = mFragmentManager.beginTransaction();}if (DEBUG) Log.v(TAG, "Detaching item #" + getItemId(position) + ": f=" + object+ " v=" + ((Fragment)object).getView());//FragmentPageAdapter在destroyItem的時(shí)候調(diào)用detachmCurTransaction.detach((Fragment)object); }
    • FragmentPageStateAdapter在每次切換頁(yè)面的時(shí)候,是將Fragment進(jìn)行回收,適合頁(yè)面較多的Fragment使用,這樣就不會(huì)消耗更多的內(nèi)存

      @Override public void destroyItem(ViewGroup container, int position, Object object) {Fragment fragment = (Fragment) object;if (mCurTransaction == null) {mCurTransaction = mFragmentManager.beginTransaction();}if (DEBUG) Log.v(TAG, "Removing item #" + position + ": f=" + object+ " v=" + ((Fragment)object).getView());while (mSavedState.size() <= position) {mSavedState.add(null);}mSavedState.set(position, fragment.isAdded()? mFragmentManager.saveFragmentInstanceState(fragment) : null);mFragments.set(position, null);//FragmentPageStateAdapter在destroyItem的時(shí)候調(diào)用removemCurTransaction.remove(fragment); }

    7. 參考文章

    Android:Activity與Fragment通信(99%)完美解決方案

    Service

    1. 什么是Service

    Service是四大組件之一,它可以在后臺(tái)執(zhí)行長(zhǎng)時(shí)間運(yùn)行操作而沒(méi)有用戶界面的應(yīng)用組件

    2. Service的兩種啟動(dòng)方式與生命周期

    startService特點(diǎn):

  • 使用這種start方式啟動(dòng)的Service的生命周期如下:onCreate()—>onStartCommand()(onStart()方法已過(guò)時(shí)) —> onDestroy()
  • 如果服務(wù)已經(jīng)開(kāi)啟,不會(huì)重復(fù)的執(zhí)行onCreate(), 而是會(huì)調(diào)用onStart()和onStartCommand()
  • 一旦服務(wù)開(kāi)啟跟調(diào)用者(開(kāi)啟者)就沒(méi)有任何關(guān)系了。
  • 開(kāi)啟者退出了,開(kāi)啟者掛了,服務(wù)還在后臺(tái)長(zhǎng)期的運(yùn)行。
  • 開(kāi)啟者不能調(diào)用服務(wù)里面的方法。
  • bindService特點(diǎn):

  • 使用這種start方式啟動(dòng)的Service的生命周期如下:onCreate() —>onBind()—>onUnbind()—>onDestroy()
  • 綁定服務(wù)不會(huì)調(diào)用onStart()或者onStartCommand()方法
  • bind的方式開(kāi)啟服務(wù),綁定服務(wù)。調(diào)用者調(diào)用unbindService解除綁定,服務(wù)也會(huì)跟著銷毀。
  • 綁定者可以調(diào)用服務(wù)里面的方法。
  • 3. Service和Thread的區(qū)別

    • Service是安卓中系統(tǒng)的組件,它運(yùn)行在獨(dú)立進(jìn)程的主線程中,默認(rèn)情況下不可以執(zhí)行耗時(shí)操作(否則ANR)
    • Thread是程序執(zhí)行的最小單元,分配CPU的基本單位,可以開(kāi)啟子線程執(zhí)行耗時(shí)操作
    • Service在不同Activity中可以獲取自身實(shí)例,可以方便的對(duì)Service進(jìn)行操作
    • Thread的運(yùn)行是獨(dú)立于Activity的,也就是說(shuō)當(dāng)一個(gè)Activity被finish之后,如果沒(méi)有主動(dòng)停止Thread或者Thread里的run方法沒(méi)有執(zhí)行完畢的話,Thread也會(huì)一直執(zhí)行,引發(fā)內(nèi)存泄漏;另一方面,沒(méi)有辦法在不同的Activity中對(duì)同一Thread進(jìn)行控制。

    Broadcast

    1. BroadcastReceiver是什么

    BroadcastReceiver是四大組件之一,是一種廣泛運(yùn)用在應(yīng)用程序之間傳輸信息的機(jī)制,通過(guò)發(fā)送Intent來(lái)傳送我們的數(shù)據(jù)。

    2. BroadcastReceiver的使用場(chǎng)景

    • 不同組件之間的消息通信(應(yīng)用內(nèi)/應(yīng)用內(nèi)不同進(jìn)程/不同進(jìn)程(應(yīng)用))
    • 與Android系統(tǒng)在特定情況下的通信(如電話呼入、藍(lán)牙狀態(tài)變化等)
    • 線程之間的通信

    3. Broadcast種類

  • 普通廣播(Normal Broadcast)

    • 通過(guò)sendBroadcast進(jìn)行發(fā)送,如果注冊(cè)了Action匹配的接受者則會(huì)收到
    • 若發(fā)送廣播有相應(yīng)權(quán)限,那么廣播接收者也需要相應(yīng)權(quán)限
  • 系統(tǒng)廣播(System Broadcast)

    • Android中內(nèi)置了多個(gè)系統(tǒng)廣播:只要涉及到手機(jī)的基本操作(如開(kāi)機(jī)、網(wǎng)絡(luò)狀態(tài)變化、拍照等等),都會(huì)發(fā)出相應(yīng)的廣播
    • 每個(gè)廣播都有特定的Intent - Filter(包括具體的action)
    • 系統(tǒng)廣播由系統(tǒng)發(fā)送,不需要手動(dòng)發(fā)送,只需要注冊(cè)監(jiān)聽(tīng)
  • 有序廣播(Ordered Broadcast)

    • 通過(guò)sendOrderedBroadcast發(fā)送
    • 發(fā)送出去的廣播被廣播接收者按照先后順序接收(有序是針對(duì)廣播接收者而言的)
    • 廣播接受者接收廣播的順序規(guī)則:Priority大的優(yōu)先;動(dòng)態(tài)注冊(cè)的接收者優(yōu)先
    • 先接收的可以對(duì)廣播進(jìn)行截?cái)嗪托薷?/li>
  • App應(yīng)用內(nèi)廣播(本地廣播、Local Broadcast)

    • 通過(guò)LocalBroadcastManager.getInstance(this).sendBroadcastSync();
    • App應(yīng)用內(nèi)廣播可理解為一種局部廣播,廣播的發(fā)送者和接收者都同屬于一個(gè)App
    • 相比于全局廣播(普通廣播),App應(yīng)用內(nèi)廣播優(yōu)勢(shì)體現(xiàn)在:安全性高 & 效率高(本地廣播只會(huì)在APP內(nèi)傳播,安全性高;不允許其他APP對(duì)自己的APP發(fā)送廣播,效率高)
  • 粘性廣播(Sticky Broadcast)

    • 在Android5.0 & API 21中已經(jīng)失效,所以不建議使用
    • 通過(guò)sendStickyBroadcast發(fā)送
    • 粘性廣播在發(fā)送后就一直存在于系統(tǒng)的消息容器里面,等待對(duì)應(yīng)的處理器去處理,如果暫時(shí)沒(méi)有處理器處理這個(gè)廣播則一直在消息容器里面處于等待狀態(tài)
    • 粘性廣播的Receiver如果被銷毀,那么下次重新創(chuàng)建的時(shí)候會(huì)自動(dòng)接收到消息數(shù)據(jù)
  • 4. 廣播的注冊(cè)方式

    • 靜態(tài)注冊(cè):也稱為清單注冊(cè),就是在AndroidManifest.xml中注冊(cè)的廣播。此類廣播接收器在應(yīng)用尚未啟動(dòng)的時(shí)候就可以接收到相應(yīng)廣播。
    • 動(dòng)態(tài)注冊(cè):也稱為運(yùn)行時(shí)注冊(cè),也就是在Service或者Activity組件中,通過(guò)Context.registerReceiver()注冊(cè)廣播接收器。此類廣播接收器是在應(yīng)用已啟動(dòng)后,通過(guò)代碼進(jìn)行注冊(cè)。生命周期與組件一致。

    5. 廣播的實(shí)現(xiàn)機(jī)制

    6. 本地廣播的使用以及實(shí)現(xiàn)機(jī)制

    • 基本使用:可以通過(guò)intent.setPackage(packageName)指定包名,也可以使用localBroadcastManager(常用),示例代碼如下:

      //注冊(cè)應(yīng)用內(nèi)廣播接收器 //步驟1:實(shí)例化BroadcastReceiver子類 & IntentFilter mBroadcastReceiver mBroadcastReceiver = new mBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter();//步驟2:實(shí)例化LocalBroadcastManager的實(shí)例 localBroadcastManager = LocalBroadcastManager.getInstance(this);//步驟3:設(shè)置接收廣播的類型 intentFilter.addAction(android.net.conn.CONNECTIVITY_CHANGE);//步驟4:調(diào)用LocalBroadcastManager單一實(shí)例的registerReceiver()方法進(jìn)行動(dòng)態(tài)注冊(cè) localBroadcastManager.registerReceiver(mBroadcastReceiver, intentFilter);//取消注冊(cè)應(yīng)用內(nèi)廣播接收器 localBroadcastManager.unregisterReceiver(mBroadcastReceiver);//發(fā)送應(yīng)用內(nèi)廣播 Intent intent = new Intent(); intent.setAction(BROADCAST_ACTION); localBroadcastManager.sendBroadcast(intent);
    • localBroadcastManager的實(shí)現(xiàn)機(jī)制

    • LocalBroadcastManager高效的原因主要是因?yàn)樗鼉?nèi)部是通過(guò)Handler實(shí)現(xiàn)的,它的sendBroadcast()方法含義和我們平時(shí)所用的全局廣播不一樣,它的sendBroadcast()方法其實(shí)是通過(guò)handler發(fā)送一個(gè)Message實(shí)現(xiàn)的。
    • 既然是它內(nèi)部是通過(guò)Handler來(lái)實(shí)現(xiàn)廣播的發(fā)送的,那么相比與系統(tǒng)廣播通過(guò)Binder實(shí)現(xiàn)那肯定是更高效了,同時(shí)使用Handler來(lái)實(shí)現(xiàn),別的應(yīng)用無(wú)法向我們的應(yīng)用發(fā)送該廣播,而我們應(yīng)用內(nèi)發(fā)送的廣播也不會(huì)離開(kāi)我們的應(yīng)用
    • LocalBroadcastManager內(nèi)部協(xié)作主要是靠這兩個(gè)Map集合:mReceivers和mActions,當(dāng)然還有一個(gè)List集合mPendingBroadcasts,這個(gè)主要就是存儲(chǔ)待接收的廣播對(duì)象

    7. 參考文章

    Android四大組件:BroadcastReceiver史上最全面解析

    Android 粘性廣播StickyBroadcast的使用

    咦,Oreo怎么收不到廣播了?

    LocalBroadcastManager—?jiǎng)?chuàng)建更高效、更安全的廣播

    WebView

    1. WebView遠(yuǎn)程代碼執(zhí)行安全漏洞

    漏洞描述

    Android API level 16以及之前的版本存在遠(yuǎn)程代碼執(zhí)行安全漏洞,該漏洞源于程序沒(méi)有正確限制使用WebView.addJavascriptInterface方法,遠(yuǎn)程攻擊者可通過(guò)使用Java Reflection API利用該漏洞執(zhí)行任意Java對(duì)象的方法。

    簡(jiǎn)單的說(shuō)就是通過(guò)addJavascriptInterface給WebView加入一個(gè)JavaScript橋接接口,JavaScript通過(guò)調(diào)用這個(gè)接口可以直接操作本地的JAVA接口。

    示例代碼

    WebView代碼如下所示:

    mWebView = new WebView(this); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.addJavascriptInterface(this, "injectedObj"); mWebView.loadUrl("file:///android_asset/www/index.html");

    發(fā)送惡意短信:

    <html><body><script>var objSmsManager = injectedObj.getClass().forName("android.telephony.SmsManager").getM ethod("getDefault",null).invoke(null,null);objSmsManager.sendTextMessage("10086",null,"this message is sent by JS when webview is loading",null,null);</script></body> </html>

    利用反射機(jī)制調(diào)用Android API getRuntime執(zhí)行shell命令,最終操作用戶的文件系統(tǒng):

    <html><body><script>function execute(cmdArgs){return injectedObj.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec(cmdArgs);}var res = execute(["/system/bin/sh", "-c", "ls -al /mnt/sdcard/"]);document.write(getContents(res.getInputStream()));</script></body> </html>
    漏洞檢測(cè)
  • 檢查應(yīng)用源代碼中是否調(diào)用Landroid/webkit/WebView類中的addJavascriptInterface方法,是否存在searchBoxJavaBridge_、accessibility、accessibilityTraversal接口
  • 在線檢測(cè):騰訊TSRC在線檢測(cè)頁(yè)面(http://security.tencent.com/lucky/check_tools.html)、烏云知識(shí)庫(kù)在線檢測(cè)(http://drops.wooyun.org/webview.html)
  • 在線檢測(cè)原理:遍歷所有window的對(duì)象,然后找到包含getClass方法的對(duì)象,如果存在此方法的對(duì)象則說(shuō)明該接口存在漏洞。
  • 漏洞修復(fù)
  • 允許被調(diào)用的函數(shù)必須以@JavascriptInterface進(jìn)行注解(API Level小于17的應(yīng)用也會(huì)受影響)

  • 建議不要使用addJavascriptInterface接口,以免帶來(lái)不必要的安全隱患,采用動(dòng)態(tài)地生成將注入的JS代碼的方式來(lái)代替

  • 如果一定要使用addJavascriptInterface接口:

  • 如果使用HTTPS協(xié)議加載URL,應(yīng)進(jìn)行證書(shū)校驗(yàn)防止訪問(wèn)的頁(yè)面被篡改掛馬;
  • 如果使用HTTP協(xié)議加載URL,應(yīng)進(jìn)行白名單過(guò)濾、完整性校驗(yàn)等防止訪問(wèn)的頁(yè)面被篡改;
  • 如果加載本地Html,應(yīng)將html文件內(nèi)置在APK中,以及進(jìn)行對(duì)html頁(yè)面完整性的校驗(yàn);
  • 移除Android系統(tǒng)內(nèi)部的默認(rèn)內(nèi)置接口

    removeJavascriptInterface("searchBoxJavaBridge_"); removeJavascriptInterface("accessibility"); removeJavascriptInterface("accessibilityTraversal");
  • 2. JSBridge

    客戶端和服務(wù)端之間可以通過(guò)JSBridge來(lái)互相調(diào)用各自的方法,實(shí)現(xiàn)雙向通信

    3. WebView的正確銷毀與內(nèi)存泄漏問(wèn)題

    由于WebView是依附于Activity的,Activity的生命周期和WebView啟動(dòng)的線程的生命周期是不一致的,這會(huì)導(dǎo)致WebView一直持有對(duì)這個(gè)Activity的引用而無(wú)法釋放,解決方案如下

  • 獨(dú)立進(jìn)程,簡(jiǎn)單暴力,不過(guò)可能涉及到進(jìn)程間通信(推薦)

  • 動(dòng)態(tài)添加WebView,對(duì)傳入WebView中使用的Context使用弱引用

  • 正確銷毀WebView,WebView在其他容器上時(shí)(如:LinearLayout),當(dāng)銷毀Activity時(shí),需要:

  • 在onDestroy()中先移除容器上的WebView
  • 然后再將WebView.destroy(),這樣就不會(huì)導(dǎo)致內(nèi)存泄漏
  • 4. WebView后臺(tái)耗電

    問(wèn)題

    在WebView加載頁(yè)面的時(shí)候,會(huì)自動(dòng)開(kāi)啟線程去加載,如果不很好的關(guān)閉這些線程,就會(huì)導(dǎo)致電量消耗加大。

    解決方法

    可以采用暴力的方法,直接在onDestroy方法中System.exit(0)結(jié)束當(dāng)前正在運(yùn)行中的java虛擬機(jī)

    5. WebView硬件加速

    WebView硬件加速以及缺點(diǎn)

    Android3.0引入硬件加速,默認(rèn)會(huì)開(kāi)啟,WebView在硬件加速的情況下滑動(dòng)更加平滑,性能更加好,但是會(huì)出現(xiàn)白塊或者頁(yè)面閃爍的副作用。

    解決方案

    建議在需要的地方WebView暫時(shí)關(guān)閉硬件加速

    6. WebViewClient的onPageFinished問(wèn)題

    問(wèn)題

    WebViewClient.onPageFinished在每次頁(yè)面加載完成的時(shí)候調(diào)用,但是遇到未加載完成的頁(yè)面跳轉(zhuǎn)其他頁(yè)面時(shí),就會(huì)被一直調(diào)用

    解決方案

    使用WebChromeClient.onProgressChanged替代WebViewClient.onPageFinished

    7. 參考文章

    WebView 遠(yuǎn)程代碼執(zhí)行漏洞淺析

    Android WebView遠(yuǎn)程執(zhí)行代碼漏洞淺析

    Android WebView 遠(yuǎn)程代碼執(zhí)行漏洞簡(jiǎn)析

    在WebView中如何讓JS與Java安全地互相調(diào)用

    Android系統(tǒng)架構(gòu)與Framework源碼分析

    1. Android系統(tǒng)架構(gòu)

    根據(jù)上圖,Android系統(tǒng)架構(gòu)從上往下分別是:

  • 應(yīng)用框架:應(yīng)用框架最常被應(yīng)用開(kāi)發(fā)者使用。作為硬件開(kāi)發(fā)者,我們應(yīng)該非常了解開(kāi)發(fā)者 API,因?yàn)楹芏啻祟?API 都可直接映射到底層 HAL 接口,并可提供與實(shí)現(xiàn)驅(qū)動(dòng)程序相關(guān)的實(shí)用信息。
  • Binder IPC:Binder 進(jìn)程間通信 (IPC) 機(jī)制允許應(yīng)用框架跨越進(jìn)程邊界并調(diào)用 Android 系統(tǒng)服務(wù)代碼,從而使得高級(jí)框架 API 能與 Android 系統(tǒng)服務(wù)進(jìn)行交互。在應(yīng)用框架級(jí)別,開(kāi)發(fā)者無(wú)法看到此類通信的過(guò)程,但一切似乎都在“按部就班地運(yùn)行”。
  • 系統(tǒng)服務(wù):應(yīng)用框架 API 所提供的功能可與系統(tǒng)服務(wù)通信,以訪問(wèn)底層硬件。服務(wù)是集中的模塊化組件,例如窗口管理器、搜索服務(wù)或通知管理器。Android 包含兩組服務(wù):“系統(tǒng)”(諸如窗口管理器和通知管理器之類的服務(wù))和“媒體”(與播放和錄制媒體相關(guān)的服務(wù))。
  • 硬件抽象層 (HAL):硬件抽象層 (HAL) 會(huì)定義一個(gè)標(biāo)準(zhǔn)接口以供硬件供應(yīng)商實(shí)現(xiàn),并允許 Android 忽略較低級(jí)別的驅(qū)動(dòng)程序?qū)崿F(xiàn)。借助 HAL,我們可以順利實(shí)現(xiàn)相關(guān)功能,而不會(huì)影響或無(wú)需更改更高級(jí)別的系統(tǒng)。HAL 實(shí)現(xiàn)會(huì)被封裝成模塊 (.so) 文件,并會(huì)由 Android 系統(tǒng)適時(shí)地加載。
  • Linux 內(nèi)核:開(kāi)發(fā)設(shè)備驅(qū)動(dòng)程序與開(kāi)發(fā)典型的 Linux 設(shè)備驅(qū)動(dòng)程序類似。Android 使用的 Linux 內(nèi)核版本包含一些特殊的補(bǔ)充功能,例如:喚醒鎖(這是一種內(nèi)存管理系統(tǒng),可更主動(dòng)地保護(hù)內(nèi)存)、Binder IPC 驅(qū)動(dòng)程序以及對(duì)移動(dòng)嵌入式平臺(tái)非常重要的其他功能。這些補(bǔ)充功能主要用于增強(qiáng)系統(tǒng)功能,不會(huì)影響驅(qū)動(dòng)程序開(kāi)發(fā)。我們可以使用任一版本的內(nèi)核,只要它支持所需功能(如 Binder 驅(qū)動(dòng)程序)。不過(guò),建議使用 Android 內(nèi)核的最新版本。
  • 2. Android Framework源碼分析

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(1)- Binder與AIDL

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(2)- AMS與APP、Activity的啟動(dòng)流程

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(3)- AMS與APP、Activity的啟動(dòng)流程

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(4)- Context

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(5)- Service

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(6)- BroadcastReceiver

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(7)- ContentProvider

    寫給Android App開(kāi)發(fā)人員看的Android底層知識(shí)(8)- PMS及App安裝過(guò)程

    除此之外,還有消息機(jī)制、窗口管理等源碼分析,推薦《開(kāi)發(fā)藝術(shù)探索》,以及LooperJing的文集:

    Android源碼解析

    • 備注:源碼分析部分先放一放,后續(xù)補(bǔ)充一些簡(jiǎn)要概括性的

    消息機(jī)制與Handler

    1. 基本概念

    Android的消息機(jī)制主要包括Handler、MessageQueue和Looper。

    Handler是Android中引入的一種讓開(kāi)發(fā)者參與處理線程中消息循環(huán)的機(jī)制。每個(gè)Handler都關(guān)聯(lián)了一個(gè)線程,每個(gè)線程內(nèi)部都維護(hù)了一個(gè)消息隊(duì)列MessageQueue,這樣Handler實(shí)際上也就關(guān)聯(lián)了一個(gè)消息隊(duì)列。可以通過(guò)Handler將Message和Runnable對(duì)象發(fā)送到該Handler所關(guān)聯(lián)線程的MessageQueue(消息隊(duì)列)中,然后該消息隊(duì)列一直在循環(huán)拿出一個(gè)Message,對(duì)其進(jìn)行處理,處理完之后拿出下一個(gè)Message,繼續(xù)進(jìn)行處理,周而復(fù)始。

    2. 為什么要有消息機(jī)制

    Android的UI控件不是線程安全的,如果在多線程中訪問(wèn)UI控件則會(huì)導(dǎo)致不可預(yù)期的狀態(tài)。那為什么不對(duì)UI控件訪問(wèn)加鎖呢?

    訪問(wèn)加鎖缺點(diǎn)有兩個(gè):

  • 首先加鎖會(huì)讓UI控件的訪問(wèn)的邏輯變的復(fù)雜;
  • 其次,鎖機(jī)制會(huì)降低UI的訪問(wèn)效率。
  • 那我們不用線程來(lái)操作不就行了嗎?但這是不可能的,因?yàn)锳ndroid的主線程不能執(zhí)行耗時(shí)操作,否則會(huì)出現(xiàn)ANR。

    所以,從各方面來(lái)說(shuō),Android消息機(jī)制是為了解決在子線程中無(wú)法訪問(wèn)UI的矛盾。

    3. Handler的工作原理

    如圖所示,在主線程ActivityThread中的main方法入口中,先是創(chuàng)建了系統(tǒng)的Handler(H),創(chuàng)建主線程的Looper,將Looper與主線程綁定,調(diào)用了Looper的loop方法之后開(kāi)啟整個(gè)應(yīng)用程序的主循環(huán)。Looper里面有一個(gè)消息隊(duì)列,通過(guò)Handler發(fā)送消息到消息隊(duì)列里面,然后通過(guò)Looper不斷去循環(huán)取出消息,交給Handler去處理。通過(guò)系統(tǒng)的Handler,或者說(shuō)Android的消息處理機(jī)制就確保了整個(gè)Android系統(tǒng)有條不紊地運(yùn)作,這是Android系統(tǒng)里面的一個(gè)比較重要的機(jī)制。

    我們的APP也可以創(chuàng)建自己的Handler,可以是在主線程里面創(chuàng)建,也可以在子線程里面創(chuàng)建,但是需要手動(dòng)創(chuàng)建子線程的Looper并且手動(dòng)啟動(dòng)消息循環(huán)。

    4. Handler的內(nèi)存泄漏問(wèn)題

    原因

    非靜態(tài)內(nèi)部類持有外部類的匿名引用,導(dǎo)致Activity無(wú)法釋放(生命周期不一致)

    解決方案
    • Handler內(nèi)部持有外部Activity的弱引用
    • Handler改為靜態(tài)內(nèi)部類
    • 在適當(dāng)時(shí)機(jī)移除Handler的所有Callback()

    5. 為什么在子線程中創(chuàng)建Handler會(huì)拋異常?

    Handler的工作是依賴于Looper的,而Looper(與消息隊(duì)列)又是屬于某一個(gè)線程(ThreadLocal是線程內(nèi)部的數(shù)據(jù)存儲(chǔ)類,通過(guò)它可以在指定線程中存儲(chǔ)數(shù)據(jù),其他線程則無(wú)法獲取到),其他線程不能訪問(wèn)。
    因此Handler就是間接跟線程是綁定在一起了。因此要使用Handler必須要保證Handler所創(chuàng)建的線程中有Looper對(duì)象并且啟動(dòng)循環(huán)。因?yàn)樽泳€程中默認(rèn)是沒(méi)有Looper的,所以會(huì)報(bào)錯(cuò)。

    正確的在子線程中創(chuàng)建Handler的方法如下(可以使用HandlerThread代替):

    handler = null;new Thread(new Runnable() {private Looper mLooper;@Overridepublic void run() {//必須調(diào)用Looper的prepare方法為當(dāng)前線程創(chuàng)建一個(gè)Looper對(duì)象,然后啟動(dòng)循環(huán)//prepare方法中實(shí)質(zhì)是給ThreadLocal對(duì)象創(chuàng)建了一個(gè)Looper對(duì)象//如果當(dāng)前線程已經(jīng)創(chuàng)建過(guò)Looper對(duì)象了,那么會(huì)報(bào)錯(cuò)Looper.prepare();handler = new Handler();//獲取Looper對(duì)象mLooper = Looper.myLooper();//啟動(dòng)消息循環(huán)Looper.loop();//在適當(dāng)?shù)臅r(shí)候退出Looper的消息循環(huán),防止內(nèi)存泄漏mLooper.quit();}}).start();

    注意:

    • 主線程中默認(rèn)是創(chuàng)建了Looper并且啟動(dòng)了消息的循環(huán)的,因此不會(huì)報(bào)錯(cuò)。
    • 應(yīng)用程序的入口是ActivityThread的main方法,在這個(gè)方法里面會(huì)創(chuàng)建Looper,并且執(zhí)行Looper的loop方法來(lái)啟動(dòng)消息的循環(huán),使得應(yīng)用程序一直運(yùn)行。
    • 有時(shí)候出于業(yè)務(wù)需要,主線程可以向子線程發(fā)送消息。子線程的Handler必須按照上述方法創(chuàng)建,并且關(guān)聯(lián)Looper。

    6. 為什么不能在子線程更新UI?

    UI更新的時(shí)候,會(huì)對(duì)當(dāng)前線程進(jìn)行檢驗(yàn),如果不是主線程,則拋出異常:

    void checkThread() {if (mThread != Thread.currentThread()) {throw new CalledFromWrongThreadException("Only the original thread that created a view hierarchy can touch its views.");} }

    比較特殊的三種情況:

    • 在Activity創(chuàng)建完成后(Activity的onResume之前ViewRootImpl實(shí)例沒(méi)有建立),mThread被賦值為主線程(ViewRootImpl),所以直接在onCreate中創(chuàng)建子線程是可以更新UI的
    • 在子線程中添加 Window,并且創(chuàng)建 ViewRootImpl,可以在子線程中更新view
    • SurfaceView可以在其他線程更新

    7. 參考文章

    Android 源碼分析之旅3.1–消息機(jī)制源碼分析

    android消息機(jī)制原理詳解

    Android中Handler的使用

    AsyncTask

    1. AsyncTask的基本概念與基本工作原理

    它本質(zhì)上就是一個(gè)封裝了線程池和Handler的異步框架。

    AsyncTask執(zhí)行任務(wù)時(shí),內(nèi)部會(huì)創(chuàng)建一個(gè)進(jìn)程作用域的線程池來(lái)管理要運(yùn)行的任務(wù),也就是說(shuō)當(dāng)你調(diào)用了AsyncTask.execute()后,AsyncTask會(huì)把任務(wù)交給線程池,由線程池來(lái)管理創(chuàng)建Thread和運(yùn)行Thread。

    2. AsyncTask使用方法

    三個(gè)參數(shù)
    • Params:表示后臺(tái)任務(wù)執(zhí)行時(shí)的參數(shù)類型,該參數(shù)會(huì)傳給AysncTask的doInBackground()方法
    • Progress:表示后臺(tái)任務(wù)的執(zhí)行進(jìn)度的參數(shù)類型,該參數(shù)會(huì)作為onProgressUpdate()方法的參數(shù)
    • Result:表示后臺(tái)任務(wù)的返回結(jié)果的參數(shù)類型,該參數(shù)會(huì)作為onPostExecute()方法的參數(shù)
    五個(gè)方法
    • onPreExecute():異步任務(wù)開(kāi)啟之前回調(diào),在主線程中執(zhí)行
    • doInBackground():執(zhí)行異步任務(wù),在線程池中執(zhí)行
    • onProgressUpdate():當(dāng)doInBackground中調(diào)用publishProgress時(shí)回調(diào),在主線程中執(zhí)行
    • onPostExecute():在異步任務(wù)執(zhí)行之后回調(diào),在主線程中執(zhí)行
    • onCancelled():在異步任務(wù)被取消時(shí)回調(diào)

    3. AsyncTask的版本差異

    內(nèi)部的線程池的版本差異
  • 3.0之前規(guī)定同一時(shí)刻能夠運(yùn)行的線程數(shù)為5個(gè),線程池總大小為128。也就是說(shuō)當(dāng)我們啟動(dòng)了10個(gè)任務(wù)時(shí),只有5個(gè)任務(wù)能夠立刻執(zhí)行,另外的5個(gè)任務(wù)則需要等待,當(dāng)有一個(gè)任務(wù)執(zhí)行完畢后,第6個(gè)任務(wù)才會(huì)啟動(dòng),以此類推。而線程池中最大能存放的線程數(shù)是128個(gè),當(dāng)我們嘗試去添加第129個(gè)任務(wù)時(shí),程序就會(huì)崩潰。
  • 因此在3.0版本中AsyncTask的改動(dòng)還是挺大的,在3.0之前的AsyncTask可以同時(shí)有5個(gè)任務(wù)在執(zhí)行,而3.0之后的AsyncTask同時(shí)只能有1個(gè)任務(wù)在執(zhí)行。為什么升級(jí)之后可以同時(shí)執(zhí)行的任務(wù)數(shù)反而變少了呢?這是因?yàn)楦潞蟮腁syncTask已變得更加靈活,如果不想使用默認(rèn)的線程池,還可以自由地進(jìn)行配置。
  • 串行、并行的版本差異
  • AsyncTask在Android 2.3之前默認(rèn)采用并行執(zhí)行任務(wù),AsyncTask在Android 2.3之后默認(rèn)采用串行執(zhí)行任務(wù)
  • 如果需要在Android 2.3之后采用并行執(zhí)行任務(wù),可以調(diào)用AsyncTask的executeOnExecutor()
  • 4. AsyncTask的缺陷

    內(nèi)存泄漏問(wèn)題
    原因

    非靜態(tài)內(nèi)部類持有外部類的匿名引用,導(dǎo)致Activity無(wú)法釋放(生命周期不一致,與Handler一樣)

    解決方案
    • AsyncTask內(nèi)部持有外部Activity的弱引用
    • AsyncTask改為靜態(tài)內(nèi)部類
    • 在Activity銷毀之前,調(diào)用AsyncTask.cancel()取消AsyncTask的運(yùn)行,以此來(lái)保證程序的穩(wěn)定
    結(jié)果丟失問(wèn)題
    原因

    在屏幕旋轉(zhuǎn)、Activity在內(nèi)存緊張時(shí)被回收等造成Activity重新創(chuàng)建時(shí)AsyncTask數(shù)據(jù)丟失的問(wèn)題。當(dāng)Activity銷毀并重新創(chuàng)建后,還在運(yùn)行的AsyncTask會(huì)持有一個(gè)Activity的非法引用即之前的Activity實(shí)例。導(dǎo)致onPostExecute()沒(méi)有任何作用(一般是對(duì)UI更新無(wú)效)。

    解決方案
  • 在Activity重建之前cancel異步任務(wù)
  • 在重建之后重新執(zhí)行異步任務(wù)
  • 5. 參考文章

    AsyncTask 使用和缺陷

    HandlerThread

    1. HandlerThread產(chǎn)生背景

    重點(diǎn)(防止線程多次創(chuàng)建、銷毀):當(dāng)系統(tǒng)有多個(gè)耗時(shí)任務(wù)需要執(zhí)行時(shí),每個(gè)任務(wù)都會(huì)開(kāi)啟一個(gè)新線程去執(zhí)行耗時(shí)任務(wù),這樣會(huì)導(dǎo)致系統(tǒng)多次創(chuàng)建和銷毀線程,從而影響性能。為了解決這一問(wèn)題,Google提供了HandlerThread,HandlerThread是在線程中創(chuàng)建一個(gè)Looper循環(huán)器,讓Looper輪詢消息隊(duì)列,當(dāng)有耗時(shí)任務(wù)進(jìn)入隊(duì)列時(shí),則不需要開(kāi)啟新線程,在原有的線程中執(zhí)行耗時(shí)任務(wù)即可,否則線程阻塞。

    HandlerThread集Thread和Handler之所長(zhǎng),適用于會(huì)長(zhǎng)時(shí)間在后臺(tái)運(yùn)行,并且間隔時(shí)間內(nèi)(或適當(dāng)情況下)會(huì)調(diào)用的情況,比如上面所說(shuō)的實(shí)時(shí)更新。

    2. HandlerThread的特點(diǎn)

    • HandlerThread本質(zhì)上是一個(gè)線程,繼承自Thread,與線程池不同,HandlerThread是一個(gè)串行隊(duì)列,背后只有一個(gè)線程

    • HandlerThread有自己的Looper對(duì)象,可以進(jìn)行Looper循環(huán),可以創(chuàng)建Handler

      public class HandlerThread extends Thread {Looper mLooper;private @Nullable Handler mHandler; }
    • HandlerThread可以在Handler的handleMessage中執(zhí)行異步方法,異步不會(huì)堵塞,減少對(duì)性能的消耗

    • HandlerThread缺點(diǎn)是不能同時(shí)繼續(xù)進(jìn)行多任務(wù)處理,需要等待進(jìn)行處理,處理效率較低

    IntentService

    1. IntentService是什么

    • 重點(diǎn)(本質(zhì)上也是為了節(jié)省資源)
    • IntentService是繼承自Service并處理異步請(qǐng)求的一個(gè)類,其內(nèi)部采用HandlerThread和Handler實(shí)現(xiàn)的,在IntentService內(nèi)有一個(gè)工作線程來(lái)處理耗時(shí)操作,其優(yōu)先級(jí)比普通Service高
    • 當(dāng)任務(wù)完成后,IntentService會(huì)自動(dòng)停止,而不需要手動(dòng)調(diào)用stopSelf()
    • 可以多次啟動(dòng)IntentService,每個(gè)耗時(shí)操作都會(huì)以工作隊(duì)列的方式在IntentService中onHandlerIntent()回調(diào)方法中執(zhí)行,并且每次只會(huì)執(zhí)行一個(gè)工作線程

    2. IntentService使用方法

  • 創(chuàng)建Service繼承自IntentService
  • 覆寫構(gòu)造方法和onHandlerIntent()方法
  • 在onHandlerIntent()中執(zhí)行耗時(shí)操作
  • 3. IntentService工作原理

    • IntentService繼承自Service,內(nèi)部有一個(gè)HandlerThread對(duì)象

    • 在onCreate的時(shí)候會(huì)創(chuàng)建一個(gè)HandlerThread對(duì)象,并啟動(dòng)線程

    • 緊接著創(chuàng)建ServiceHandler對(duì)象,ServiceHandler繼承自Handler,用來(lái)處理消息。ServiceHandler將獲取HandlerThread的Looper就可以開(kāi)始正常工作了

      @Overridepublic void onCreate() {super.onCreate();HandlerThread thread = new HandlerThread("IntentService[" + mName + "]");thread.start();mServiceLooper = thread.getLooper();mServiceHandler = new ServiceHandler(mServiceLooper);}
    • 每啟動(dòng)一次onStart方法,就會(huì)把數(shù)消息和數(shù)據(jù)發(fā)給mServiceHandler,相當(dāng)于發(fā)送了一次Message消息給HandlerThread的消息隊(duì)列。

      @Overridepublic void onStart(@Nullable Intent intent, int startId) {Message msg = mServiceHandler.obtainMessage();msg.arg1 = startId;msg.obj = intent;mServiceHandler.sendMessage(msg);}
    • mServiceHandler會(huì)把數(shù)據(jù)傳給onHandleIntent方法,onHandleIntent是個(gè)抽象方法,需要在IntentService實(shí)現(xiàn),所以每次onStart方法之后都會(huì)調(diào)用我們自己寫的onHandleIntent方法去處理。處理完畢使用stopSelf通知HandlerThread已經(jīng)處理完畢,HandlerThread繼續(xù)觀察消息隊(duì)列,如果還有未執(zhí)行玩的message則繼續(xù)執(zhí)行,否則結(jié)束。

      private final class ServiceHandler extends Handler {public ServiceHandler(Looper looper) {super(looper);}@Overridepublic void handleMessage(Message msg) {onHandleIntent((Intent)msg.obj);stopSelf(msg.arg1);}}

    Android項(xiàng)目構(gòu)建過(guò)程

    下圖展示了從一個(gè)Android項(xiàng)目構(gòu)建出一個(gè)帶有簽名、對(duì)齊操作的APK包的完整過(guò)程(省略了代碼混淆過(guò)程、NDK的編譯過(guò)程):

    下面是具體描述:

  • AAPT(Android Asset Packaging Tool)工具會(huì)打包應(yīng)用中的資源文件,如AndroidManifest.xml、layout布局中的xml等,并將xml文件編譯為二進(jìn)制形式,當(dāng)然assets文件夾中的文件不會(huì)被編譯,圖片及raw文件夾中的資源也會(huì)保持原來(lái)的形態(tài),需要注意的是raw文件夾中的資源也會(huì)生成資源id。AAPT編譯完成之后會(huì)生成R.java文件。
  • AIDL工具會(huì)將所有的aidl接口轉(zhuǎn)化為java接口。
  • 所有的java代碼,包括R.java與aidl文件都會(huì)被Java編譯器編譯成.class文件。
  • 如果開(kāi)啟了混淆,Proguard工具會(huì)將上述產(chǎn)生的.class文件及第三庫(kù)及其他.class(包括android.jar)等文件進(jìn)行混淆操作。
  • Dex工具會(huì)將所有需要的.class文件編譯成.dex文件(dex文件是虛擬機(jī)可以執(zhí)行的格式),dex文件最終會(huì)被打包進(jìn)APK文件。
  • ApkBuilder工具會(huì)將編譯過(guò)的資源及未編譯過(guò)的資源(如圖片等)以及.dex文件、NDK工具編譯出的.so文件等打包成APK文件。
  • 生成APK文件后,需要對(duì)其簽名才可安裝到設(shè)備,平時(shí)測(cè)試時(shí)會(huì)使用debug keystore,當(dāng)正式發(fā)布應(yīng)用時(shí)必須使用release版的keystore對(duì)應(yīng)用進(jìn)行簽名。
  • 如果對(duì)APK正式簽名,還需要使用zipalign工具對(duì)APK進(jìn)行對(duì)齊操作,這樣做的好處是當(dāng)應(yīng)用運(yùn)行時(shí)會(huì)提高速度,但是相應(yīng)的會(huì)增加內(nèi)存的開(kāi)銷。
  • 詳細(xì)版本如下:

    代碼混淆

    1. 代碼混淆及其優(yōu)點(diǎn)

    代碼混淆的過(guò)程

    混淆其實(shí)是包括了代碼壓縮、代碼混淆以及資源壓縮等的優(yōu)化過(guò)程。

    這四個(gè)流程默認(rèn)開(kāi)啟,在Android項(xiàng)目中我們可以選擇將“優(yōu)化”和“預(yù)校驗(yàn)”關(guān)閉:

  • 壓縮。移除無(wú)效的類、類成員、方法、屬性等;
  • 優(yōu)化。分析和優(yōu)化方法的二進(jìn)制代碼;根據(jù)proguard-android-optimize.txt中的描述,優(yōu)化可能會(huì)造成一些潛在風(fēng)險(xiǎn),不能保證在所有版本的Dalvik上都正常運(yùn)行。
  • 混淆。把類名、屬性名、方法名替換為簡(jiǎn)短且無(wú)意義的名稱;
  • 預(yù)校驗(yàn)。添加預(yù)校驗(yàn)信息。這個(gè)預(yù)校驗(yàn)是作用在Java平臺(tái)上的,Android平臺(tái)上不需要這項(xiàng)功能,去掉之后還可以加快混淆速度。
  • 代碼混淆的優(yōu)點(diǎn)

    代碼混淆的優(yōu)點(diǎn)如下:

    • ProGuard混淆流程將檢測(cè)主項(xiàng)目以及依賴庫(kù)中未被使用的類、類成員、方法、屬性并移除,這有助于規(guī)避64K方法數(shù)的瓶頸
    • 將類、類成員、方法重命名為無(wú)意義的簡(jiǎn)短名稱,增加了逆向工程的難度(由于Java是一門跨平臺(tái)的解釋性語(yǔ)言,其源代碼被編譯成class字節(jié)碼來(lái)適應(yīng)其他平臺(tái),而class文件包含了Java源代碼信息,很容易被反編譯)
    • 移除未被使用的資源,可以有效減小apk安裝包大小

    2. 代碼混淆操作、調(diào)試步驟

  • 開(kāi)啟混淆、開(kāi)啟資源壓縮

    android {buildTypes {release {minifyEnabled trueshrinkResources trueproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}} }
  • 在proguard-rules.pro添加自定義混淆規(guī)則

    • 第三方庫(kù)所需的混淆規(guī)則。正規(guī)的第三方庫(kù)一般都會(huì)在接入文檔中寫好所需混淆規(guī)則,使用時(shí)注意添加。

    • 在運(yùn)行時(shí)動(dòng)態(tài)改變的代碼,例如反射。比較典型的例子就是會(huì)與 json 相互轉(zhuǎn)換的實(shí)體類。假如項(xiàng)目命名規(guī)范要求實(shí)體類都要放在model包下的話,可以添加類似這樣的代碼把所有實(shí)體類都保持住:

      -keep public class **.*Model*.** {*;}
    • JNI中調(diào)用的類。

    • WebView中JavaScript調(diào)用的方法

    • Layout布局使用的View構(gòu)造函數(shù)、android:onClick等。

  • 檢查混淆結(jié)果,避免因混淆引入的bug。一方面,需要從代碼層面檢查。使用上文的配置進(jìn)行混淆打包后在 /build/outputs/mapping/release/ 目錄下會(huì)輸出以下文件:

    • dump.txt:描述APK文件中所有類的內(nèi)部結(jié)構(gòu)
    • mapping.txt:提供混淆前后類、方法、類成員等的對(duì)照表
    • seeds.txt:列出沒(méi)有被混淆的類和成員
    • usage.txt:列出被移除的代碼
      gi
  • 開(kāi)啟代碼混淆后的調(diào)試

    retrace.bat|retrace.sh [-verbose] mapping.txt [<stacktrace_file>]
  • 3. 代碼混淆的工作原理

    ProGuard過(guò)程中將無(wú)用的字段或方法存入到EntryPoint中,將非EntryPoint的字段和方法進(jìn)行替換,其中Entry Point是在ProGuard過(guò)程中不會(huì)被處理的類或方法。詳細(xì)描述如下:

  • 在壓縮的步驟中,ProGuard會(huì)從上述的Entry Point開(kāi)始遞歸遍歷,搜索哪些類和類的成員在使用,對(duì)于沒(méi)有被使用的類和類的成員,就會(huì)在壓縮段丟棄。
  • 在接下來(lái)的優(yōu)化過(guò)程中,那些非Entry Point的類、方法都會(huì)被設(shè)置為private、static或final,不使用的參數(shù)會(huì)被移除,此外,有些方法會(huì)被標(biāo)記為內(nèi)聯(lián)的。
  • 在混淆的步驟中,ProGuard會(huì)對(duì)非Entry Point的類和方法進(jìn)行重命名。
  • 4. 參考文章

    寫給Android開(kāi)發(fā)者的混淆使用手冊(cè)

    持續(xù)集成

    1. 持續(xù)集成的基本概念

    • 持續(xù)集成(Continuous Integration),持續(xù)集成是一種軟件開(kāi)發(fā)實(shí)踐,通過(guò)自動(dòng)化的構(gòu)建(包括編譯、發(fā)布和自動(dòng)化測(cè)試)來(lái)驗(yàn)證,從而幫助盡快發(fā)現(xiàn)集成錯(cuò)誤。
    • 持續(xù)集成一直被認(rèn)為是敏捷開(kāi)發(fā)的重要實(shí)踐之一,也是提升軟件質(zhì)量的重要手段。特別在團(tuán)隊(duì)協(xié)作開(kāi)發(fā)中,為項(xiàng)目添加持續(xù)集成還是非常有必要的,確保了任何時(shí)間、任何地點(diǎn)生成可部署的軟件。

    2. Jenkins+Git+Gradle實(shí)現(xiàn)持續(xù)集成

  • 安裝Jenkins,安裝需要的插件(比如說(shuō)git插件、Gradle插件),配置JDK,Git,Gradle等編譯環(huán)境
  • 創(chuàng)建新的Jenkins項(xiàng)目,配置Git代碼倉(cāng)庫(kù)地址、配置構(gòu)建時(shí)的Gradle版本,和需要執(zhí)行的Gradle Task
  • 配置Jenkins項(xiàng)目的構(gòu)建參數(shù),比如Gradle Task的參數(shù)、渠道參數(shù)
  • 配置郵件通知
  • 開(kāi)始構(gòu)建
  • 3. 參考文章

    Android Jenkins+Git+Gradle持續(xù)集成-實(shí)在太詳細(xì)

    ANR

    1. ANR是什么

    Android中,主線程(UI線程)如果在規(guī)定時(shí)內(nèi)沒(méi)有處理完相應(yīng)工作,就會(huì)出現(xiàn)ANR(Application Not Responding),彈出頁(yè)面無(wú)響應(yīng)的對(duì)話框。

    2. ANR分類

  • Activity的輸入事件(按鍵和觸摸事件)5s內(nèi)沒(méi)被處理: Input event dispatching timed out
  • BroadcastReceiver的事件(onReceive方法)在規(guī)定時(shí)間內(nèi)沒(méi)處理完(前臺(tái)廣播為10s,后臺(tái)廣播為60s): Timeout of broadcast BroadcastRecord
  • Service在規(guī)定時(shí)間內(nèi)(前臺(tái)20s/后臺(tái)200s)未響應(yīng): Timeout executing service
  • ContentProvider的publish在10s內(nèi)沒(méi)進(jìn)行完: Timeout publishing content providers
  • 3. ANR的核心原因

    • 主線程在做一些耗時(shí)的工作
    • 主線程被其他線程鎖
    • cpu被其他進(jìn)程占用,該進(jìn)程沒(méi)被分配到足夠的cpu資源。

    4. ANR的原理

  • 在進(jìn)行相關(guān)操作調(diào)用Handler.sendMessageAtTime()發(fā)送一個(gè)ANR的消息,延時(shí)時(shí)間為ANR發(fā)生的時(shí)間(如前臺(tái)Service是當(dāng)前時(shí)間20s之后)。
  • 進(jìn)行相關(guān)的操作
  • 操作結(jié)束后向remove掉該條Message。
  • 如果相關(guān)的操作在規(guī)定時(shí)間沒(méi)有執(zhí)行完成,該條Message將被Handler取出并執(zhí)行,就發(fā)生了ANR,并且由系統(tǒng)彈出ANR的彈窗。
  • 5. ANR的分析方法(主要是分析是否有死鎖、通過(guò)調(diào)用棧定位耗時(shí)操作、系統(tǒng)資源情況)

  • 從/data/anr/traces.txt中找到ANR反生的信息:可以從log中搜索“ANR in”或“am_anr”,會(huì)找到ANR發(fā)生的log,該行會(huì)包含了ANR的時(shí)間、進(jìn)程、是何種ANR等信息,如果是BroadcastReceiver的ANR可以懷疑BroadCastReceiver.onReceive()的問(wèn)題,如果的Service或Provider就懷疑是否其onCreate()的問(wèn)題。

  • 在該條log之后會(huì)有CPU usage的信息,表明了CPU在ANR前后的用量(log會(huì)表明截取ANR的時(shí)間),從各種CPU Usage信息中大概可以分析如下幾點(diǎn):

    • 如果某些進(jìn)程的CPU占用百分比較高,幾乎占用了所有CPU資源,而發(fā)生ANR的進(jìn)程CPU占用為0%或非常低,則認(rèn)為CPU資源被占用,進(jìn)程沒(méi)有被分配足夠的資源,從而發(fā)生了ANR。這種情況多數(shù)可以認(rèn)為是系統(tǒng)狀態(tài)的問(wèn)題,并不是由本應(yīng)用造成的。
    • 如果發(fā)生ANR的進(jìn)程CPU占用較高,如到了80%或90%以上,則可以懷疑應(yīng)用內(nèi)一些代碼不合理消耗掉了CPU資源,如出現(xiàn)了死循環(huán)或者后臺(tái)有許多線程執(zhí)行任務(wù)等等原因,這就要結(jié)合trace和ANR前后的log進(jìn)一步分析了。
    • 如果CPU總用量不高,該進(jìn)程和其他進(jìn)程的占用過(guò)高,這有一定概率是由于某些主線程的操作就是耗時(shí)過(guò)長(zhǎng),或者是由于主進(jìn)程被鎖造成的。
  • 除了上述的情況1以外,分析CPU usage之后,確定問(wèn)題需要我們進(jìn)一步分析trace文件。trace文件記錄了發(fā)生ANR前后該進(jìn)程的各個(gè)線程的stack。對(duì)我們分析ANR問(wèn)題最有價(jià)值的就是其中主線程的stack,一般主線程的trace可能有如下幾種情況:

    • 主線程是running或者native而對(duì)應(yīng)的棧對(duì)應(yīng)了我們應(yīng)用中的函數(shù),則很有可能就是執(zhí)行該函數(shù)時(shí)候發(fā)生了超時(shí)。
    • 主線程被block:非常明顯的線程被鎖,這時(shí)候可以看是被哪個(gè)線程鎖了,可以考慮優(yōu)化代碼。如果是死鎖問(wèn)題,就更需要及時(shí)解決了。
    • 由于抓trace的時(shí)刻很有可能耗時(shí)操作已經(jīng)執(zhí)行完了(ANR -> 耗時(shí)操作執(zhí)行完畢 ->系統(tǒng)抓trace)。
  • 6. 如何避免ANR的方法(常見(jiàn)場(chǎng)景)

  • 主線程避免執(zhí)行耗時(shí)操作(文件操作、IO操作、數(shù)據(jù)庫(kù)操作、網(wǎng)絡(luò)訪問(wèn)等):

    Activity、Service(默認(rèn)情況下)的所有生命周期回調(diào)
    BroadcastReceiver的onReceive()回調(diào)方法
    AsyncTask的回調(diào)除了doInBackground,其他都是在主線程中
    沒(méi)有使用子線程Looper的Handler的handlerMessage,post(Runnable)都是執(zhí)行在主線程中

  • 盡量避免主線程的被鎖的情況,在一些同步的操作主線程有可能被鎖,需要等待其他線程釋放相應(yīng)鎖才能繼續(xù)執(zhí)行,這樣會(huì)有一定的死鎖、從而ANR的風(fēng)險(xiǎn)。對(duì)于這種情況有時(shí)也可以用異步線程來(lái)執(zhí)行相應(yīng)的邏輯。

  • 7. 參考文章

    Android ANR問(wèn)題總結(jié)

    內(nèi)存管理

    1. 內(nèi)存管理的兩大核心與目標(biāo)

    內(nèi)存管理的兩大核心
    • 內(nèi)存分配機(jī)制
    • 內(nèi)存回收機(jī)制
    內(nèi)存管理的目標(biāo)
    • 更少的占用內(nèi)存,讓更多的進(jìn)程存活在內(nèi)存當(dāng)中
    • 在合適的時(shí)候,合理的釋放系統(tǒng)資源,保證新的進(jìn)程能夠被創(chuàng)建合分配內(nèi)存(注意這里沒(méi)有說(shuō)是立即釋放,因?yàn)轭l繁的創(chuàng)建釋放會(huì)造成內(nèi)存抖動(dòng))
    • 在系統(tǒng)內(nèi)存緊張的時(shí)候,能釋放掉大部分不重要的資源
    • 能合理的在特殊生命周期中,保存或還原重要數(shù)據(jù)

    2. Android中內(nèi)存管理機(jī)制的特點(diǎn)

    • Android系統(tǒng)是基于Linux 2.6內(nèi)核開(kāi)發(fā)的開(kāi)源操作系統(tǒng),而linux系統(tǒng)的內(nèi)存管理有其獨(dú)特的動(dòng)態(tài)存儲(chǔ)管理機(jī)制。

    • Android系統(tǒng)對(duì)Linux的內(nèi)存管理機(jī)制進(jìn)行了優(yōu)化。

    • Android分配機(jī)制上面的優(yōu)化:

      • Android會(huì)為每個(gè)進(jìn)程分配一個(gè)初始內(nèi)存大小heapstartsiz(初始分配小內(nèi)存,使得系統(tǒng)運(yùn)行更多的進(jìn)程)
      • 當(dāng)應(yīng)用需要大內(nèi)存的時(shí)候,繼續(xù)分配更多的內(nèi)存,最大限制為heapgrowthlimit,否則觸發(fā)OOM
    • Android內(nèi)存回收機(jī)制上面的優(yōu)化:

      • Linux系統(tǒng)會(huì)在進(jìn)程活動(dòng)停止后就結(jié)束該進(jìn)程;Android把這些進(jìn)程都保留在內(nèi)存中,直到系統(tǒng)需要更多內(nèi)存為止。這些保留在內(nèi)存中的進(jìn)程通常情況下不會(huì)影響整體系統(tǒng)的運(yùn)行速度,并且當(dāng)用戶再次激活這些進(jìn)程時(shí),提升了進(jìn)程的啟動(dòng)速度。
      • Android會(huì)根據(jù)進(jìn)程的內(nèi)存占用、進(jìn)程優(yōu)先級(jí)等方面,采用LRU算法進(jìn)行回收

    3. 常見(jiàn)的內(nèi)存問(wèn)題的相關(guān)概念

    • 內(nèi)存溢出:指程序在申請(qǐng)內(nèi)存時(shí),沒(méi)有足夠的空間供其使用
    • 內(nèi)存泄漏:指程序分配出去的內(nèi)存不再使用,無(wú)法進(jìn)行回收
    • 內(nèi)存抖動(dòng):指程序短時(shí)間內(nèi)大量創(chuàng)建對(duì)象,然后回收的現(xiàn)象

    4. 參考文章

    Android內(nèi)存管理機(jī)制

    淺談Android內(nèi)存管理

    內(nèi)存泄漏

    1. 什么是內(nèi)存泄漏

    內(nèi)存泄漏是一個(gè)對(duì)象已經(jīng)不需要再使用了,但是因?yàn)槠渌膶?duì)象持有該對(duì)象的引用,導(dǎo)致它的內(nèi)存不能被垃圾回收器回收。內(nèi)存泄漏的慢慢積累,最終會(huì)導(dǎo)致OOM的發(fā)生。

    2. 內(nèi)存泄漏的主要原因

    長(zhǎng)生命周期的對(duì)象持有短生命周期對(duì)象的引用就很可能發(fā)生內(nèi)存泄漏。(短生命周期的對(duì)象不能被正確回收)

    3. Java內(nèi)存分配策略

    • 靜態(tài)存儲(chǔ)區(qū)(方法區(qū)):主要存儲(chǔ)全局變量和靜態(tài)變量,在整個(gè)程序運(yùn)行期間都存在
    • 棧區(qū):方法體的局部變量會(huì)在棧區(qū)創(chuàng)建空間,并在方法執(zhí)行結(jié)束后會(huì)自動(dòng)釋放變量的空間和內(nèi)存
    • 堆區(qū):保存動(dòng)態(tài)產(chǎn)生的數(shù)據(jù),如:new出來(lái)的對(duì)象和數(shù)組,在不使用的時(shí)候由Java回收器自動(dòng)回收

    4. 常見(jiàn)的內(nèi)存泄漏及其解決方案

    • 單例造成的內(nèi)存泄漏:在單例中,使用context.getApplicationContext()作為單例的context
    • 匿名內(nèi)部類造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類持有匿名外部類的引用,必須將內(nèi)部類設(shè)置為static、或者使用弱引用
    • Handler造成的內(nèi)存泄漏:使用static的Handler內(nèi)部類,同時(shí)在實(shí)現(xiàn)內(nèi)部類中持有Context的弱引用
    • 避免使用static變量:由于static變量會(huì)跟Activity生命周期一致,當(dāng)Activity退出后臺(tái)被后臺(tái)回收時(shí),static變量是不安全,所以也要管理好static變量的生命周期
    • 資源未關(guān)閉造成的內(nèi)存泄漏:比如Socket、Broadcast、Cursor、Bitmap、ListView、集合容器等,使用完后要關(guān)閉
    • AsyncTask造成的內(nèi)存泄漏:由于非靜態(tài)內(nèi)部類持有匿名內(nèi)部類的引用而造成內(nèi)存泄漏,可以通過(guò)AsyncTask內(nèi)部持有外部Activity的弱引用同時(shí)改為靜態(tài)內(nèi)部類或在onDestroy()中執(zhí)行AsyncTask.cancel()進(jìn)行修復(fù)
    • WebView造成的內(nèi)存泄漏:頁(yè)面銷毀的時(shí)候WebView需要正確移除并且調(diào)用其destroy方法

    5. LeakCanary檢測(cè)內(nèi)存泄漏核心原理

  • 給可被回收的對(duì)象上打了智能標(biāo)記(弱引用,Key-Value的形式)。
  • 監(jiān)聽(tīng)Activity的生命周期。
  • 如果Activity銷毀之后過(guò)一小段時(shí)間對(duì)象依然沒(méi)有被釋放,就會(huì)給內(nèi)存做個(gè)快照(Dump Memory),并且導(dǎo)出到本地文件。
  • 通過(guò)讀取、分析這個(gè)heap dump文件:根據(jù)Key用SQL語(yǔ)句去查詢數(shù)據(jù)庫(kù),并且計(jì)算出最短的GC root路徑,從而找出阻止該對(duì)象釋放的那個(gè)對(duì)象。
  • 通過(guò)UI(Debug版本是Notification)的形式把分析結(jié)果報(bào)告給開(kāi)發(fā)者。
  • 6. 參考文章

    常見(jiàn)的內(nèi)存泄漏原因及解決方法

    用 LeakCanary 檢測(cè)內(nèi)存泄漏

    InputMethodManager.mLastSrvView memory leak in Android6.0 with huawei mobile phone #572

    內(nèi)存溢出

    1. 內(nèi)存溢出是什么?

    OOM指Out of memory(內(nèi)存溢出),當(dāng)前占用內(nèi)存 + 我們申請(qǐng)的內(nèi)存資源 超過(guò)了虛擬機(jī)的最大內(nèi)存限制就會(huì)拋出Out of memory異常。

    2. 應(yīng)用的內(nèi)存限制與申請(qǐng)大內(nèi)存

    • Android虛擬機(jī)對(duì)單個(gè)應(yīng)用的最大內(nèi)存分配值定義在/system/build.prop文件中

      //堆分配的初始大小,它會(huì)影響到整個(gè)系統(tǒng)對(duì)RAM的使用程度,和第一次使用應(yīng)用時(shí)的流暢程度。它值越小,系統(tǒng)ram消耗越慢,但一些較大應(yīng)用一開(kāi)始不夠用,需要調(diào)用gc和堆調(diào)整策略,導(dǎo)致應(yīng)用反應(yīng)較慢。它值越大,這個(gè)值越大系統(tǒng)ram消耗越快,但是應(yīng)用更流暢。 dalvik.vm.heapstartsize=xxxm //單個(gè)應(yīng)用可用最大內(nèi)存。最大內(nèi)存限制主要針對(duì)的是這個(gè)值,它表示單個(gè)進(jìn)程內(nèi)存被限定在xxxm,即程序運(yùn)行過(guò)程中實(shí)際只能使用xxxm內(nèi)存,超出就會(huì)報(bào)OOM。(僅僅針對(duì)dalvik堆,不包括native堆) dalvik.vm.heapgrowthlimit=xxxm //單個(gè)進(jìn)程可用的最大內(nèi)存,但如果存在heapgrowthlimit參數(shù),則以heapgrowthlimit為準(zhǔn)。heapsize表示不受控情況下的極限堆,表示單個(gè)虛擬機(jī)或單個(gè)進(jìn)程可用的最大內(nèi)存。 dalvik.vm.heapsize=xxxm ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); int memoryClass = am.getMemoryClass();
    • 每開(kāi)一個(gè)應(yīng)用就會(huì)打開(kāi)一個(gè)獨(dú)立的虛擬機(jī)(這樣設(shè)計(jì)就會(huì)在單個(gè)程序崩潰的情況下不會(huì)導(dǎo)致整個(gè)系統(tǒng)的崩潰)

    • 在android開(kāi)發(fā)中,如果要使用大堆,需要在manifest中指定android:largeHeap為true,這樣dvm heap最大可達(dá)heapsize。盡量少使用large heap。使用額外的內(nèi)存會(huì)影響系統(tǒng)整體的用戶體驗(yàn),并且會(huì)使得GC的每次運(yùn)行時(shí)間更長(zhǎng)。在任務(wù)切換時(shí),系統(tǒng)的性能會(huì)變得大打折扣。

    3. 內(nèi)存優(yōu)化-常見(jiàn)內(nèi)存溢出及其解決方案

    • 解決應(yīng)用中的內(nèi)存泄漏問(wèn)題。
    • 圖片:正確縮放、壓縮、解碼、回收。
    • 在UI不可見(jiàn)的時(shí)候,適當(dāng)釋放其UI資源。
    • 列表控件:重用convertView、使用LRU緩存算法、滾動(dòng)的時(shí)候進(jìn)行監(jiān)聽(tīng),此時(shí)不應(yīng)該加載圖片。
    • View:避免在onDraw方法中創(chuàng)建對(duì)象。
    • 謹(jǐn)慎使用多進(jìn)程:使用多進(jìn)程可以把應(yīng)用中的部分組件運(yùn)行在單獨(dú)的進(jìn)程當(dāng)中,這樣可以擴(kuò)大應(yīng)用的內(nèi)存占用范圍,但是這個(gè)技術(shù)必須謹(jǐn)慎使用,使用多進(jìn)程會(huì)使得代碼邏輯更加復(fù)雜,使用不當(dāng)可能反而會(huì)導(dǎo)致顯著增加內(nèi)存。當(dāng)應(yīng)用需要運(yùn)行一個(gè)常駐后臺(tái)的任務(wù),而且這個(gè)任務(wù)并不輕量,可以考慮使用這個(gè)技術(shù)。
    • 使用更加輕量的數(shù)據(jù)結(jié)構(gòu)。例如,我們可以考慮使用ArrayMap/SparseArray而不是HashMap等傳統(tǒng)數(shù)據(jù)結(jié)構(gòu)。
    • 避免在Android里面使用Enum,而用靜態(tài)常量代替。(因?yàn)槊杜e的內(nèi)存消耗是靜態(tài)常量的兩倍左右)
    • 字符串拼接:在有些時(shí)候,代碼中會(huì)需要使用到大量的字符串拼接的操作,這種時(shí)候有必要考慮使用StringBuilder來(lái)替代頻繁的“+”。
    • Try catch某些大內(nèi)存分配的操作。
    • 資源文件需要選擇合適的文件夾進(jìn)行存放。hdpi/xhdpi/xxhdpi等等不同dpi的文件夾下的圖片在不同的設(shè)備上會(huì)經(jīng)過(guò)scale的處理,拉伸之后內(nèi)存消耗更大。對(duì)于不希望被拉伸的圖片,需要放到assets或者nodpi的目錄下。
    • 在onLowMemory()與onTrimMemory()中適當(dāng)釋放內(nèi)存。
    • 珍惜Services資源。如果你的應(yīng)用需要在后臺(tái)使用service,除非它被觸發(fā)并執(zhí)行一個(gè)任務(wù),否則其他時(shí)候Service都應(yīng)該是停止?fàn)顟B(tài)。另外需要注意當(dāng)這個(gè)service完成任務(wù)之后因?yàn)橥V箂ervice失敗而引起的內(nèi)存泄漏。建議使用IntentService。
    • 優(yōu)化布局層次,減少內(nèi)存消耗。越扁平化的視圖布局,占用的內(nèi)存就越少,效率越高。
    • 謹(jǐn)慎使用依賴注入框架:使用之后,代碼是簡(jiǎn)化了不少。然而,那些注入框架會(huì)通過(guò)掃描你的代碼執(zhí)行許多初始化的操作,這會(huì)導(dǎo)致你的代碼需要大量的內(nèi)存空間來(lái)mapping代碼,而且mapped pages會(huì)長(zhǎng)時(shí)間的被保留在內(nèi)存中。
    • 使用ProGuard來(lái)剔除不需要的代碼,通過(guò)移除不需要的代碼,重命名類,域與方法等等對(duì)代碼進(jìn)行壓縮,優(yōu)化與混淆。使得代碼更加緊湊,能夠減少mapping代碼所需要的內(nèi)存空間。
    • 謹(jǐn)慎使用第三方libraries。很多開(kāi)源的library代碼都不是為移動(dòng)網(wǎng)絡(luò)環(huán)境而編寫的,如果運(yùn)用在移動(dòng)設(shè)備上,并不一定適合。即使是針對(duì)Android而設(shè)計(jì)的library,也需要特別謹(jǐn)慎,特別是如果你知道引入的library具體做了什么事情的時(shí)候。
    • 考慮不同的實(shí)現(xiàn)方式、方案、策略來(lái)優(yōu)化內(nèi)存占用。

    4. 參考文章

    Android 性能優(yōu)化(內(nèi)存之OOM)

    Android 查看每個(gè)應(yīng)用的最大可用內(nèi)存

    Lint與代碼優(yōu)化工具

    1. 什么是Lint?

    Android Lint是一個(gè)靜態(tài)代碼分析工具,能夠?qū)z測(cè)代碼質(zhì)量——對(duì)項(xiàng)目中潛在的Bug、可優(yōu)化的代碼、安全性、性能、可用性、可訪問(wèn)性、國(guó)際化等進(jìn)行檢查(注:Lint檢測(cè)不局限于代碼,功能十分強(qiáng)大)。

    通過(guò)下面的gradle命令開(kāi)啟Lint:

    ./gradlew lint

    2. Lint的工作流程

    • App項(xiàng)目源文件:包括Java代碼,XML代碼,圖標(biāo),以及ProGuard配置文件、Git忽略文件等

    • lint.xml:Lint 檢測(cè)的執(zhí)行標(biāo)準(zhǔn)配置文件,我們可以修改它來(lái)允許或者禁止報(bào)告一些問(wèn)題

    • Lint工具按照標(biāo)準(zhǔn)配置文件中指定的規(guī)則去檢測(cè)App項(xiàng)目源文件,發(fā)現(xiàn)問(wèn)題,并且進(jìn)行報(bào)告。常見(jiàn)的問(wèn)題有:

      • Correctness:不夠完美的編碼,比如硬編碼、使用過(guò)時(shí)API等
      • Performance:對(duì)性能有影響的編碼,比如:靜態(tài)引用,循環(huán)引用等
      • Internationalization:國(guó)際化,直接使用漢字,沒(méi)有使用資源引用等,適配國(guó)際化的時(shí)候資源漏翻譯
      • Security:不安全的編碼,比如在WebView中允許使用JavaScriptInterface等

    3. 忽略Lint警告

    • Java代碼中忽略Lint警告:使用注解。注解跟@SuppressWarnings很類似,@SuppressLint(“忽略的警告名稱”),如果不清楚警告名稱,直接寫all表示忽略所有警告
    • XML代碼中忽略Lint警告:使用 tools:ignore=”忽略的警告名”

    4. Debug構(gòu)建中關(guān)閉Lint檢測(cè)

    執(zhí)行Gradle命令的時(shí)候,通過(guò)-x參數(shù)不執(zhí)行某個(gè)action

    ./gradlew build -x lint

    5. 自定義Lint

    • 創(chuàng)建lint.xml到根目錄下,可以自定義Lint安全等級(jí)、忽略文件等

    • 自定義Lint檢查規(guī)則(比如日志不通過(guò)LogUtils打印則警告):

    • 依賴Android官方的lint的庫(kù)
    • 創(chuàng)建類繼承Detector,實(shí)現(xiàn)一些規(guī)則
    • 并且提供IssueRegistry向外提供Detector注冊(cè)匯總信息
    • 輸出jar包或者aar包,主項(xiàng)目進(jìn)行依賴
    • 進(jìn)行l(wèi)int檢測(cè)即可

    6. 一些其他的代碼優(yōu)化工具

    • KW(Klockwork)掃描工具(這個(gè)工具需要授權(quán)才能使用,屬于動(dòng)態(tài)檢測(cè),依賴項(xiàng)目編譯生成的文件。目前還是存在一些BUG,比如空指針的檢測(cè)、IO流的關(guān)閉檢測(cè)等)
    • 阿里巴巴的編碼規(guī)約掃描工具(IDEA的一個(gè)插件)
    • Uber的NullAway空指針掃描工具(空指針的檢測(cè)工具,接入比較麻煩)
    • ……

    7. 參考文章

    Android 性能優(yōu)化:使用 Lint 優(yōu)化代碼、去除多余資源

    Android工具:被你忽視的Lint

    自動(dòng)規(guī)避代碼陷阱——自定義Lint規(guī)則

    Android Lint

    美團(tuán)點(diǎn)評(píng)技術(shù)團(tuán)隊(duì)-Android自定義Lint實(shí)踐2——改進(jìn)原生Detector

    美團(tuán)自定義Lint示例

    Writing a Lint Check

    Idea 阿里代碼規(guī)約插件安裝

    使用Klockwork進(jìn)行代碼分析簡(jiǎn)單操作流程

    NullAway:Uber用于檢測(cè)Android上的NullPointerExceptions的開(kāi)源工具

    UI卡頓優(yōu)化

    1. UI卡頓原理

    View的繪制幀數(shù)保持60fps是最佳,這要求每幀的繪制時(shí)間不超過(guò)16ms(1000/60),如果安卓不能在16ms內(nèi)完成界面的渲染,那么就會(huì)出現(xiàn)卡頓現(xiàn)象。而UI的繪制在主線程中進(jìn)行的,因此UI卡頓本質(zhì)上就是主線程卡頓。

    2. UI卡頓常見(jiàn)原因及其解決方案

    • 布局Layout過(guò)于復(fù)雜,無(wú)法在16ms內(nèi)完成渲染。

    • 過(guò)度繪制overDraw,導(dǎo)致像素在同一幀的時(shí)間內(nèi)被繪制多次,使CPU和GPU負(fù)載過(guò)重。

    • View頻繁的觸發(fā)measure、layout,導(dǎo)致measure、layout累計(jì)耗時(shí)過(guò)多和整個(gè)View頻繁的重新渲染。

      布局優(yōu)化

      • 通過(guò)開(kāi)發(fā)者工具檢查過(guò)度繪制
      • 使用include復(fù)用布局、使用ViewStub延遲加載布局、使用merge減少代碼層級(jí)、使用RelativeLayout也能大大減少視圖的層級(jí)、慎重設(shè)置整體背景顏色防止過(guò)度繪制
      • 使用自定義View取代復(fù)雜的View
    • 使用TraceView工具檢測(cè)UI卡頓、方法耗時(shí)

    • 在UI線程中做輕微的耗時(shí)操作,導(dǎo)致UI線程卡頓:應(yīng)該把耗時(shí)操作放在子線程中進(jìn)行。

    • 同一時(shí)間動(dòng)畫(huà)執(zhí)行的次數(shù)過(guò)多,導(dǎo)致CPU和GPU負(fù)載過(guò)重。

    • 頻繁的觸發(fā)GC操作導(dǎo)致線程暫停、內(nèi)存抖動(dòng),會(huì)使得安卓系統(tǒng)在16ms內(nèi)無(wú)法完成繪制:可以考慮使用享元模式、避免在onDraw方法中創(chuàng)建對(duì)象等。

    • 冗余資源及邏輯等導(dǎo)致加載和執(zhí)行緩慢。

    • UI卡頓最嚴(yán)重的后果是ANR,因此需要在開(kāi)發(fā)中避免和解決ANR問(wèn)題。

    • 列表控件滑動(dòng)卡頓:復(fù)用convertView、滑動(dòng)不進(jìn)行加載、使用壓縮圖片、加載縮略圖等。

    3. BlockCanary及其原理

    BlockCanary會(huì)在發(fā)生卡頓的時(shí)候記錄各種信息,輸出到配置目錄下的文件,并彈出消息欄通知,輕松找出Android App界面卡頓元兇。

    BlockCanary的核心原理是:通過(guò)Android的消息機(jī)制在mainLooperPrinter中判斷start和end,來(lái)獲取主線程dispatch該message的開(kāi)始和結(jié)束時(shí)間,并判定該時(shí)間超過(guò)閾值(如2000毫秒)為主線程卡慢發(fā)生,并dump出各種信息,提供開(kāi)發(fā)者分析性能瓶頸。

    核心代碼如下:

    Looper.getMainLooper().setMessageLogging(mainLooperPrinter);@Override public void println(String x) {if (!mStartedPrinting) {mStartTimeMillis = System.currentTimeMillis();mStartThreadTimeMillis = SystemClock.currentThreadTimeMillis();mStartedPrinting = true;} else {final long endTime = System.currentTimeMillis();mStartedPrinting = false;if (isBlock(endTime)) {notifyBlockEvent(endTime);}} }private boolean isBlock(long endTime) {return endTime - mStartTimeMillis > mBlockThresholdMillis; }

    4. 參考文章

    BlockCanary — 輕松找出Android App界面卡頓元兇

    冷啟動(dòng)與熱啟動(dòng)

    1. 冷啟動(dòng)與熱啟動(dòng)是什么?

    • 冷啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)沒(méi)有該應(yīng)用的進(jìn)程,這時(shí)系統(tǒng)會(huì)重新創(chuàng)建一個(gè)新的進(jìn)程分配給該應(yīng)用,這個(gè)啟動(dòng)方式就是冷啟動(dòng)。

      冷啟動(dòng)大致流程:實(shí)例化Application -> 實(shí)例化入口Activity -> 顯示Activity(配置主題中背景等屬性 -> 顯示測(cè)量布局繪制最終顯示在界面上)

    • 熱啟動(dòng):當(dāng)啟動(dòng)應(yīng)用時(shí),后臺(tái)已有該應(yīng)用的進(jìn)程,所以在已有進(jìn)程的情況下,這種啟動(dòng)會(huì)從已有的進(jìn)程中來(lái)啟動(dòng)應(yīng)用,這個(gè)方式叫熱啟動(dòng)。(例:按back鍵、home鍵,應(yīng)用雖然會(huì)退出,但是該應(yīng)用的進(jìn)程是依然會(huì)保留在后臺(tái),可進(jìn)入任務(wù)列表查看)

      熱啟動(dòng)大致流程(不需要實(shí)例化Application):實(shí)例化入口Activity -> 顯示Activity

    2. 應(yīng)用啟動(dòng)時(shí)間測(cè)量

    • 使用命令

      adb shell am start -W [packageName]/[packageName.XXXActivity]
    • 使用Activity.reportFullyDrawn在Logcat中打印出來(lái),例子:

      ActivityManager: Displayed com.android.myexample/.StartupTiming: +3s534ms
    • 使用TraceView精確測(cè)量(TraceView工具可以檢測(cè)UI卡頓、方法耗時(shí))

      // start tracing to "/sdcard/calc.trace" Debug.startMethodTracing("calc"); // ... // stop tracing Debug.stopMethodTracing();
    • 使用高速攝像機(jī)進(jìn)行抓幀

    3. 冷啟動(dòng)優(yōu)化常見(jiàn)方案

    • 通過(guò)懶加載方式初始化第三方SDK,可以嘗試在閃屏Activity中加載
    • 不要在mainThread中加載資源
    • 減少第一個(gè)界面onCreate()方法的工作量
    • 不要讓Application參與業(yè)務(wù)的操作、耗時(shí)操作
    • 不要以靜態(tài)變量的方式在Application中保存數(shù)據(jù)
    • 減少布局的復(fù)雜性和深度

    4. 解決冷啟動(dòng)白/黑屏問(wèn)題的兩種方案

    • 設(shè)置要啟動(dòng)的Activity主題為透明,可以給用戶造成一個(gè)視覺(jué)上的假象,例如:

      <style name="AppTransparentTheme" parent="Theme.AppCompat.Light.NoActionBar.Fullscreen"><item name="android:windowIsTranslucent">true</item><item name="android:windowBackground">@android:color/transparent</item> </style>
    • 為要啟動(dòng)的Activity設(shè)置主題為一張背景圖,例如:

      <style name="AppBackgroundTheme" parent="Theme.AppCompat.Light.NoActionBar.Fullscreen"><item name="android:windowBackground">@mipmap/bg_welcome</item> </style>

    5. 參考文章

    Android Study 之冷啟動(dòng)優(yōu)化(解決啟動(dòng)短暫白屏or黑屏)

    Android冷啟動(dòng)實(shí)現(xiàn)APP秒開(kāi)

    Android 性能優(yōu)化 冷啟動(dòng)速度優(yōu)化

    APK瘦身

    1. APK文件的組成

    直接在Android Studio中打開(kāi)APK文件,通過(guò)APK分析器,可以看到APK文件的組成成分與比例(實(shí)際上是調(diào)用AAPT工具的功能):

    • asserts:存放一些配置文件或資源文件,比如WebView的本地html,React Native的jsbundle等
    • lib:lib目錄下會(huì)有各種so文件,分析器會(huì)檢查出項(xiàng)目自己的so和各種庫(kù)的so。
    • resources.arsc:編譯后的二進(jìn)制資源文件,里面是id-name-value的一個(gè)Map。
    • res:res目錄存放的是資源文件。包括圖片、字符串。raw文件夾下面是音頻文件,各種xml文件等等。
    • dex:dex文件是Java代碼打包后的字節(jié)碼,一個(gè)dex文件最多只支持65536個(gè)方法,開(kāi)啟了dex分包的話會(huì)有多個(gè)。
    • META-INF:META-INF目錄下存放的是簽名信息,分別是MANIFEST.MF、CERT.SF、CERT.RSA。用來(lái)保證apk包的完整性和系統(tǒng)的安全性,幫助用戶避免安裝來(lái)歷不明的盜版APK。
    • AndroidManifest.xml:Android清單文件。

    2. 常見(jiàn)APK瘦身方案

    • 優(yōu)化assets

      • 資源動(dòng)態(tài)下載,字體、js代碼這樣的資源能動(dòng)態(tài)下載的就做動(dòng)態(tài)下載,雖然復(fù)雜度提高,但是實(shí)現(xiàn)了動(dòng)態(tài)更新
      • 壓縮資源文件,用到的時(shí)候再進(jìn)行解壓
      • 刪除不必要的字體文件中的字體
      • 減少圖標(biāo)字體(Icon-Font)的使用,多用SVG代替
    • 優(yōu)化lib

      • 配置abiFilters精簡(jiǎn)so動(dòng)態(tài)庫(kù),而已根據(jù)需求保留需要的平臺(tái)

        defaultConfig {//armeabi是必須包含的,v7是一個(gè)圖形加強(qiáng)版本,x86是英特爾平臺(tái)的支持庫(kù)ndk {abiFilters "armeabi", "armeabi-v7a" ,"x86"} }
      • 統(tǒng)計(jì)分析用戶手機(jī)的cpu類型,排除沒(méi)有或少量用戶才會(huì)用到的so

    • 優(yōu)化resources.arsc

      • 刪除不必要的string entry,你可以借助android-arscblamer來(lái)檢查出可以優(yōu)化的部分,比如一些空的引用
      • 使用微信的資源混淆工具AndResGuard,它將資源的名稱進(jìn)行了混淆(需要重點(diǎn)配置白名單)
    • 優(yōu)化META-INF:除了公鑰CERT.RSA沒(méi)有壓縮機(jī)會(huì)外,其余的兩個(gè)文件都可以通過(guò)混淆資源名稱的方式進(jìn)行壓縮

    • 優(yōu)化res

      • 動(dòng)態(tài)下載資源

      • 通過(guò)Android Studio的重構(gòu)工具刪除無(wú)用資源

      • 打包時(shí)剔除無(wú)用資源

        release {zipAlignEnabled trueminifyEnabled true shrinkResources true // 是否去除無(wú)效的資源文件 proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'signingConfig signingConfigs.release}
      • 刪除無(wú)用的語(yǔ)言(排除了所有的依賴庫(kù)的資源)

        android {//...defaultConfig {resConfigs "zh"} }
      • 控制圖片、視頻、音頻資源的大小,推薦使用有損壓縮等其他格式(ogg、svg、webp等)

      • 統(tǒng)一應(yīng)用風(fēng)格,減少shape文件

      • 使用toolbar,減少menu文件

      • 通過(guò)復(fù)用等方式減少layout文件

    • 優(yōu)化dex:

      • 利用工具(dexcount、statistic、apk-method-count、Lint)分析、精簡(jiǎn)不必要的方法、空行、依賴庫(kù)等
      • 通過(guò)proguard來(lái)刪除無(wú)用代碼
      • 剔除無(wú)用的測(cè)試代碼
      • 依賴第三方庫(kù)的時(shí)候,在打包發(fā)版中不要將某些不必要的庫(kù)進(jìn)行releaseCompile(比如LeakCanary)
      • 使用更小庫(kù)或合并現(xiàn)有庫(kù)
      • 減少方法數(shù)、使用插件化等方案,不用mulitdex

    3. 參考文章

    App瘦身最佳實(shí)踐

    Android中5種app瘦身方式

    進(jìn)程及進(jìn)程?;?、跨進(jìn)程通信

    1. 查看進(jìn)程信息

    使用ps命令可以查看進(jìn)程信息:

    adb shell ps|grep <package_name>

    返回的結(jié)果分別為:

    • 進(jìn)程當(dāng)前用戶
    • 進(jìn)程ID
    • 進(jìn)程的父進(jìn)程ID
    • 進(jìn)程的虛擬內(nèi)存大小
    • 實(shí)際駐留”在內(nèi)存中”的內(nèi)存大小
    • 進(jìn)程名

    2. Android進(jìn)程優(yōu)先級(jí)

    • 前臺(tái)進(jìn)程:Foreground process(用戶正在使用的程序,一般系統(tǒng)是不會(huì)殺死前臺(tái)進(jìn)程的,除非用戶強(qiáng)制停止應(yīng)用或者系統(tǒng)內(nèi)存不足等極端情況會(huì)殺死。)

      • 用戶正在交互的Activity(已調(diào)用onResume)
      • 當(dāng)某個(gè)Service綁定正在交互的Activity
      • 被主動(dòng)調(diào)用為前臺(tái)Service(startForeground())
      • 組件正在執(zhí)行生命周期的回調(diào)(onCreate()、onStart()、onDestory())
      • BroadcastReceiver正在執(zhí)行onReceive()
    • 可見(jiàn)進(jìn)程:Visible process(用戶正在使用,看得到,但是摸不著,沒(méi)有覆蓋到整個(gè)屏幕,只有屏幕的一部分可見(jiàn)進(jìn)程不包含任何前臺(tái)組件,一般系統(tǒng)也是不會(huì)殺死可見(jiàn)進(jìn)程的,除非要在資源吃緊的情況下,要保持某個(gè)或多個(gè)前臺(tái)進(jìn)程存活)

      • Activity不在前臺(tái)、但仍對(duì)用戶可見(jiàn)(已調(diào)用onPause(),沒(méi)有調(diào)用onStop()))
      • 綁定到可見(jiàn)(前臺(tái))Activity的Service
    • 服務(wù)進(jìn)程:Service process(在內(nèi)存不足以維持所有前臺(tái)進(jìn)程和可見(jiàn)進(jìn)程同時(shí)運(yùn)行的情況下,服務(wù)進(jìn)程會(huì)被殺死)

      • 簡(jiǎn)單的startService()啟動(dòng),與用戶看見(jiàn)的Activity沒(méi)有直接關(guān)聯(lián)。
    • 后臺(tái)進(jìn)程:Background process(系統(tǒng)可能隨時(shí)終止它們,回收內(nèi)存)

      • 在用戶按了"back"或者"home"后,程序本身看不到了,但是其實(shí)還在運(yùn)行的程序。對(duì)用戶沒(méi)有直接影響,Activity處于onStop()的時(shí)候。
      • 應(yīng)用開(kāi)啟的進(jìn)程:android:process=":xxx"
    • 空進(jìn)程:Empty process(某個(gè)進(jìn)程不包含任何活躍的組件時(shí)該進(jìn)程就會(huì)被置為空進(jìn)程,完全沒(méi)用,優(yōu)先級(jí)最低,殺了它只有好處沒(méi)壞處,第一被回收)

      • 不含有任何的活動(dòng)的組件。(Android設(shè)計(jì)的,處于緩存的目的,為了第二次啟動(dòng)更快,采取的一個(gè)權(quán)衡)

    3. 進(jìn)程回收策略(Low memory Killer)

    Low memory Killer:定時(shí)執(zhí)行,一旦發(fā)現(xiàn)內(nèi)存低于某個(gè)內(nèi)存閾值,Low memory Killer會(huì)根據(jù)進(jìn)程的優(yōu)先級(jí)、進(jìn)程占用的內(nèi)存大小等因素通過(guò)復(fù)雜的評(píng)分機(jī)制,對(duì)進(jìn)程進(jìn)行打分,然后將分?jǐn)?shù)高的進(jìn)程判定為bad進(jìn)程,殺死并釋放內(nèi)存

    4. 進(jìn)程?;罘桨?/h4>
    • 與手機(jī)廠商合作,加入白名單
    • 監(jiān)聽(tīng)鎖屏廣播,在RemoteService中開(kāi)啟/關(guān)閉一個(gè)像素的Activity
    • 利用Android5.0以下系統(tǒng)同一時(shí)間只能殺死一個(gè)進(jìn)程的漏洞(5.0之后同一個(gè)Group的進(jìn)程都會(huì)被殺死),開(kāi)啟雙進(jìn)程守護(hù)
    • 利用前臺(tái)服務(wù),startForeground(ID, new Notification()),發(fā)送空的通知
    • 利用系統(tǒng)黏性服務(wù)機(jī)制拉活
    • 利用開(kāi)機(jī),網(wǎng)絡(luò)切換、拍照、拍視頻等系統(tǒng)廣播也能喚醒,不過(guò)Android N已經(jīng)將這三種廣播取消了
    • 利用Native進(jìn)程監(jiān)聽(tīng)進(jìn)程是否存活,否則拉活
    • 利用JobScheduler機(jī)制代替Native進(jìn)程實(shí)現(xiàn)拉活
    • 利用賬號(hào)同步機(jī)制拉活。用戶強(qiáng)制停止都?xì)⒉黄饎?chuàng)建一個(gè)賬號(hào)并設(shè)置同步器,創(chuàng)建周期同步,系統(tǒng)會(huì)自動(dòng)調(diào)用同步器,這樣就能激活A(yù)PP,局限是國(guó)產(chǎn)機(jī)會(huì)修改最短同步周期,并且需要聯(lián)網(wǎng)才能使用。

    5. 跨進(jìn)程通信方式

    6. 參考文章

    Android進(jìn)程?;畹囊话闾茁?/p>

    關(guān)于進(jìn)程?;畹膬扇隆率稚?jí)經(jīng)驗(yàn)卡

    Android里帳戶同步的實(shí)現(xiàn)

    Bitmap

    1. Bitmap的理解

    Bitmap是Android系統(tǒng)中的圖像處理的最重要類之一。用它可以獲取圖像文件信息,進(jìn)行圖像剪切、旋轉(zhuǎn)、縮放等操作,并可以指定格式保存圖像文件。

    2. Bitmap的內(nèi)存分配策略

    在Androin3.0之前的版本,Bitmap像素?cái)?shù)據(jù)存放在Native內(nèi)存中,而且Nativie內(nèi)存的釋放是不確定的,容易內(nèi)存溢出而Crash,不使用的圖片要調(diào)用recycle()進(jìn)行回收。

    從Androin3.0開(kāi)始,Bitmap像素?cái)?shù)據(jù)和Bitmap對(duì)象一起存放在虛擬機(jī)的堆內(nèi)存中(從源代碼上看是多了一個(gè)byte[] buffer用來(lái)存放數(shù)據(jù)),也就是我們常說(shuō)的Java Heap內(nèi)存。

    從Androin8.0開(kāi)始,Bitmap像素?cái)?shù)據(jù)存重新回到Native內(nèi)存中

    3. Bitmap的內(nèi)存占用計(jì)算

    Bitmap的內(nèi)存占用大小的計(jì)算:

    • 一般情況下的計(jì)算

      Bitmap占用的內(nèi)存 = width * height * 一個(gè)像素所占的內(nèi)存

    • 在Android中,考慮各種因素情況下的計(jì)算

      Bitmap占用的內(nèi)存 = width * height * nTargetDensity/inDensity * nTargetDensity/inDensity * 一個(gè)像素所占的內(nèi)存

    Bitmap的內(nèi)存占用大小與三個(gè)因素有關(guān):

    • 色彩格式,前面我們已經(jīng)提到,如果是ARGB_8888那么就是一個(gè)像素4個(gè)字節(jié),如果是RGB_565那就是2個(gè)字節(jié)
    • 原始文件存放的資源目錄(分辨率越小,內(nèi)存占用越小)
    • 目標(biāo)屏幕的密度(屏幕的密度越小,內(nèi)存占用越小)

    有關(guān)Bitmap的色彩格式:

    • ARGB_8888的內(nèi)存消耗是RGB_565的2倍
    • ARGB_8888格式比RGB_565多了一個(gè)透明通道
    • 如果使用RGB_565格式解析ARGB_8888格式的圖片(png),可能會(huì)導(dǎo)致圖片變綠

    4. Bitmap的回收

    • 在Android3.0以前以及Android8.0之后Bitmap的像素?cái)?shù)據(jù)是存放Native內(nèi)存中,我們需要回收Native層和Java層的內(nèi)存。
    • 在Android3.0以后以及Android8.0之前Bitmap的像素?cái)?shù)據(jù)是存放在Java層的內(nèi)存中的,我們只要回收堆內(nèi)存即可。
    • 官方建議我們3.0以后使用recycle方法進(jìn)行回收,該方法也可以不主動(dòng)調(diào)用,因?yàn)槔厥掌鲿?huì)自動(dòng)收集不可用的Bitmap對(duì)象進(jìn)行回收。
    • recycle方法會(huì)判斷Bitmap在不可用的情況下,將發(fā)送指令到垃圾回收器,讓其回收native層和Java層的內(nèi)存,則Bitmap進(jìn)入dead狀態(tài)。
    • recycle方法是不可逆的,如果再次調(diào)用getPixels()等方法,則獲取不到想要的結(jié)果。

    5. Bitmap的復(fù)用

    Android在3.0之后BitmapFactory.Options引入了inBitmap屬性,設(shè)置該屬性之后解碼圖片時(shí)會(huì)嘗試復(fù)用一張已經(jīng)存在的Bitmap,避免了內(nèi)存的回收以及重新申請(qǐng)的過(guò)程。

    Bitmap復(fù)用的限制:

    • 聲明可被復(fù)用的Bitmap必須設(shè)置inMutable為true
    • Android4.4(API 19)之前只有格式為jpg、png,同等寬高(要求苛刻),inSampleSize為1的Bitmap才可以復(fù)用
    • Android4.4(API 19)之前被復(fù)用的Bitmap的inPreferredConfig會(huì)覆蓋待分配內(nèi)存的Bitmap設(shè)置的inPreferredConfig
    • Android4.4(API 19)之前待加載Bitmap的Options.inSampleSize必須明確指定為1
    • Android4.4(API 19)之后被復(fù)用的Bitmap的內(nèi)存必須大于需要申請(qǐng)內(nèi)存的Bitmap的內(nèi)存

    6. Bitmap加載大圖與防止OOM

    加載大圖的時(shí)候注意點(diǎn):

    • 在Android系統(tǒng)中,讀取位圖Bitmap時(shí),分給虛擬機(jī)中的圖片的堆棧大小只有8M,如果超出了,就會(huì)出現(xiàn)OutOfMemory異常
    • 在加載大圖、長(zhǎng)圖等操作當(dāng)中,推薦對(duì)OutOfMemoryError進(jìn)行捕獲,并且返回一張默認(rèn)圖片
    • 使用采樣率(inSampleSize),如果需要顯示縮列圖,并不需要加載完整的圖片數(shù)據(jù),只需要按一定的比例加載即可
    • 使用Matrix變形等,比如使用Matrix進(jìn)行放大,雖然圖像大了,但并沒(méi)有占用更多的內(nèi)存
    • 推薦使用一些成熟的開(kāi)源圖片加載庫(kù),它們幫我們完成了很多工作。比如異步加載、Facebook的Fresco還自己開(kāi)辟了Native內(nèi)存用于存儲(chǔ)圖片,以得到更大的內(nèi)存空間(兼容性問(wèn)題)
    • 使用分塊解碼(BitmapRegionDecoder)、硬解碼等方案

    獲取圖片縮略圖的模板代碼如下(主要分為3個(gè)步驟):

    public static Bitmap thumbnail(String path, int width, int height, boolean autoRotate) {//1. 獲得Bitmap的寬高,但是不加載到內(nèi)存BitmapFactory.Options options = new BitmapFactory.Options();options.inJustDecodeBounds = true;BitmapFactory.decodeFile(path, options);int srcWidth = options.outWidth;int srcHeight = options.outHeight;//2. 計(jì)算圖片縮放倍數(shù)int inSampleSize = 1;if (srcHeight > height || srcWidth > width) {if (srcWidth > srcHeight) {inSampleSize = Math.round(srcHeight / height);} else {inSampleSize = Math.round(srcWidth / width);}}//3. 真正加載圖片到內(nèi)存當(dāng)中options.inJustDecodeBounds = false;options.inSampleSize = inSampleSize;//ARGB_8888格式的圖片,每像素占用 4 Byte,而 RGB565則是 2 Byteoptions.inPreferredConfig = Bitmap.Config.RGB_565;options.inPurgeable = true;options.inInputShareable = true;return BitmapFactory.decodeFile(path, options); }

    7. LRU緩存機(jī)制

    LRU緩存機(jī)制的核心原理:

    • LruCache中維護(hù)了一個(gè)以訪問(wèn)順序排序的集合LinkedHashMap(雙向循環(huán)鏈表)
    • 新數(shù)據(jù)插入到鏈表頭部
    • 每當(dāng)緩存命中(即緩存數(shù)據(jù)被訪問(wèn)),則將數(shù)據(jù)移到鏈表頭部
    • 當(dāng)鏈表滿的時(shí)候,將鏈表尾部的數(shù)據(jù)丟棄

    8. 圖片的三級(jí)緩存

    關(guān)于Android圖片的多級(jí)緩存,其中主要的就是內(nèi)存緩存和硬盤緩存。它的核心思想是:

    • 在獲取一張圖片時(shí),首先到內(nèi)存緩存(LruCache)中去加載
    • 如果未加載到,則到硬盤緩存(DiskLruCache)中加載,如果加載到將其返回并添加進(jìn)內(nèi)存緩存
    • 否則通過(guò)網(wǎng)絡(luò)加載一張新的圖片,并將新加載的圖片添加進(jìn)入內(nèi)存緩存和硬盤緩存

    9. 參考文章

    Bitmap詳解與Bitmap的內(nèi)存優(yōu)化

    Android性能調(diào)優(yōu)(5)—Bitmap內(nèi)存模型

    Android面試一天一題(Day 22: 圖片到底是什么)

    Android使用BitmapRegionDecoder加載超大圖片方案

    Android性能調(diào)優(yōu)(6)—Bitmap優(yōu)化

    徹底解析Android緩存機(jī)制——LruCache

    淺談圖片加載的三級(jí)緩存

    數(shù)據(jù)存儲(chǔ)方式與數(shù)據(jù)緩存

    1. Android中5大數(shù)據(jù)存儲(chǔ)方式

    • 文件:存儲(chǔ)一些簡(jiǎn)單的文本數(shù)據(jù)或者二進(jìn)制數(shù)據(jù),包括內(nèi)存、外部存儲(chǔ)。
    • SharedPreferences(本質(zhì)上屬于文件存儲(chǔ)):適用于存儲(chǔ)一些鍵值對(duì),一般用來(lái)存儲(chǔ)配置信息。
    • SQLite數(shù)據(jù)庫(kù):適用于存儲(chǔ)一些復(fù)雜的關(guān)系型數(shù)據(jù)。
    • 網(wǎng)絡(luò):存儲(chǔ)比較重要的數(shù)據(jù),比如賬號(hào)密碼等。
    • ContentProvider:訪問(wèn)(增刪改查)其他應(yīng)用程序中私有數(shù)據(jù)。

    2. 有關(guān)數(shù)據(jù)安全問(wèn)題

    • 避免使用靜態(tài)變量保存核心、重要的數(shù)據(jù)。因?yàn)殪o態(tài)變量在進(jìn)程被殺死的時(shí)候,會(huì)重新初始化
    • 官方推薦使用五大數(shù)據(jù)存儲(chǔ)方式

    3. 數(shù)據(jù)緩存

    數(shù)據(jù)緩存
    • 推薦使用LRU策略緩存
    • 內(nèi)存緩存:存儲(chǔ)在集合當(dāng)中,重要數(shù)據(jù)不推薦使用靜態(tài)變量存儲(chǔ)
    • 磁盤緩存:根據(jù)數(shù)據(jù)類型、應(yīng)用場(chǎng)合選擇Android中5大數(shù)據(jù)存儲(chǔ)方式實(shí)現(xiàn)緩存
    • 使用一些實(shí)現(xiàn)了內(nèi)存緩存、磁盤緩存、緩存時(shí)間等強(qiáng)大功能的第三方開(kāi)源的緩存庫(kù):ACache、RxCache等
    緩存統(tǒng)計(jì)顯示與緩存清理
    • 緩存統(tǒng)計(jì)與顯示:統(tǒng)計(jì)/data/你的應(yīng)用包名/cache/目錄的大小
    • 緩存清理:刪除/data/你的應(yīng)用包名/cache/目錄

    4. 參考文章

    安卓中五種數(shù)據(jù)存儲(chǔ)方式

    【Android開(kāi)源項(xiàng)目分析】android輕量級(jí)開(kāi)源緩存框架——ASimpleCache(ACache)源碼分析

    【從 0 開(kāi)始開(kāi)發(fā)一款直播 APP】6 緩存 ACache 源碼解析

    Android記錄20-獲取緩存大小和清除緩存功能

    SharedPreferences

    1. SharedPreferences基本概念以及優(yōu)缺點(diǎn)

    • SharedPreferences用來(lái)保存基于XML文件存儲(chǔ)的key-value鍵值對(duì)數(shù)據(jù),通常用來(lái)存儲(chǔ)一些簡(jiǎn)單的配置信息。數(shù)據(jù)存儲(chǔ)在/data/data//shared_prefs目錄下。
    • 只能存儲(chǔ)少量boolean、int、float、long、String五種簡(jiǎn)單的數(shù)據(jù)類型,操作簡(jiǎn)單,但是無(wú)法完全替代其他數(shù)據(jù)存儲(chǔ)方式。
    • 無(wú)法進(jìn)行條件查詢等復(fù)雜操作,對(duì)于數(shù)據(jù)的處理只能是簡(jiǎn)單的處理。

    2. SharedPreferences的實(shí)現(xiàn)原理

    SharedPreferences是個(gè)單例,具體實(shí)現(xiàn)在SharedPrefencesImpl。任意Context拿到的都是同一個(gè)實(shí)例。
    SharedPreferences在實(shí)例化的時(shí)候會(huì)把SharedPreferences對(duì)應(yīng)的xml文件內(nèi)容通過(guò)pull解析全部讀取到內(nèi)存當(dāng)中(mMap)。
    關(guān)于讀操作:對(duì)于非多進(jìn)程兼容的SharedPreferences的讀操作是從內(nèi)存讀取的,不涉及IO操作。寫入的時(shí)候由于內(nèi)存已經(jīng)保存了完整的xml數(shù)據(jù),然后新寫入的數(shù)據(jù)也會(huì)同步更新到內(nèi)存,所以無(wú)論是用commit還是apply都不會(huì)影響立即讀取。
    關(guān)于寫操作:除非需要關(guān)心xml是否寫入文件成功,否則你應(yīng)該在所有調(diào)用commit的地方改用apply。

    3. 同步與異步提交

    commit方法的特點(diǎn)
    • 存儲(chǔ)的過(guò)程是原子操作
    • commit方法有返回值,設(shè)置成功為ture,否則為false
    • 同時(shí)對(duì)一個(gè)SharedPreferences設(shè)置值最后一次的設(shè)置會(huì)直接覆蓋前次值
    • 如果不關(guān)心設(shè)置成功與否,并且是在主線程設(shè)置值,建議用apply方法
    apply方法的特點(diǎn)
    • 存儲(chǔ)的過(guò)程也是原子操作
    • apply沒(méi)有返回值,存儲(chǔ)是否成功無(wú)從知道
    • apply寫入過(guò)程分兩步,第一步先同步寫入內(nèi)存,第二部在異步寫入物理磁盤
    • apply寫入的過(guò)程會(huì)阻塞同一個(gè)SharedPreferences對(duì)象的其他寫入操作
    總結(jié)

    apply比commit效率高,commit直接是向物理介質(zhì)寫入內(nèi)容,而apply是先同步將內(nèi)容提交到內(nèi)存,然后在異步的向物理介質(zhì)寫入內(nèi)容。這樣做顯然提高了效率。

    4. SharedPreferences不能實(shí)現(xiàn)跨進(jìn)程同步問(wèn)題

    現(xiàn)象
    • 數(shù)據(jù)安全問(wèn)題:數(shù)據(jù)讀寫不能實(shí)時(shí)更新而造成數(shù)據(jù)寫入丟失等問(wèn)題,每個(gè)進(jìn)程都會(huì)維護(hù)一個(gè)SharedPreferences的內(nèi)存副本,副本之間互不干擾
    • getSharedPreferences時(shí)候的空指針問(wèn)題
    解決方案
    • 通過(guò)查看 API 文檔發(fā)現(xiàn),在API Level > 11即Android 3.0可以通過(guò)Context.MODE_MULTI_PROCESS屬性來(lái)實(shí)現(xiàn)多進(jìn)程間的數(shù)據(jù)共享
    • 但是在API 23時(shí)該屬性被廢棄。官方文檔中明確寫明SharedPreferences不適用于多進(jìn)程間共享數(shù)據(jù),推薦使用ContentProvider等方式

    5. SharedPreferences存儲(chǔ)的數(shù)據(jù)不能過(guò)大

    • SharedPreferences存儲(chǔ)的基本的配置型數(shù)據(jù),不能存儲(chǔ)大量數(shù)據(jù)
    • SharedPreferences的讀寫操作可能會(huì)阻塞主線程,引起界面卡頓甚至ANR
    • SharedPreferences的Key-Value的mMap是一直存放在內(nèi)存當(dāng)中的,這樣會(huì)帶來(lái)極大的內(nèi)存消耗,甚至產(chǎn)生泄漏、OOM
    • SharedPreferences對(duì)Key-Value頻繁讀寫會(huì)產(chǎn)生大量的臨時(shí)對(duì)象,會(huì)造成內(nèi)存抖動(dòng),頻繁GC會(huì)造成界面卡頓等問(wèn)題

    6. 參考文章

    Android面試一天一題(14 Day:SharedPreferences)

    SharedPreferences多進(jìn)程共享數(shù)據(jù)爬坑之旅

    深入理解Android SharedPreferences的commit與apply

    SharedPreferences commit跟apply的區(qū)別

    組件化

    1. 組件化的基本概念

    組件化開(kāi)發(fā)就是將一個(gè)app分成多個(gè)模塊,每個(gè)模塊都是一個(gè)組件(Module),開(kāi)發(fā)的過(guò)程中我們可以讓這些組件相互依賴或者單獨(dú)調(diào)試部分組件等,但是最終發(fā)布的時(shí)候是將這些組件合并統(tǒng)一成一個(gè)apk,這就是組件化開(kāi)發(fā)。

    2. 組件化的特點(diǎn)

    • 公共資源、業(yè)務(wù)、模塊混在一起耦合度太高,組件化可以實(shí)現(xiàn)模塊之間的解耦、單獨(dú)測(cè)試驗(yàn)證,又實(shí)現(xiàn)了模塊共享資源和工具類
    • 組件化可以提高開(kāi)發(fā)效率:每個(gè)模塊可以獨(dú)立開(kāi)發(fā)編譯運(yùn)行
    • 利用組件化的思想對(duì)開(kāi)源框架進(jìn)行一次封裝,除了防止代碼入侵以外,同時(shí)也簡(jiǎn)化了使用,實(shí)現(xiàn)了項(xiàng)目的需求

    3. 組件化的實(shí)現(xiàn)

    組件化只是一種項(xiàng)目架構(gòu)的思想,并沒(méi)有具體的實(shí)現(xiàn)方案,需要根據(jù)公司的業(yè)務(wù)、項(xiàng)目性質(zhì)等進(jìn)行具體實(shí)現(xiàn)。一般的套路如下:

    組件化中,最好提供一個(gè)統(tǒng)一路由方案實(shí)現(xiàn)模塊之間的分發(fā)和跳轉(zhuǎn)。

    4. 參考文章

    Android組件化和插件化開(kāi)發(fā)

    Android組件化方案

    插件化

    1. 插件化的基本概念

    插件化開(kāi)發(fā)和組件化開(kāi)發(fā)略有不用,插件化開(kāi)發(fā)時(shí)將整個(gè)app拆分成很多模塊,這些模塊包括一個(gè)宿主和多個(gè)插件,與組件化最大的不同是:插件化中每個(gè)模塊都是一個(gè)單獨(dú)的apk(組件化的每個(gè)模塊是個(gè)lib),最終打包的時(shí)候?qū)⑺拗鱝pk和插件apk分開(kāi)或者聯(lián)合打包。

    2. 插件化的特點(diǎn)

    • 解決應(yīng)用越來(lái)越大所帶來(lái)的技術(shù)限制,比如65535方法數(shù)量限制
    • 應(yīng)用越來(lái)越大的時(shí)候多人合作開(kāi)發(fā)的問(wèn)題:插件化可以實(shí)現(xiàn)宿主和插件分開(kāi)編譯、并行開(kāi)發(fā),提高開(kāi)發(fā)效率并且分工明確
    • 插件模塊的動(dòng)態(tài)按需下載,減少宿主APK的體積
    • 插件模塊的動(dòng)態(tài)更新可以解決線上BUG或者上架活動(dòng),達(dá)到熱更新、熱修復(fù)的目的
    • 帶有插件化、熱更新的APK不能在Google Play上線,也就是沒(méi)有海外市場(chǎng)

    3. 插件化的核心原理

    • 通過(guò)類加載機(jī)制(DexClassLoader)加載插件APK
    • 通過(guò)代理機(jī)制(主要是動(dòng)態(tài)代理)實(shí)現(xiàn)Activity等組件的生命周期
    • 通過(guò)Java的反射機(jī)制結(jié)合面向接口(抽象)編程、面向切面程,實(shí)例化并且調(diào)用插件中的代碼
    • 訪問(wèn)插件中的資源:通過(guò)反射生成AssetManager對(duì)象并且通過(guò)反射調(diào)用addAssetPath方法加載插件中的資源(資源、主題等)
    • 利用Hook機(jī)制對(duì)ActivityManagerService進(jìn)行Hook,實(shí)現(xiàn)啟動(dòng)一個(gè)沒(méi)有在清單文件中注冊(cè)的插件Activity
    • 不同框架的具體實(shí)現(xiàn)和原理都不一樣……

    4. 常見(jiàn)插件化框架(按照時(shí)間先后排列)

    AndroidDynamicLoader:Android 動(dòng)態(tài)加載框架,他不是用代理 Activity 的方式實(shí)現(xiàn)而是用 Fragment 以及 Schema 的方式實(shí)現(xiàn)

    PluginMgr:不需要插件規(guī)范的apk動(dòng)態(tài)加載框架。

    Dynamic-load-apk:Android 使用動(dòng)態(tài)加載框架DL進(jìn)行插件化開(kāi)發(fā)

    Direct-Load-apk:Direct - load - apk 能夠加載插件的全部 資源. 支持 插件間 Activity跳轉(zhuǎn). 不像 “dynamic load - apk” 這個(gè)項(xiàng)目, “Direct - load - apk” 不需要對(duì)插件有任何約束,也不需要在插件中引入jar和繼承自定義Activity,可以直接使用this指針。

    Android-Plugin-Framework:此項(xiàng)目是Android插件開(kāi)發(fā)框架完整源碼及示例。用來(lái)通過(guò)動(dòng)態(tài)加載的方式在宿主程序中運(yùn)行插件APK

    ACDD:非代理Android動(dòng)態(tài)部署框架

    DynamicAPK:實(shí)現(xiàn)Android App多apk插件化和動(dòng)態(tài)加載,支持資源分包和熱修復(fù).攜程App的插件化和動(dòng)態(tài)加載框架

    比較新的,有代表性的有下面4個(gè):

    DroidPlugin:是360手機(jī)助手在Android系統(tǒng)上實(shí)現(xiàn)了一種新的插件機(jī)制

    Small:世界那么大,組件那么小。Small,做最輕巧的跨平臺(tái)插件化框架

    VirtualAPK:VirtualAPK是滴滴出行自研的一款優(yōu)秀的插件化框架

    RePlugin:RePlugin是一套完整的、穩(wěn)定的、適合全面使用的,占坑類插件化方案,由360手機(jī)衛(wèi)士的RePlugin Team研發(fā),也是業(yè)內(nèi)首個(gè)提出”全面插件化“(全面特性、全面兼容、全面使用)的方案

    5. 參考文章

    Android插件化技術(shù)入門

    插件化開(kāi)發(fā)小結(jié)

    Android博客周刊專題之 插件化開(kāi)發(fā)

    Android開(kāi)源插件化框架匯總

    熱修復(fù)

    1. 熱修復(fù)主要解決的問(wèn)題

    • 版本發(fā)布之后發(fā)現(xiàn)嚴(yán)重BUG,需要緊急動(dòng)態(tài)修復(fù)
    • 小功能即時(shí)上線、下線,比如節(jié)日活動(dòng)

    2. 傳統(tǒng)開(kāi)發(fā)流程與熱修復(fù)開(kāi)發(fā)流程對(duì)比

    從流程來(lái)看,傳統(tǒng)的開(kāi)發(fā)流程存在很多弊端:

    • 重新發(fā)布版本代價(jià)太大
    • 用戶下載安裝成本太高
    • BUG修復(fù)不及時(shí),用戶體驗(yàn)太差

    而熱修復(fù)的開(kāi)發(fā)流程顯得更加靈活,優(yōu)勢(shì)很多:

    • 無(wú)需重新發(fā)版,實(shí)時(shí)高效熱修復(fù)
    • 用戶無(wú)感知修復(fù)(甚至無(wú)需重啟應(yīng)用),無(wú)需下載新的應(yīng)用,代價(jià)小
    • 修復(fù)成功率高,把損失降到最低

    3. 熱修復(fù)補(bǔ)丁修復(fù)詳細(xì)工作流程

  • 線上檢查到Crash
  • 拉出BugFix分支修復(fù)Crash問(wèn)題
  • jenkins構(gòu)建和補(bǔ)丁生成
  • app通過(guò)推送或主動(dòng)拉取補(bǔ)丁文件
  • 將BugFix代碼合到master上
  • 4. 熱修復(fù)的兩大核心原理

    • ClassLoader加載方案
    • Native層替換方案(Hook Native)

    5. 熱修復(fù)主流框架及實(shí)現(xiàn)原理

    QQ空間的超級(jí)補(bǔ)丁技術(shù)

    超級(jí)補(bǔ)丁技術(shù)基于DEX分包方案,使用了多DEX加載的原理,大致的過(guò)程就是:把BUG方法修復(fù)以后,放到一個(gè)單獨(dú)的DEX里,插入到dexElements數(shù)組的最前面,讓虛擬機(jī)去優(yōu)先加載修復(fù)完后的方法。

    當(dāng)patch.dex中包含Test.class時(shí)就會(huì)優(yōu)先加載,在后續(xù)的DEX中遇到Test.class的話就會(huì)直接返回而不去加載,這樣就達(dá)到了修復(fù)的目的。

    微信的Tinker

    微信針對(duì)QQ空間超級(jí)補(bǔ)丁技術(shù)的不足提出了一個(gè)提供DEX差量包,整體替換DEX的方案。主要的原理是與QQ空間超級(jí)補(bǔ)丁技術(shù)基本相同,區(qū)別在于不再將patch.dex增加到elements數(shù)組中,而是差量的方式給出patch.dex,然后將patch.dex與應(yīng)用的classes.dex合并,然后整體替換掉舊的DEX文件,以達(dá)到修復(fù)的目的。

    阿里的AndFix

    AndFix不同于QQ空間超級(jí)補(bǔ)丁技術(shù)和微信Tinker通過(guò)增加或替換整個(gè)DEX的方案,提供了一種運(yùn)行時(shí)通過(guò)Hook Native方法,在Native修改Filed指針的方式,實(shí)現(xiàn)Java方法的替換,達(dá)到即時(shí)生效無(wú)需重啟,對(duì)應(yīng)用無(wú)性能消耗的目的。

    美團(tuán)的Robust

    主要原理:在每個(gè)方法前加入一段代碼,如果patch.jar存在,則加載patch.jar中的代碼片段,否則執(zhí)行原本的代碼片段。

    餓了么的Amigo

    Amigo 原理與 Tinker 基本相同,但是在 Tinker 的基礎(chǔ)上,進(jìn)一步實(shí)現(xiàn)了 so 文件、資源文件、Activity、BroadcastReceiver 的修復(fù),幾乎可以號(hào)稱全面修復(fù),不愧 Amigo(朋友)這個(gè)稱號(hào),能在危急時(shí)刻送來(lái)全面的幫助。

    6. 三大主流框架對(duì)比

    7. 參考文章

    Android熱修復(fù)技術(shù)選型——三大流派解析

    Android 插件化和熱修復(fù)知識(shí)梳理

    路由

    1. 什么是路由?

    根據(jù)路由表將頁(yè)面請(qǐng)求分發(fā)到指定頁(yè)面。

    2. 為什么需要路由?(路由的應(yīng)用場(chǎng)景)

    • 解耦:APP中使用到組件化、插件化等技術(shù)的時(shí)候,需要解耦模塊、頁(yè)面之間的依賴關(guān)系
    • 跳轉(zhuǎn)一致化:原生、H5頁(yè)面之間的互相跳轉(zhuǎn)規(guī)范統(tǒng)一
    • 頁(yè)面動(dòng)態(tài)配置:APP收到消息推送,點(diǎn)擊通知/用戶點(diǎn)擊活動(dòng)Banner廣告等需要跳轉(zhuǎn)到某個(gè)頁(yè)面,該頁(yè)面可以動(dòng)態(tài)配置
    • 頁(yè)面跳轉(zhuǎn)的攔截:比如不合法的頁(yè)面的屏蔽、登錄驗(yàn)證攔截、頁(yè)面不存在需要攔截并且跳轉(zhuǎn)到下載頁(yè)面等

    3. 路由的優(yōu)勢(shì)(與不使用路由對(duì)比)

    • 路由實(shí)現(xiàn)了頁(yè)面之間解耦:顯式Intent在項(xiàng)目龐大以后,類依賴耦合太大,不適合組件化拆分
    • 路由簡(jiǎn)化了頁(yè)面之間的協(xié)作:隱式Intent協(xié)作困難,調(diào)用時(shí)候不知道調(diào)什么參數(shù)
    • 路由的攔截功能提高了頁(yè)面訪問(wèn)的安全性:每個(gè)注冊(cè)了Scheme的Activity都可以直接打開(kāi),有安全風(fēng)險(xiǎn)
    • 路由表的動(dòng)態(tài)生成簡(jiǎn)化了頁(yè)面的管理:解決了傳統(tǒng)的AndroidMainfest集中式管理,這樣比較臃腫的問(wèn)題
    • 路由的動(dòng)態(tài)降級(jí)功能:不使用路由,如果頁(yè)面出錯(cuò),無(wú)法動(dòng)態(tài)降級(jí)
    • 路由的動(dòng)態(tài)攔截功能:不使用路由,每次打開(kāi)新的頁(yè)面都需要做登錄驗(yàn)證
    • 路由實(shí)現(xiàn)了頁(yè)面統(tǒng)一跳轉(zhuǎn):H5、Android、iOS地址不一樣,不利于統(tǒng)一相互跳轉(zhuǎn)協(xié)議、不利于服務(wù)器端(例如推送、活動(dòng)Banner等)對(duì)APP頁(yè)面進(jìn)行動(dòng)態(tài)配置

    4. 路由的常見(jiàn)功能及其實(shí)現(xiàn)思路和核心原理

    • 路由注冊(cè)

      • AndroidManifest里面的Activity聲明scheme碼是不安全的,所有App都可以打開(kāi)這個(gè)頁(yè)面,這里就產(chǎn)生有三種方式去注冊(cè):
      • 注解產(chǎn)生路由表,通過(guò)DispatchActivity轉(zhuǎn)發(fā)Intent
      • AndroidManifest注冊(cè),將其export=false,再通過(guò)DispatchActivity轉(zhuǎn)發(fā)Intent,天貓就是這么做的,比上面的方法的好處是路由查找都是系統(tǒng)調(diào)用,省掉了維護(hù)路由表的過(guò)程,但是AndroidManifest配置還是比較不方便的
      • 注解自動(dòng)修改AndroidManifest,這種方式可以避免路由表匯總的問(wèn)題,方案是這樣的,用自定義Lint掃描出注解相關(guān)的Activity,然后在processManifestTask后面修改AndroidManifest,該方案不穩(wěn)定
    • 路由表生成

      • 用APT(Annotation Processing Tool)生成URL和Activity的對(duì)應(yīng)關(guān)系、并且(結(jié)合路由分組策略)進(jìn)行路由匯總
    • 路由分發(fā)

      • 現(xiàn)在所有路由方案分發(fā)都是用Activity做分發(fā)的
    • 結(jié)果返回

      • 捕獲onActivityResult
    • 動(dòng)態(tài)攔截

      • 攔截器是重中之重,有了攔截器可以做好多事情。ARouter是用線程等待實(shí)現(xiàn)的(等所有注冊(cè)的攔截器處理完成之后才會(huì)進(jìn)行下一步分發(fā)跳轉(zhuǎn))
    • 參數(shù)獲取

      • 大部分路由庫(kù)都是手動(dòng)獲取參數(shù)的,這樣還要傳入?yún)?shù)key比較麻煩,有三種做法:
      • Hook掉Instrumentation的newActivity方法,注入?yún)?shù)
      • 注冊(cè)ActivityLifecycleCallbacks方法,注入?yún)?shù)
      • APT生成注入代碼,onCreate的時(shí)候bind一下

    5. 常見(jiàn)的路由框架對(duì)比

    6. 參考文章

    需要給activity跳轉(zhuǎn)增加路由么?

    Android 組件化 —— 路由設(shè)計(jì)最佳實(shí)踐

    Android 路由框架ARouter最佳實(shí)踐

    開(kāi)源最佳實(shí)踐:Android平臺(tái)頁(yè)面路由框架ARouter

    一款可能是最容易使用的對(duì)頁(yè)面、服務(wù)的路由框架。使用APT實(shí)現(xiàn)

    RouterKit

    Android權(quán)限機(jī)制和動(dòng)態(tài)權(quán)限適配

    1. 什么是Android權(quán)限機(jī)制

    • Android6.0以前:開(kāi)發(fā)者在AndroidManifest文件中聲明需要的權(quán)限,APP安裝時(shí),系統(tǒng)提示用戶APP將獲取的權(quán)限,需要用戶同意授權(quán)才能繼續(xù)安裝,從此APP便永久的獲得了授權(quán)。
    • Android6.0之后:引入動(dòng)態(tài)權(quán)限的機(jī)制。在APP運(yùn)行時(shí),用戶可以根據(jù)自身的需要,決定是否授予APP危險(xiǎn)權(quán)限,同時(shí),用戶也可以很方便回收授予的權(quán)限。動(dòng)態(tài)權(quán)限管理的機(jī)制,對(duì)于用戶的隱私保護(hù)是更加適用的。

    2. 危險(xiǎn)權(quán)限(組)與一般權(quán)限

    • 危險(xiǎn)權(quán)限(組)Dangerous Permissions:聯(lián)系人、電話、相機(jī)、定位、存儲(chǔ)、錄音、短信、日歷、傳感器
    • 一般權(quán)限Normal Permissions:除危險(xiǎn)權(quán)限之外的權(quán)限,比如網(wǎng)絡(luò)、WIFI、藍(lán)牙、鬧鐘、壁紙、NFC等

    注意:

    • 對(duì)于危險(xiǎn)權(quán)限的分組,如果申請(qǐng)某個(gè)危險(xiǎn)的權(quán)限,假設(shè)app早已被用戶授權(quán)了同一組的某個(gè)危險(xiǎn)權(quán)限,那么系統(tǒng)會(huì)立即授權(quán),而不需要用戶去點(diǎn)擊授權(quán)。
    • 不要對(duì)權(quán)限組過(guò)多的依賴,盡可能對(duì)每個(gè)危險(xiǎn)權(quán)限都進(jìn)行正常流程的申請(qǐng),因?yàn)樵诤笃诘腁ndroid版本中這個(gè)權(quán)限組可能會(huì)產(chǎn)生變化。

    3. 如何適配Android6.0動(dòng)態(tài)權(quán)限及其兼容性問(wèn)題

    動(dòng)態(tài)權(quán)限適配
    • APP要適配Android6.0非常簡(jiǎn)單,只需要在清單文件中配聲明權(quán)限,然后將targetSdkVersion升級(jí)到23及以上,同時(shí)加入權(quán)限檢查、申請(qǐng)、處理申請(qǐng)結(jié)果等代碼邏輯即可。

    • 相關(guān)重要API:

      • 檢查權(quán)限:ContextCompat.checkSelfPermission()
      • 申請(qǐng)授權(quán):ActivityCompat.requestPermissions()
      • 處理回調(diào):onRequestPermissionsResult()
    • 權(quán)限適配的代碼封裝,同時(shí)也可以使用一些封裝好的開(kāi)源庫(kù):MPermission、RxPermission等

    動(dòng)態(tài)權(quán)限的運(yùn)行兼容性問(wèn)題
    • 首先,舊版本APP(targetSdkVersion低于23),因?yàn)闆](méi)有適配權(quán)限的申請(qǐng)相關(guān)邏輯,在Android6.0以上機(jī)型運(yùn)行的時(shí)候,仍然采用安裝時(shí)授權(quán)的方案。
    • 適配了Android6.0的APP,在低版本Android系統(tǒng)上運(yùn)行的時(shí)候,仍然采用安裝時(shí)授權(quán)的方案。
    • 開(kāi)發(fā)者需要注意的是,權(quán)限申請(qǐng)的代碼邏輯只應(yīng)該在Android6.0及以上的機(jī)型被執(zhí)行。(因此推薦使用XXXCompat的類,這種類已經(jīng)對(duì)Android版本進(jìn)行了判斷)

    4. 參考文章

    Android 權(quán)限機(jī)制與適配經(jīng)驗(yàn)(QQ音樂(lè))

    Android 6.0 運(yùn)行時(shí)權(quán)限處理完全解析(鴻洋)

    View的繪制以及事件傳遞機(jī)制

    http://hencoder.com/

    動(dòng)畫(huà)機(jī)制

    屏幕適配

    Android新特性介紹,ConstraintLayout完全解析

    設(shè)計(jì)模式與架構(gòu)

    Kotlin

    開(kāi)源框架源碼分析

    Java高級(jí)基礎(chǔ)

    大綱

    Android工程師之Android面試大綱

    面試復(fù)習(xí)——Android工程師之Android面試大綱

    歡迎進(jìn)入Hensen_的博客目錄(全站式導(dǎo)航)

    總結(jié)

    以上是生活随笔為你收集整理的Android面试复习资料整理的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    国产午夜亚洲精品不卡下载 | 97久久精品无码一区二区 | 鲁一鲁av2019在线 | 亚洲精品美女久久久久久久 | 黑人巨大精品欧美一区二区 | 欧美性黑人极品hd | 日韩精品无码一区二区中文字幕 | 国产黑色丝袜在线播放 | 强开小婷嫩苞又嫩又紧视频 | 97久久精品无码一区二区 | 综合网日日天干夜夜久久 | 亚洲呦女专区 | 亚洲日韩中文字幕在线播放 | 午夜精品一区二区三区在线观看 | 国产片av国语在线观看 | 久久久久久久人妻无码中文字幕爆 | 国内精品人妻无码久久久影院蜜桃 | 无码人妻精品一区二区三区下载 | 国产成人亚洲综合无码 | 老熟妇仑乱视频一区二区 | 无码纯肉视频在线观看 | 亚洲色欲色欲欲www在线 | 老熟妇仑乱视频一区二区 | 久久无码中文字幕免费影院蜜桃 | 成人性做爰aaa片免费看 | 久久精品视频在线看15 | 高潮毛片无遮挡高清免费 | 最近中文2019字幕第二页 | 久久99精品久久久久婷婷 | 丝袜 中出 制服 人妻 美腿 | 女人被爽到呻吟gif动态图视看 | 成人无码精品1区2区3区免费看 | 九九在线中文字幕无码 | 午夜丰满少妇性开放视频 | 国产性生大片免费观看性 | 国精品人妻无码一区二区三区蜜柚 | 18禁黄网站男男禁片免费观看 | 波多野结衣av在线观看 | 日韩av无码中文无码电影 | 亚洲精品国偷拍自产在线观看蜜桃 | 天天综合网天天综合色 | 双乳奶水饱满少妇呻吟 | 乱码午夜-极国产极内射 | 成熟女人特级毛片www免费 | 亚洲狠狠婷婷综合久久 | 亚洲精品无码国产 | 帮老师解开蕾丝奶罩吸乳网站 | 香港三级日本三级妇三级 | 一本精品99久久精品77 | 高清国产亚洲精品自在久久 | 久9re热视频这里只有精品 | 亚洲国产精品美女久久久久 | 成人免费视频一区二区 | 国产精品高潮呻吟av久久4虎 | 国产又爽又黄又刺激的视频 | 国产黑色丝袜在线播放 | 国产精品成人av在线观看 | 国产九九九九九九九a片 | 美女毛片一区二区三区四区 | 国产成人精品久久亚洲高清不卡 | 97精品人妻一区二区三区香蕉 | 色婷婷综合中文久久一本 | 欧美三级不卡在线观看 | 久久久中文字幕日本无吗 | 日产国产精品亚洲系列 | aⅴ亚洲 日韩 色 图网站 播放 | 久久久中文字幕日本无吗 | 在线精品亚洲一区二区 | 熟妇女人妻丰满少妇中文字幕 | 日本熟妇乱子伦xxxx | 国产精品久久久久久久9999 | 性生交大片免费看l | 亚洲熟妇色xxxxx欧美老妇y | 狠狠色噜噜狠狠狠狠7777米奇 | 久久久久久久久888 | 亚洲色无码一区二区三区 | 亚洲欧美中文字幕5发布 | 国产成人精品一区二区在线小狼 | 人妻有码中文字幕在线 | 老司机亚洲精品影院 | 无码人中文字幕 | 亚洲成在人网站无码天堂 | 亚洲成av人综合在线观看 | 国产在线一区二区三区四区五区 | 日本一区二区更新不卡 | 精品国产一区二区三区四区 | 性色av无码免费一区二区三区 | 成年美女黄网站色大免费全看 | 亚洲国产欧美国产综合一区 | 国产精品视频免费播放 | 日韩亚洲欧美精品综合 | 中文字幕乱码人妻无码久久 | 秋霞成人午夜鲁丝一区二区三区 | 性色av无码免费一区二区三区 | 成人精品一区二区三区中文字幕 | 一本色道久久综合狠狠躁 | 天堂亚洲免费视频 | 久久久久久久人妻无码中文字幕爆 | 成人亚洲精品久久久久 | 女人被爽到呻吟gif动态图视看 | 中文字幕无码日韩专区 | 人人妻人人藻人人爽欧美一区 | 中文字幕日产无线码一区 | 亚洲成av人片天堂网无码】 | 久久精品视频在线看15 | 乌克兰少妇xxxx做受 | 熟妇人妻无乱码中文字幕 | 国产亚洲人成a在线v网站 | 日本护士xxxxhd少妇 | 久久午夜无码鲁丝片秋霞 | 成人无码精品一区二区三区 | 亚洲一区av无码专区在线观看 | 午夜丰满少妇性开放视频 | 岛国片人妻三上悠亚 | 亚洲欧洲日本无在线码 | 少妇无码一区二区二三区 | 无遮挡啪啪摇乳动态图 | 国精产品一区二区三区 | 日本又色又爽又黄的a片18禁 | 美女毛片一区二区三区四区 | 久久精品国产99精品亚洲 | 国产午夜福利100集发布 | 成在人线av无码免费 | 色窝窝无码一区二区三区色欲 | 欧美一区二区三区视频在线观看 | 最新版天堂资源中文官网 | 99久久婷婷国产综合精品青草免费 | 人妻与老人中文字幕 | 激情内射日本一区二区三区 | 性啪啪chinese东北女人 | 亚洲国产欧美在线成人 | 欧美老妇交乱视频在线观看 | 亚洲伊人久久精品影院 | 强辱丰满人妻hd中文字幕 | 久久久久se色偷偷亚洲精品av | 动漫av一区二区在线观看 | 99久久人妻精品免费一区 | 亚洲小说春色综合另类 | 55夜色66夜色国产精品视频 | 又大又黄又粗又爽的免费视频 | 国产福利视频一区二区 | 7777奇米四色成人眼影 | 久久精品国产99久久6动漫 | 精品久久久久香蕉网 | 国产精品无码一区二区三区不卡 | 大屁股大乳丰满人妻 | 精品国产成人一区二区三区 | 男女超爽视频免费播放 | 国产人妻精品一区二区三区不卡 | 久久精品国产大片免费观看 | 秋霞成人午夜鲁丝一区二区三区 | 亚洲狠狠色丁香婷婷综合 | 国产精品亚洲а∨无码播放麻豆 | 亚洲国产精品无码久久久久高潮 | 水蜜桃亚洲一二三四在线 | 精品人人妻人人澡人人爽人人 | 最新版天堂资源中文官网 | 久久人人爽人人爽人人片av高清 | 色 综合 欧美 亚洲 国产 | 亚洲成av人在线观看网址 | 精品无人国产偷自产在线 | 亚洲欧美日韩成人高清在线一区 | 丰满少妇人妻久久久久久 | 伊人久久大香线蕉亚洲 | 亚洲日韩一区二区三区 | 男人的天堂av网站 | 国产精品亚洲专区无码不卡 | 亚洲国产av美女网站 | 成熟人妻av无码专区 | 无码福利日韩神码福利片 | 2020久久香蕉国产线看观看 | av无码电影一区二区三区 | 免费网站看v片在线18禁无码 | 亚洲一区av无码专区在线观看 | 狠狠躁日日躁夜夜躁2020 | 国产高清av在线播放 | 欧美人与动性行为视频 | 中文字幕无码免费久久9一区9 | 无码吃奶揉捏奶头高潮视频 | 性做久久久久久久免费看 | 亚洲国产欧美在线成人 | 一本久久a久久精品亚洲 | 兔费看少妇性l交大片免费 | 无码帝国www无码专区色综合 | 欧美亚洲日韩国产人成在线播放 | 牲交欧美兽交欧美 | 无码av岛国片在线播放 | 色妞www精品免费视频 | 亚洲国产av美女网站 | 高潮毛片无遮挡高清免费 | 日本免费一区二区三区最新 | 亚洲一区av无码专区在线观看 | 最新国产乱人伦偷精品免费网站 | 日本一本二本三区免费 | 精品国产青草久久久久福利 | 免费观看的无遮挡av | 狂野欧美性猛xxxx乱大交 | 亚洲中文字幕在线无码一区二区 | 99久久婷婷国产综合精品青草免费 | 国产成人精品必看 | 青春草在线视频免费观看 | 玩弄少妇高潮ⅹxxxyw | av香港经典三级级 在线 | 精品无码一区二区三区爱欲 | 久久国产精品_国产精品 | 亚洲一区二区三区 | 欧美丰满熟妇xxxx | 国产亚洲tv在线观看 | 免费无码的av片在线观看 | 亚洲精品中文字幕乱码 | 红桃av一区二区三区在线无码av | 精品乱子伦一区二区三区 | 国产在线一区二区三区四区五区 | 日本一卡2卡3卡四卡精品网站 | 成人片黄网站色大片免费观看 | 77777熟女视频在线观看 а天堂中文在线官网 | 我要看www免费看插插视频 | 极品尤物被啪到呻吟喷水 | 人人妻人人澡人人爽精品欧美 | 任你躁国产自任一区二区三区 | 国精产品一品二品国精品69xx | 激情五月综合色婷婷一区二区 | 丰满少妇熟乱xxxxx视频 | 熟女少妇人妻中文字幕 | 久久久亚洲欧洲日产国码αv | 国产精品高潮呻吟av久久 | 成人性做爰aaa片免费看 | 亚洲国产精品无码久久久久高潮 | 欧美高清在线精品一区 | 免费乱码人妻系列无码专区 | 欧美日韩在线亚洲综合国产人 | 亚洲成av人片天堂网无码】 | 性欧美熟妇videofreesex | 亚洲国产精品无码一区二区三区 | 人人妻人人澡人人爽欧美精品 | 亚洲无人区午夜福利码高清完整版 | 国产成人精品久久亚洲高清不卡 | 中文字幕无码视频专区 | 美女毛片一区二区三区四区 | 曰韩少妇内射免费播放 | 国产在线无码精品电影网 | 小泽玛莉亚一区二区视频在线 | 超碰97人人射妻 | 一个人看的视频www在线 | 午夜精品一区二区三区在线观看 | 国产在线精品一区二区三区直播 | 欧美老熟妇乱xxxxx | 又大又硬又爽免费视频 | 国产在热线精品视频 | 狠狠色丁香久久婷婷综合五月 | 国产国产精品人在线视 | 中文字幕无码av激情不卡 | 噜噜噜亚洲色成人网站 | 国产性生交xxxxx无码 | 国产真实伦对白全集 | 亚洲色www成人永久网址 | 久久亚洲国产成人精品性色 | 成人精品视频一区二区 | 无码一区二区三区在线 | 欧美人与物videos另类 | 午夜性刺激在线视频免费 | 高清无码午夜福利视频 | 高清国产亚洲精品自在久久 | 波多野结衣aⅴ在线 | 麻豆成人精品国产免费 | 免费观看黄网站 | 三级4级全黄60分钟 | 一二三四社区在线中文视频 | 无码吃奶揉捏奶头高潮视频 | 日本大乳高潮视频在线观看 | 狂野欧美性猛xxxx乱大交 | 精品偷拍一区二区三区在线看 | 亚洲 欧美 激情 小说 另类 | 国精品人妻无码一区二区三区蜜柚 | 久久精品女人的天堂av | 国产麻豆精品精东影业av网站 | 人妻天天爽夜夜爽一区二区 | 欧美 丝袜 自拍 制服 另类 | 国产凸凹视频一区二区 | 国产人妻精品午夜福利免费 | 久久久无码中文字幕久... | 性欧美大战久久久久久久 | 樱花草在线播放免费中文 | 黑人玩弄人妻中文在线 | aⅴ亚洲 日韩 色 图网站 播放 | 国产精品美女久久久 | 人人妻人人澡人人爽人人精品浪潮 | 国产成人一区二区三区别 | 97夜夜澡人人爽人人喊中国片 | 亚洲大尺度无码无码专区 | 亚洲日本一区二区三区在线 | 男女超爽视频免费播放 | 无遮挡国产高潮视频免费观看 | 狂野欧美性猛交免费视频 | 亚洲狠狠色丁香婷婷综合 | 在线播放免费人成毛片乱码 | 麻豆成人精品国产免费 | 中文字幕乱码亚洲无线三区 | 精品 日韩 国产 欧美 视频 | 一二三四在线观看免费视频 | 成 人 网 站国产免费观看 | 国产成人精品视频ⅴa片软件竹菊 | 无码人妻av免费一区二区三区 | 国产真实伦对白全集 | 久久国产精品_国产精品 | 免费无码肉片在线观看 | 无码免费一区二区三区 | 亚洲欧美色中文字幕在线 | 曰韩少妇内射免费播放 | 国产卡一卡二卡三 | 波多野结衣av一区二区全免费观看 | 色婷婷av一区二区三区之红樱桃 | 日日摸夜夜摸狠狠摸婷婷 | 乱码av麻豆丝袜熟女系列 | 久久精品99久久香蕉国产色戒 | 午夜成人1000部免费视频 | 国产av剧情md精品麻豆 | 国产两女互慰高潮视频在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | √天堂资源地址中文在线 | 中文字幕乱码人妻无码久久 | 18无码粉嫩小泬无套在线观看 | 亚洲精品欧美二区三区中文字幕 | 亚无码乱人伦一区二区 | 欧美精品免费观看二区 | 国产亚洲视频中文字幕97精品 | 色综合久久久无码网中文 | 久久亚洲中文字幕精品一区 | 国产精品久久久午夜夜伦鲁鲁 | 欧美精品一区二区精品久久 | 国产熟妇高潮叫床视频播放 | 免费无码的av片在线观看 | 精品国产国产综合精品 | 99久久99久久免费精品蜜桃 | 高清无码午夜福利视频 | 亚洲精品成人福利网站 | 精品乱子伦一区二区三区 | 在线观看免费人成视频 | 亚洲熟妇自偷自拍另类 | 色综合天天综合狠狠爱 | 久久久国产精品无码免费专区 | 中文毛片无遮挡高清免费 | 激情五月综合色婷婷一区二区 | 对白脏话肉麻粗话av | 伦伦影院午夜理论片 | 午夜福利一区二区三区在线观看 | 国内综合精品午夜久久资源 | 夜夜高潮次次欢爽av女 | 国产精品亚洲专区无码不卡 | 亚洲另类伦春色综合小说 | 香蕉久久久久久av成人 | 夜夜夜高潮夜夜爽夜夜爰爰 | 少妇人妻大乳在线视频 | 久久久婷婷五月亚洲97号色 | 麻豆国产人妻欲求不满谁演的 | 18禁止看的免费污网站 | 成人精品一区二区三区中文字幕 | 精品 日韩 国产 欧美 视频 | 午夜福利试看120秒体验区 | 领导边摸边吃奶边做爽在线观看 | 99久久婷婷国产综合精品青草免费 | 亚洲自偷自偷在线制服 | 爽爽影院免费观看 | 东京无码熟妇人妻av在线网址 | 性生交大片免费看l | 国内综合精品午夜久久资源 | 久热国产vs视频在线观看 | 青草青草久热国产精品 | 女人被男人躁得好爽免费视频 | 18精品久久久无码午夜福利 | 国产成人精品优优av | 欧美精品国产综合久久 | 国产热a欧美热a在线视频 | 波多野结衣 黑人 | 人妻天天爽夜夜爽一区二区 | 国产精品18久久久久久麻辣 | 九九在线中文字幕无码 | 亚洲自偷自偷在线制服 | 国产69精品久久久久app下载 | 免费无码午夜福利片69 | 人人妻在人人 | 婷婷色婷婷开心五月四房播播 | 一本久道久久综合狠狠爱 | 色婷婷综合激情综在线播放 | 人妻少妇精品无码专区动漫 | 午夜理论片yy44880影院 | 欧美人与牲动交xxxx | 国产精品.xx视频.xxtv | 精品国精品国产自在久国产87 | 日本va欧美va欧美va精品 | 日韩欧美中文字幕公布 | 日日麻批免费40分钟无码 | 狂野欧美性猛交免费视频 | 2019nv天堂香蕉在线观看 | 亚洲精品欧美二区三区中文字幕 | 久久久精品国产sm最大网站 | 性啪啪chinese东北女人 | 天海翼激烈高潮到腰振不止 | 久久精品无码一区二区三区 | 无码帝国www无码专区色综合 | 一本久道久久综合婷婷五月 | 欧美 日韩 亚洲 在线 | 久久99热只有频精品8 | 亚洲欧美国产精品久久 | 亚洲熟妇自偷自拍另类 | 夜先锋av资源网站 | 丰满人妻一区二区三区免费视频 | 久久亚洲日韩精品一区二区三区 | 精品国偷自产在线 | 国产午夜视频在线观看 | 亚洲日韩一区二区 | 久久 国产 尿 小便 嘘嘘 | 无码任你躁久久久久久久 | 帮老师解开蕾丝奶罩吸乳网站 | 日韩精品无码一区二区中文字幕 | 国产一区二区三区日韩精品 | 无码中文字幕色专区 | 亚洲阿v天堂在线 | 日韩精品久久久肉伦网站 | 中文字幕乱妇无码av在线 | 又大又黄又粗又爽的免费视频 | 澳门永久av免费网站 | 亚洲s色大片在线观看 | 精品久久久无码人妻字幂 | 成人动漫在线观看 | 精品欧洲av无码一区二区三区 | 亚洲 激情 小说 另类 欧美 | 人人超人人超碰超国产 | 国产成人一区二区三区别 | 中文字幕乱码中文乱码51精品 | 狠狠色噜噜狠狠狠7777奇米 | 丰满肥臀大屁股熟妇激情视频 | 国产特级毛片aaaaaaa高清 | 亚洲日韩乱码中文无码蜜桃臀网站 | 日日摸日日碰夜夜爽av | 四虎永久在线精品免费网址 | 精品少妇爆乳无码av无码专区 | 人妻天天爽夜夜爽一区二区 | 中文字幕无码免费久久9一区9 | 性色欲情网站iwww九文堂 | 少妇人妻av毛片在线看 | 国产成人人人97超碰超爽8 | 撕开奶罩揉吮奶头视频 | 中文字幕日韩精品一区二区三区 | 欧美阿v高清资源不卡在线播放 | 久久久国产精品无码免费专区 | 性生交大片免费看l | 四十如虎的丰满熟妇啪啪 | 伊人色综合久久天天小片 | 久久久精品欧美一区二区免费 | 扒开双腿吃奶呻吟做受视频 | 乱人伦人妻中文字幕无码 | 欧美黑人巨大xxxxx | 青青青爽视频在线观看 | 午夜男女很黄的视频 | 久久aⅴ免费观看 | 亚洲精品综合五月久久小说 | 久久精品中文字幕一区 | 久久久国产精品无码免费专区 | 国产午夜无码精品免费看 | 久久天天躁狠狠躁夜夜免费观看 | 我要看www免费看插插视频 | 久久精品成人欧美大片 | 成人亚洲精品久久久久软件 | 国内精品九九久久久精品 | 国产精品久久久午夜夜伦鲁鲁 | 在线视频网站www色 | 亚洲成色www久久网站 | 全黄性性激高免费视频 | 久久精品女人的天堂av | 国语自产偷拍精品视频偷 | 久久国产精品二国产精品 | 午夜性刺激在线视频免费 | 亚洲精品无码人妻无码 | 成人亚洲精品久久久久软件 | 亚洲啪av永久无码精品放毛片 | 小鲜肉自慰网站xnxx | 国产猛烈高潮尖叫视频免费 | 欧美 丝袜 自拍 制服 另类 | 国产精品无套呻吟在线 | 久久精品女人的天堂av | 麻豆人妻少妇精品无码专区 | 久激情内射婷内射蜜桃人妖 | 狂野欧美性猛xxxx乱大交 | 国产凸凹视频一区二区 | 国产成人精品一区二区在线小狼 | 亚洲日韩av一区二区三区中文 | 樱花草在线播放免费中文 | 久久久久久a亚洲欧洲av冫 | 成人影院yy111111在线观看 | 久久久中文久久久无码 | 亚洲精品一区国产 | 老熟女重囗味hdxx69 | 亚洲无人区一区二区三区 | 97无码免费人妻超级碰碰夜夜 | 99久久精品日本一区二区免费 | 精品厕所偷拍各类美女tp嘘嘘 | 熟妇人妻激情偷爽文 | 日产国产精品亚洲系列 | 99国产欧美久久久精品 | 性史性农村dvd毛片 | 午夜肉伦伦影院 | 国产高清av在线播放 | 女人色极品影院 | 亚洲国产成人a精品不卡在线 | 亚洲熟悉妇女xxx妇女av | 亚洲精品久久久久久久久久久 | 色婷婷香蕉在线一区二区 | 国产成人综合色在线观看网站 | 免费观看的无遮挡av | 东京一本一道一二三区 | 国产艳妇av在线观看果冻传媒 | 国产精品va在线播放 | 欧美性猛交内射兽交老熟妇 | av人摸人人人澡人人超碰下载 | 性生交大片免费看l | 国产性生大片免费观看性 | 内射白嫩少妇超碰 | 一本大道伊人av久久综合 | 天天躁夜夜躁狠狠是什么心态 | 狠狠色丁香久久婷婷综合五月 | 亚洲小说图区综合在线 | 国产电影无码午夜在线播放 | 日本精品少妇一区二区三区 | 国产明星裸体无码xxxx视频 | 亚洲乱码国产乱码精品精 | 午夜精品一区二区三区在线观看 | 精品国产乱码久久久久乱码 | 自拍偷自拍亚洲精品被多人伦好爽 | 300部国产真实乱 | 一本大道伊人av久久综合 | 色五月丁香五月综合五月 | 黑人大群体交免费视频 | 性欧美videos高清精品 | 无码国内精品人妻少妇 | 国产亚洲欧美在线专区 | 人妻体内射精一区二区三四 | 免费国产成人高清在线观看网站 | www国产精品内射老师 | 久久综合香蕉国产蜜臀av | 性欧美熟妇videofreesex | 女人被男人躁得好爽免费视频 | 国产高清不卡无码视频 | 亚洲の无码国产の无码步美 | 人人妻人人澡人人爽欧美一区 | 亚洲爆乳大丰满无码专区 | 国产亚洲精品久久久久久 | 高潮喷水的毛片 | 亚洲日韩av一区二区三区中文 | 人人爽人人爽人人片av亚洲 | 精品久久久久久亚洲精品 | 亚洲午夜无码久久 | 国产福利视频一区二区 | 久久天天躁夜夜躁狠狠 | 久久精品国产日本波多野结衣 | 国产一区二区三区精品视频 | 欧美性生交xxxxx久久久 | 日韩精品无码一区二区中文字幕 | 人妻尝试又大又粗久久 | 又湿又紧又大又爽a视频国产 | 国产av剧情md精品麻豆 | 久久综合狠狠综合久久综合88 | 无码精品人妻一区二区三区av | 亚洲国产综合无码一区 | 亚洲狠狠色丁香婷婷综合 | 精品厕所偷拍各类美女tp嘘嘘 | 欧美三级不卡在线观看 | 欧美freesex黑人又粗又大 | 国内揄拍国内精品人妻 | a国产一区二区免费入口 | 亚洲精品国产品国语在线观看 | 国产极品美女高潮无套在线观看 | 国产欧美精品一区二区三区 | 久久久久久国产精品无码下载 | 日日碰狠狠躁久久躁蜜桃 | 丰腴饱满的极品熟妇 | 日本精品少妇一区二区三区 | 国产精品久久久久久久9999 | 红桃av一区二区三区在线无码av | 亚洲日韩乱码中文无码蜜桃臀网站 | 中文字幕av伊人av无码av | 无码av最新清无码专区吞精 | 99re在线播放 | 亚洲欧洲日本无在线码 | 亚洲va中文字幕无码久久不卡 | 日韩 欧美 动漫 国产 制服 | www成人国产高清内射 | 香港三级日本三级妇三级 | 丰满人妻精品国产99aⅴ | 国产极品美女高潮无套在线观看 | 初尝人妻少妇中文字幕 | 国产乱人无码伦av在线a | 精品国产一区av天美传媒 | 18黄暴禁片在线观看 | 日本大香伊一区二区三区 | 九月婷婷人人澡人人添人人爽 | 日本精品少妇一区二区三区 | 水蜜桃av无码 | 国产三级精品三级男人的天堂 | 久久久亚洲欧洲日产国码αv | av无码不卡在线观看免费 | 亚洲日韩av片在线观看 | 国产精品亚洲lv粉色 | а天堂中文在线官网 | 熟女少妇在线视频播放 | 国产情侣作爱视频免费观看 | 日日碰狠狠躁久久躁蜜桃 | 亚洲熟悉妇女xxx妇女av | 白嫩日本少妇做爰 | 成人亚洲精品久久久久软件 | ass日本丰满熟妇pics | 久久久中文久久久无码 | 三上悠亚人妻中文字幕在线 | 性欧美疯狂xxxxbbbb | 性欧美大战久久久久久久 | 国产精品久久久久久亚洲影视内衣 | 2020久久香蕉国产线看观看 | 少妇无码一区二区二三区 | 国内揄拍国内精品人妻 | 亚洲区小说区激情区图片区 | 伊人色综合久久天天小片 | 在线播放亚洲第一字幕 | 亚洲一区二区三区无码久久 | 欧美激情综合亚洲一二区 | 日本xxxx色视频在线观看免费 | 精品日本一区二区三区在线观看 | aⅴ亚洲 日韩 色 图网站 播放 | 在线看片无码永久免费视频 | 老熟妇仑乱视频一区二区 | 亚洲国产成人av在线观看 | 国产av久久久久精东av | 亚洲综合伊人久久大杳蕉 | 1000部啪啪未满十八勿入下载 | 在线播放无码字幕亚洲 | 精品偷拍一区二区三区在线看 | 成人无码视频免费播放 | 少妇高潮一区二区三区99 | 亚洲精品久久久久久久久久久 | 一本久久a久久精品亚洲 | 中文字幕乱码人妻二区三区 | 国产三级精品三级男人的天堂 | 一区二区三区乱码在线 | 欧洲 | 久久国产精品精品国产色婷婷 | 亚洲精品国产精品乱码不卡 | 无码任你躁久久久久久久 | 成人精品一区二区三区中文字幕 | 国产综合在线观看 | 国产精品久久国产三级国 | 欧美阿v高清资源不卡在线播放 | 久青草影院在线观看国产 | 亚洲色大成网站www国产 | 欧美 亚洲 国产 另类 | 欧美性猛交内射兽交老熟妇 | 超碰97人人做人人爱少妇 | 国产人妻精品一区二区三区不卡 | 无码人妻出轨黑人中文字幕 | 撕开奶罩揉吮奶头视频 | 国产婷婷色一区二区三区在线 | 2019午夜福利不卡片在线 | 国产精品多人p群无码 | 精品午夜福利在线观看 | 美女极度色诱视频国产 | 久久精品国产精品国产精品污 | 久久午夜无码鲁丝片午夜精品 | 日日躁夜夜躁狠狠躁 | 中文字幕无线码免费人妻 | 亚洲日韩一区二区 | 强辱丰满人妻hd中文字幕 | 欧美人与禽猛交狂配 | 中文字幕乱码人妻无码久久 | 白嫩日本少妇做爰 | 欧美第一黄网免费网站 | 久久亚洲精品成人无码 | 装睡被陌生人摸出水好爽 | 色五月五月丁香亚洲综合网 | 亚洲精品成人av在线 | www国产亚洲精品久久久日本 | 色噜噜亚洲男人的天堂 | 欧美人与动性行为视频 | 无码一区二区三区在线观看 | 麻豆国产人妻欲求不满 | 牲欲强的熟妇农村老妇女 | 欧美激情综合亚洲一二区 | 欧美人妻一区二区三区 | 欧洲熟妇色 欧美 | 香港三级日本三级妇三级 | 人人超人人超碰超国产 | 亚洲日本一区二区三区在线 | 欧美日韩人成综合在线播放 | 99久久亚洲精品无码毛片 | 国产内射爽爽大片视频社区在线 | 波多野结衣高清一区二区三区 | 天天做天天爱天天爽综合网 | 亚洲日韩一区二区三区 | 国产乱人无码伦av在线a | 成人精品视频一区二区 | 国产超级va在线观看视频 | 又大又紧又粉嫩18p少妇 | 亚洲男人av天堂午夜在 | 小sao货水好多真紧h无码视频 | 久久精品人妻少妇一区二区三区 | 精品久久久久久人妻无码中文字幕 | 国产亚洲精品久久久久久大师 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产情侣作爱视频免费观看 | 少妇人妻偷人精品无码视频 | 国产suv精品一区二区五 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 欧美精品免费观看二区 | 成人精品天堂一区二区三区 | 亚洲精品久久久久久一区二区 | 色欲综合久久中文字幕网 | 天堂无码人妻精品一区二区三区 | 成人综合网亚洲伊人 | 日本饥渴人妻欲求不满 | 成人精品天堂一区二区三区 | 久久99精品久久久久久 | 中文字幕人妻无码一夲道 | 欧美日韩一区二区综合 | 久久久亚洲欧洲日产国码αv | 亚洲a无码综合a国产av中文 | 在线天堂新版最新版在线8 | 亚拍精品一区二区三区探花 | 国产精品第一区揄拍无码 | 亚洲精品午夜无码电影网 | 天天摸天天透天天添 | 亚洲第一网站男人都懂 | 最近的中文字幕在线看视频 | 日韩欧美中文字幕公布 | 中文字幕无码乱人伦 | 欧美熟妇另类久久久久久不卡 | 综合人妻久久一区二区精品 | 一个人免费观看的www视频 | 美女极度色诱视频国产 | 欧美精品免费观看二区 | 四虎国产精品免费久久 | 国产亚洲日韩欧美另类第八页 | 纯爱无遮挡h肉动漫在线播放 | 国产精品多人p群无码 | 5858s亚洲色大成网站www | 国产乱码精品一品二品 | 亚洲欧美日韩成人高清在线一区 | 国产成人无码av一区二区 | 精品一区二区不卡无码av | 亚洲欧美综合区丁香五月小说 | 国产成人精品优优av | 天堂亚洲免费视频 | 国产精品igao视频网 | 西西人体www44rt大胆高清 | 疯狂三人交性欧美 | 欧美日本日韩 | www国产亚洲精品久久久日本 | 亚洲成av人在线观看网址 | 日本在线高清不卡免费播放 | 欧美老妇与禽交 | 日韩精品无码免费一区二区三区 | 久久综合香蕉国产蜜臀av | 精品无码一区二区三区的天堂 | 亚洲色成人中文字幕网站 | 国产精品福利视频导航 | 亚洲日本va中文字幕 | 久久久久人妻一区精品色欧美 | 麻豆精品国产精华精华液好用吗 | 欧美阿v高清资源不卡在线播放 | 欧美 亚洲 国产 另类 | 天天躁日日躁狠狠躁免费麻豆 | 老司机亚洲精品影院 | 国内揄拍国内精品人妻 | 日韩亚洲欧美精品综合 | 7777奇米四色成人眼影 | 国产熟女一区二区三区四区五区 | 色狠狠av一区二区三区 | 国产免费久久久久久无码 | 色欲综合久久中文字幕网 | 国产农村妇女高潮大叫 | 曰本女人与公拘交酡免费视频 | 在线观看国产午夜福利片 | 国产黑色丝袜在线播放 | 色欲综合久久中文字幕网 | 午夜福利试看120秒体验区 | 欧美日本精品一区二区三区 | 国产性生交xxxxx无码 | 国产精品嫩草久久久久 | 人人妻人人澡人人爽欧美一区 | 免费观看又污又黄的网站 | 精品国产国产综合精品 | 久久国语露脸国产精品电影 | 荡女精品导航 | av无码不卡在线观看免费 | 亚洲熟妇色xxxxx亚洲 | 色五月丁香五月综合五月 | 动漫av网站免费观看 | 亚洲中文字幕久久无码 | 亚洲中文字幕在线观看 | 少妇愉情理伦片bd | 免费国产黄网站在线观看 | 精品欧洲av无码一区二区三区 | 国内丰满熟女出轨videos | 国产精品爱久久久久久久 | 亚洲伊人久久精品影院 | 国产精品亚洲综合色区韩国 | 动漫av网站免费观看 | 国产成人无码专区 | 国产成人综合美国十次 | 精品无人国产偷自产在线 | 67194成是人免费无码 | 精品国产一区二区三区av 性色 | 亚洲一区二区三区无码久久 | 久久亚洲日韩精品一区二区三区 | 正在播放东北夫妻内射 | 一本无码人妻在中文字幕免费 | 国産精品久久久久久久 | 欧美喷潮久久久xxxxx | 免费网站看v片在线18禁无码 | 国产精品igao视频网 | 亚洲日韩中文字幕在线播放 | 99久久精品国产一区二区蜜芽 | 乱人伦中文视频在线观看 | 久久国产自偷自偷免费一区调 | 久久久久久久久蜜桃 | 高潮毛片无遮挡高清免费 | 狠狠色丁香久久婷婷综合五月 | 亚洲色偷偷偷综合网 | 天堂一区人妻无码 | 在线精品亚洲一区二区 | 中文字幕+乱码+中文字幕一区 | 欧美激情内射喷水高潮 | 荫蒂被男人添的好舒服爽免费视频 | 最新版天堂资源中文官网 | 无码国产乱人伦偷精品视频 | 亚洲七七久久桃花影院 | 又湿又紧又大又爽a视频国产 | 亚洲a无码综合a国产av中文 | 国产激情无码一区二区 | 亚洲小说图区综合在线 | 蜜臀aⅴ国产精品久久久国产老师 | 久久精品国产精品国产精品污 | 国产精品-区区久久久狼 | 领导边摸边吃奶边做爽在线观看 | 免费无码一区二区三区蜜桃大 | 亚洲综合无码久久精品综合 | 日韩人妻少妇一区二区三区 | 日本又色又爽又黄的a片18禁 | 亚洲成在人网站无码天堂 | 亚洲成av人在线观看网址 | 国产无av码在线观看 | 性欧美牲交在线视频 | 国产欧美熟妇另类久久久 | 亚洲精品国产第一综合99久久 | 久久精品人人做人人综合试看 | 欧美乱妇无乱码大黄a片 | 亚洲精品一区国产 | 亚洲日韩精品欧美一区二区 | 欧美日韩综合一区二区三区 | 少妇久久久久久人妻无码 | 99久久亚洲精品无码毛片 | 白嫩日本少妇做爰 | 九月婷婷人人澡人人添人人爽 | 国产激情一区二区三区 | 扒开双腿疯狂进出爽爽爽视频 | 少妇被粗大的猛进出69影院 | 在线a亚洲视频播放在线观看 | 美女极度色诱视频国产 | 岛国片人妻三上悠亚 | 亚洲熟妇色xxxxx欧美老妇 | 久久99久久99精品中文字幕 | 中文字幕乱码人妻二区三区 | 国产三级久久久精品麻豆三级 | 国产真实乱对白精彩久久 | 又大又黄又粗又爽的免费视频 | 55夜色66夜色国产精品视频 | 亚洲国产av美女网站 | 日本精品高清一区二区 | 九九热爱视频精品 | 日本一卡二卡不卡视频查询 | 国产亲子乱弄免费视频 | 国产午夜精品一区二区三区嫩草 | 亚洲男女内射在线播放 | 国产成人精品久久亚洲高清不卡 | 成人免费视频视频在线观看 免费 | 久久99精品久久久久婷婷 | 大肉大捧一进一出视频出来呀 | 牛和人交xxxx欧美 | 国产人妻精品一区二区三区 | 一本久道久久综合婷婷五月 | 国精产品一品二品国精品69xx | 男女猛烈xx00免费视频试看 | 亚洲欧洲日本综合aⅴ在线 | 女人被男人躁得好爽免费视频 | 国产精品亚洲专区无码不卡 | 性开放的女人aaa片 | 久久久国产精品无码免费专区 | 特大黑人娇小亚洲女 | 亚洲精品综合一区二区三区在线 | 97久久精品无码一区二区 | 亚洲欧美日韩成人高清在线一区 | 国产一区二区三区精品视频 | 无码午夜成人1000部免费视频 | ass日本丰满熟妇pics | 少妇一晚三次一区二区三区 | 色欲综合久久中文字幕网 | 一本久道久久综合狠狠爱 | 无码帝国www无码专区色综合 | 夜精品a片一区二区三区无码白浆 | 精品亚洲韩国一区二区三区 | 福利一区二区三区视频在线观看 | 性欧美熟妇videofreesex | 国产口爆吞精在线视频 | 亚洲人成无码网www | 日本肉体xxxx裸交 | 国产精品毛多多水多 | 国产精品办公室沙发 | 亚洲 高清 成人 动漫 | 高清无码午夜福利视频 | 国产精品美女久久久 | 漂亮人妻洗澡被公强 日日躁 | 人妻插b视频一区二区三区 | 亚洲精品鲁一鲁一区二区三区 | 麻豆果冻传媒2021精品传媒一区下载 | 青青青爽视频在线观看 | 亚洲aⅴ无码成人网站国产app | 欧美放荡的少妇 | 伊人久久大香线焦av综合影院 | 狠狠色色综合网站 | 2020久久超碰国产精品最新 | 亲嘴扒胸摸屁股激烈网站 | 午夜无码区在线观看 | 无码播放一区二区三区 | 国产精品久久国产三级国 | 亚洲一区二区观看播放 | 2020久久超碰国产精品最新 | 久久久久人妻一区精品色欧美 | 久久久久成人精品免费播放动漫 | 免费看少妇作爱视频 | 2020久久超碰国产精品最新 | 国产艳妇av在线观看果冻传媒 | 在线播放亚洲第一字幕 | 国产人妖乱国产精品人妖 | 精品少妇爆乳无码av无码专区 | 亚洲色大成网站www国产 | 在线天堂新版最新版在线8 | 精品成在人线av无码免费看 | 国产熟妇另类久久久久 | 亚洲精品国产精品乱码视色 | 久久亚洲精品中文字幕无男同 | 99久久精品午夜一区二区 | 亚洲成熟女人毛毛耸耸多 | 欧美35页视频在线观看 | 国产免费久久久久久无码 | 亚洲熟妇色xxxxx亚洲 | 性欧美videos高清精品 | 久久久精品成人免费观看 | 欧美成人高清在线播放 | 无码国产乱人伦偷精品视频 | 国产香蕉尹人视频在线 | 免费无码肉片在线观看 | 久久午夜无码鲁丝片 | 在线视频网站www色 | 风流少妇按摩来高潮 | 亚洲第一无码av无码专区 | 国产精品亚洲一区二区三区喷水 | 国产情侣作爱视频免费观看 | 亚洲国产精品成人久久蜜臀 | 久久久www成人免费毛片 | 99riav国产精品视频 | 免费网站看v片在线18禁无码 | 亚洲中文字幕无码中字 | 国产成人精品视频ⅴa片软件竹菊 | 亚洲欧洲日本综合aⅴ在线 | 国产亚洲美女精品久久久2020 | 人妻少妇精品无码专区二区 | 亚洲精品国产精品乱码视色 | 国产乱人伦偷精品视频 | 人妻少妇精品无码专区二区 | 丝袜人妻一区二区三区 | 性欧美牲交在线视频 | 国产两女互慰高潮视频在线观看 | 丰满人妻一区二区三区免费视频 | 久久精品女人天堂av免费观看 | 成人精品天堂一区二区三区 | 精品国产麻豆免费人成网站 | 风流少妇按摩来高潮 | 国产口爆吞精在线视频 | 国内精品人妻无码久久久影院蜜桃 | 欧美精品国产综合久久 | 国产精品第一国产精品 | 超碰97人人做人人爱少妇 | 无码帝国www无码专区色综合 | 欧美乱妇无乱码大黄a片 | 国产激情综合五月久久 | 在线观看国产一区二区三区 | 国产成人精品三级麻豆 | 久久国产自偷自偷免费一区调 | 亚洲一区二区三区香蕉 | 久精品国产欧美亚洲色aⅴ大片 | 在线天堂新版最新版在线8 | 久久综合狠狠综合久久综合88 | 在线成人www免费观看视频 | 亚洲毛片av日韩av无码 | 台湾无码一区二区 | 日欧一片内射va在线影院 | 熟妇人妻无码xxx视频 | 精品熟女少妇av免费观看 | 亚洲aⅴ无码成人网站国产app | 久久久久久久人妻无码中文字幕爆 | 婷婷色婷婷开心五月四房播播 | 日本xxxx色视频在线观看免费 | 国内少妇偷人精品视频免费 | 色综合久久88色综合天天 | 国内精品一区二区三区不卡 | 精品欧美一区二区三区久久久 | 久久亚洲国产成人精品性色 | 99麻豆久久久国产精品免费 | 麻豆精品国产精华精华液好用吗 | 国产精品国产三级国产专播 | 国产精品a成v人在线播放 | 丁香花在线影院观看在线播放 | 无码成人精品区在线观看 | 午夜成人1000部免费视频 | 狂野欧美性猛xxxx乱大交 | 欧美老熟妇乱xxxxx | 亚洲精品中文字幕久久久久 | 国产精品嫩草久久久久 | 特级做a爰片毛片免费69 | 玩弄人妻少妇500系列视频 | 久久综合久久自在自线精品自 | а√天堂www在线天堂小说 | 伊人久久大香线蕉av一区二区 | 亚洲综合久久一区二区 | 精品国产福利一区二区 | 国产精品毛多多水多 | 无码国产激情在线观看 | 一本大道伊人av久久综合 | 国产激情无码一区二区 | 国产农村妇女高潮大叫 | 亚洲精品国产第一综合99久久 | 亚洲精品一区国产 | 国产精品人妻一区二区三区四 | 在线观看欧美一区二区三区 | 欧美野外疯狂做受xxxx高潮 | av无码不卡在线观看免费 | 无码人妻少妇伦在线电影 | 又大又黄又粗又爽的免费视频 | 免费观看激色视频网站 | 欧美自拍另类欧美综合图片区 | 国产激情综合五月久久 | 永久黄网站色视频免费直播 | 欧美日本免费一区二区三区 | 国产精品久久久久久亚洲影视内衣 | 成熟女人特级毛片www免费 | 国产精品内射视频免费 | 丰满人妻被黑人猛烈进入 | 最新版天堂资源中文官网 | 久热国产vs视频在线观看 | 欧美激情一区二区三区成人 | 午夜精品久久久久久久 | 噜噜噜亚洲色成人网站 | 性色欲网站人妻丰满中文久久不卡 | 日本高清一区免费中文视频 | 人人澡人人透人人爽 | 中文字幕无码视频专区 | 亚洲熟妇色xxxxx欧美老妇y | 日本一本二本三区免费 | 婷婷综合久久中文字幕蜜桃三电影 | 99久久亚洲精品无码毛片 | 国产成人无码av片在线观看不卡 | 国产成人无码午夜视频在线观看 | 377p欧洲日本亚洲大胆 | 国产精品自产拍在线观看 | 欧美人与物videos另类 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 久久久无码中文字幕久... | 日韩精品a片一区二区三区妖精 | 97无码免费人妻超级碰碰夜夜 | 亚洲男女内射在线播放 | 中文毛片无遮挡高清免费 | 亚洲а∨天堂久久精品2021 | 亚洲一区二区三区在线观看网站 | 色一情一乱一伦 | 成 人 网 站国产免费观看 | 亚洲乱码国产乱码精品精 | 玩弄中年熟妇正在播放 | 国产亚洲精品久久久久久国模美 | 欧美成人免费全部网站 | 亚洲日本va中文字幕 | 波多野结衣aⅴ在线 | 装睡被陌生人摸出水好爽 | 午夜肉伦伦影院 | 久久久精品456亚洲影院 | 日日夜夜撸啊撸 | 国产亲子乱弄免费视频 | 性生交片免费无码看人 | 亚洲国产欧美在线成人 | 欧美一区二区三区视频在线观看 | 国产内射爽爽大片视频社区在线 | 精品厕所偷拍各类美女tp嘘嘘 | 亚洲中文字幕av在天堂 | 麻豆精品国产精华精华液好用吗 | 亚洲精品无码人妻无码 | 亚洲成在人网站无码天堂 | 精品无码一区二区三区的天堂 | 精品国产aⅴ无码一区二区 | 亚洲精品鲁一鲁一区二区三区 | 99麻豆久久久国产精品免费 | 国产极品美女高潮无套在线观看 | 国产亲子乱弄免费视频 | 国产凸凹视频一区二区 | 少妇一晚三次一区二区三区 | 午夜理论片yy44880影院 | 亚洲国精产品一二二线 | 无套内谢的新婚少妇国语播放 | 一本久久伊人热热精品中文字幕 | 日韩欧美群交p片內射中文 | 精品国产av色一区二区深夜久久 | 国产精品视频免费播放 | 午夜精品久久久内射近拍高清 | 亚洲精品国产a久久久久久 | 成人毛片一区二区 | 国产精品第一区揄拍无码 | 国产9 9在线 | 中文 | 欧美熟妇另类久久久久久不卡 | 西西人体www44rt大胆高清 | 欧美老熟妇乱xxxxx | 乱人伦人妻中文字幕无码久久网 | 婷婷丁香六月激情综合啪 | 成年美女黄网站色大免费视频 | 日本饥渴人妻欲求不满 | 2020久久超碰国产精品最新 | 色窝窝无码一区二区三区色欲 | 成人av无码一区二区三区 | 国产三级久久久精品麻豆三级 | 未满小14洗澡无码视频网站 | 黑人巨大精品欧美一区二区 | 无遮挡国产高潮视频免费观看 | 国产国产精品人在线视 | 国产精品手机免费 | 麻豆国产丝袜白领秘书在线观看 | 67194成是人免费无码 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 欧美 亚洲 国产 另类 | 欧美xxxx黑人又粗又长 | 国产后入清纯学生妹 | 激情内射亚州一区二区三区爱妻 | 欧美丰满熟妇xxxx性ppx人交 | √天堂中文官网8在线 | 午夜精品久久久内射近拍高清 | 国产精品美女久久久久av爽李琼 | 一本大道伊人av久久综合 | 国内精品九九久久久精品 | 久久午夜无码鲁丝片 | 亚洲成av人影院在线观看 | 丰满人妻被黑人猛烈进入 | 无套内射视频囯产 | 双乳奶水饱满少妇呻吟 | 亚洲人亚洲人成电影网站色 | 精品国产精品久久一区免费式 | 激情爆乳一区二区三区 | 999久久久国产精品消防器材 | 国产人妖乱国产精品人妖 | 99久久精品日本一区二区免费 | 在线看片无码永久免费视频 | 国产极品美女高潮无套在线观看 | 99精品国产综合久久久久五月天 | 精品人妻中文字幕有码在线 | 精品久久久无码人妻字幂 | 丰满人妻精品国产99aⅴ | 人妻互换免费中文字幕 | 日日夜夜撸啊撸 | 巨爆乳无码视频在线观看 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 国产精品香蕉在线观看 | 九九综合va免费看 | 国内精品九九久久久精品 | 2019nv天堂香蕉在线观看 | 亚洲精品成人av在线 | 性做久久久久久久免费看 | 伊人久久大香线蕉午夜 | 国产成人无码区免费内射一片色欲 | 国产精品理论片在线观看 | 西西人体www44rt大胆高清 | 无码精品国产va在线观看dvd | 日本一区二区更新不卡 | 中国女人内谢69xxxxxa片 | 国产色视频一区二区三区 | 欧美激情综合亚洲一二区 | 国产偷国产偷精品高清尤物 | 国语自产偷拍精品视频偷 | 纯爱无遮挡h肉动漫在线播放 | 日日碰狠狠躁久久躁蜜桃 | 性欧美牲交在线视频 | 欧美丰满熟妇xxxx性ppx人交 | 麻豆人妻少妇精品无码专区 | 成人女人看片免费视频放人 | av在线亚洲欧洲日产一区二区 | 精品日本一区二区三区在线观看 | 亚洲色在线无码国产精品不卡 | 国产精品igao视频网 | 97se亚洲精品一区 | 日韩欧美中文字幕在线三区 | 红桃av一区二区三区在线无码av | 久久精品国产一区二区三区肥胖 | 亚洲欧美国产精品专区久久 | 精品国偷自产在线视频 | 欧美zoozzooz性欧美 | 欧美午夜特黄aaaaaa片 | 国内精品人妻无码久久久影院蜜桃 | 乱中年女人伦av三区 | 欧美真人作爱免费视频 | 一本精品99久久精品77 | 国产成人无码av片在线观看不卡 | 成人无码精品1区2区3区免费看 | 国产成人亚洲综合无码 | 国模大胆一区二区三区 | 亚洲精品无码人妻无码 | 午夜无码人妻av大片色欲 | 国产激情艳情在线看视频 | 精品欧洲av无码一区二区三区 | 极品尤物被啪到呻吟喷水 | 免费看男女做好爽好硬视频 | 久久久久久亚洲精品a片成人 | 野外少妇愉情中文字幕 | 亚洲综合无码一区二区三区 | 丝袜人妻一区二区三区 | 国产无套内射久久久国产 | 黑人粗大猛烈进出高潮视频 | 亚洲gv猛男gv无码男同 | 国产午夜视频在线观看 | 少妇的肉体aa片免费 | 日韩av无码一区二区三区不卡 | 女人被男人爽到呻吟的视频 | 欧美老妇交乱视频在线观看 | 亚洲乱码日产精品bd | 丰满少妇高潮惨叫视频 | 特黄特色大片免费播放器图片 | 午夜福利一区二区三区在线观看 | аⅴ资源天堂资源库在线 | 日韩欧美群交p片內射中文 | 性做久久久久久久免费看 | 国产人妻久久精品二区三区老狼 | 亚洲s色大片在线观看 | 人妻体内射精一区二区三四 | 成年美女黄网站色大免费全看 | 国产麻豆精品精东影业av网站 | 初尝人妻少妇中文字幕 | 少妇高潮一区二区三区99 | av在线亚洲欧洲日产一区二区 | 99久久人妻精品免费二区 | 国产疯狂伦交大片 | 久久午夜夜伦鲁鲁片无码免费 | 999久久久国产精品消防器材 | 国产色xx群视频射精 | 欧美野外疯狂做受xxxx高潮 | 亚洲人成网站色7799 | 亚洲精品无码国产 | 激情内射亚州一区二区三区爱妻 | 亚洲色大成网站www | 国产色xx群视频射精 | 日韩少妇白浆无码系列 | 久激情内射婷内射蜜桃人妖 | 国产猛烈高潮尖叫视频免费 | 一本加勒比波多野结衣 | 久久99精品久久久久久动态图 | 国产激情一区二区三区 | 四虎国产精品免费久久 | 伊人久久大香线焦av综合影院 | 最近免费中文字幕中文高清百度 | 欧美性生交活xxxxxdddd | 内射老妇bbwx0c0ck | 国产精品欧美成人 | 国产av人人夜夜澡人人爽麻豆 | 久久久久久亚洲精品a片成人 | 久久综合网欧美色妞网 | 色综合视频一区二区三区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 装睡被陌生人摸出水好爽 | 97久久国产亚洲精品超碰热 | 亚洲精品午夜国产va久久成人 | 日本欧美一区二区三区乱码 | 欧美大屁股xxxxhd黑色 | 欧美黑人性暴力猛交喷水 | 少妇的肉体aa片免费 | 青青青爽视频在线观看 | 欧美 亚洲 国产 另类 | 97se亚洲精品一区 | 久久人人爽人人爽人人片ⅴ | 人人妻人人藻人人爽欧美一区 | 日本丰满熟妇videos | 国产精品内射视频免费 | 纯爱无遮挡h肉动漫在线播放 | 久久久久久亚洲精品a片成人 | 最近中文2019字幕第二页 | 人人妻人人澡人人爽欧美精品 | 精品无人国产偷自产在线 | а天堂中文在线官网 | 成人毛片一区二区 | 亚洲自偷自偷在线制服 | 日韩视频 中文字幕 视频一区 | a片免费视频在线观看 | 人妻尝试又大又粗久久 | 欧美日韩一区二区免费视频 | 国内精品人妻无码久久久影院 | 欧美精品无码一区二区三区 | √天堂资源地址中文在线 | 欧美午夜特黄aaaaaa片 | 亚洲成在人网站无码天堂 | 国产精品亚洲一区二区三区喷水 | 国产无套粉嫩白浆在线 | 久久99国产综合精品 | 国产三级久久久精品麻豆三级 | 俄罗斯老熟妇色xxxx | 久久久国产一区二区三区 | 国产精品丝袜黑色高跟鞋 | 老子影院午夜精品无码 | 亲嘴扒胸摸屁股激烈网站 | 亚洲精品国产品国语在线观看 | 免费人成在线视频无码 | 午夜福利试看120秒体验区 | 兔费看少妇性l交大片免费 | 日本乱偷人妻中文字幕 | 国产亚洲欧美日韩亚洲中文色 | 亚洲综合久久一区二区 | 欧美成人免费全部网站 | 亚洲成av人在线观看网址 | 丰满诱人的人妻3 | 欧美性生交活xxxxxdddd | 小sao货水好多真紧h无码视频 | 特级做a爰片毛片免费69 | 色老头在线一区二区三区 | 久久天天躁夜夜躁狠狠 | 内射爽无广熟女亚洲 | 日韩欧美中文字幕公布 | 国内丰满熟女出轨videos | 天堂亚洲免费视频 | 亚洲色偷偷偷综合网 | 精品无人区无码乱码毛片国产 | 未满成年国产在线观看 | 午夜精品久久久久久久久 | 国产无遮挡又黄又爽又色 | 伊人久久婷婷五月综合97色 | 在线观看国产一区二区三区 | 日本乱人伦片中文三区 | 国产精品无码mv在线观看 | 日本一卡2卡3卡四卡精品网站 | 无码人妻av免费一区二区三区 | 成人精品视频一区二区三区尤物 | 又湿又紧又大又爽a视频国产 | 永久免费精品精品永久-夜色 | aa片在线观看视频在线播放 | 四虎国产精品免费久久 | 国产精品无码成人午夜电影 | 久久久久亚洲精品男人的天堂 | 中文字幕av无码一区二区三区电影 | 久久人人爽人人爽人人片av高清 | 国产香蕉尹人视频在线 | 国产特级毛片aaaaaaa高清 | 国产成人av免费观看 | 欧美zoozzooz性欧美 | 国产69精品久久久久app下载 | 国内综合精品午夜久久资源 | 国语自产偷拍精品视频偷 | 精品人妻av区 | 极品尤物被啪到呻吟喷水 | 人人妻人人澡人人爽欧美精品 | 亚洲精品成a人在线观看 | 亚洲中文字幕无码一久久区 | 亚洲人成网站免费播放 | 在线视频网站www色 | 99久久久无码国产精品免费 | 娇妻被黑人粗大高潮白浆 | 少女韩国电视剧在线观看完整 | 丰满人妻一区二区三区免费视频 | 国产真实夫妇视频 | a在线亚洲男人的天堂 | 国产免费久久精品国产传媒 | 精品国产一区av天美传媒 | 熟女少妇人妻中文字幕 | 色欲综合久久中文字幕网 | 天堂亚洲免费视频 | 欧美freesex黑人又粗又大 | 日本熟妇大屁股人妻 | 色情久久久av熟女人妻网站 | 麻豆av传媒蜜桃天美传媒 | 亚洲精品www久久久 | 欧美三级不卡在线观看 | 亚洲天堂2017无码 | 樱花草在线社区www | 国产av一区二区三区最新精品 | 国产精品亚洲专区无码不卡 | 国产无遮挡又黄又爽又色 | 精品成人av一区二区三区 | 未满成年国产在线观看 | 亚洲va中文字幕无码久久不卡 | 午夜福利电影 | 国产av无码专区亚洲awww | 免费网站看v片在线18禁无码 | 亚洲成av人片天堂网无码】 | 日本爽爽爽爽爽爽在线观看免 | 国产成人无码一二三区视频 | 无码人妻精品一区二区三区不卡 | 日本xxxx色视频在线观看免费 | 亚洲熟熟妇xxxx | 一本无码人妻在中文字幕免费 | 撕开奶罩揉吮奶头视频 | 天天躁夜夜躁狠狠是什么心态 | 成人精品一区二区三区中文字幕 | 欧美国产日韩亚洲中文 | 荫蒂添的好舒服视频囗交 | 在线成人www免费观看视频 | 国产精品久久久久无码av色戒 | 久久97精品久久久久久久不卡 | 久久亚洲日韩精品一区二区三区 | 久久久久成人精品免费播放动漫 | 亚洲成a人片在线观看无码 | 亚洲va中文字幕无码久久不卡 | 扒开双腿疯狂进出爽爽爽视频 | 亚洲精品无码人妻无码 | 亚洲人亚洲人成电影网站色 | 亚洲熟妇色xxxxx欧美老妇 | 亚洲综合色区中文字幕 | 国产偷抇久久精品a片69 | 少妇邻居内射在线 | 国产高清不卡无码视频 | 国产麻豆精品精东影业av网站 | 欧美一区二区三区 | 色窝窝无码一区二区三区色欲 | 色综合久久久久综合一本到桃花网 | 亚洲人成网站免费播放 | 天天摸天天透天天添 | 宝宝好涨水快流出来免费视频 | 亚洲春色在线视频 | 国产午夜福利亚洲第一 | 亚洲成av人在线观看网址 | 无套内谢的新婚少妇国语播放 | 久久精品丝袜高跟鞋 | 2020久久超碰国产精品最新 | 日本熟妇浓毛 | 在线精品亚洲一区二区 | 中文无码精品a∨在线观看不卡 | 天天做天天爱天天爽综合网 | 久久综合久久自在自线精品自 | 欧美丰满老熟妇xxxxx性 | 自拍偷自拍亚洲精品被多人伦好爽 | 国产成人亚洲综合无码 | 久久国产精品二国产精品 | 丰满诱人的人妻3 | 久久国语露脸国产精品电影 | 青青草原综合久久大伊人精品 | 色婷婷香蕉在线一区二区 | 国产在热线精品视频 | 中文字幕人妻无码一区二区三区 | 秋霞成人午夜鲁丝一区二区三区 | 久久久久久久女国产乱让韩 | 国产精品久久久久久亚洲毛片 | 国产午夜福利亚洲第一 | 在线亚洲高清揄拍自拍一品区 | 国产成人无码区免费内射一片色欲 | 草草网站影院白丝内射 | av无码久久久久不卡免费网站 | 天天综合网天天综合色 | 蜜桃视频韩日免费播放 | 欧美丰满老熟妇xxxxx性 | 蜜桃臀无码内射一区二区三区 | 欧美xxxx黑人又粗又长 | 日韩亚洲欧美精品综合 | 中文字幕无码av激情不卡 | 国产无套粉嫩白浆在线 | 97夜夜澡人人爽人人喊中国片 | 国产国语老龄妇女a片 | 少妇无套内谢久久久久 | 午夜福利试看120秒体验区 | 成人亚洲精品久久久久 | 水蜜桃色314在线观看 | 亚洲一区二区观看播放 | 色欲人妻aaaaaaa无码 | 国产精品久久久久无码av色戒 | 国产综合色产在线精品 | 亚洲七七久久桃花影院 | 亚洲狠狠色丁香婷婷综合 | 高潮毛片无遮挡高清免费视频 | 国产 浪潮av性色四虎 | 国产又爽又黄又刺激的视频 | 成人精品一区二区三区中文字幕 | 中文字幕无码人妻少妇免费 | 伊在人天堂亚洲香蕉精品区 | 无码国产乱人伦偷精品视频 | 中文无码精品a∨在线观看不卡 | 日日鲁鲁鲁夜夜爽爽狠狠 | 亚洲精品国产品国语在线观看 | 亚洲精品久久久久中文第一幕 | 精品国产一区av天美传媒 | 久久国产36精品色熟妇 | 亚洲天堂2017无码中文 | av小次郎收藏 | 色妞www精品免费视频 | 精品人人妻人人澡人人爽人人 | 99久久亚洲精品无码毛片 | 欧美激情一区二区三区成人 | 亚洲成av人综合在线观看 | 欧美日韩在线亚洲综合国产人 | 亚洲国产精品一区二区第一页 | 亚洲狠狠色丁香婷婷综合 | 国产精品亚洲专区无码不卡 | 精品国产精品久久一区免费式 | 日韩欧美群交p片內射中文 | 国产成人无码区免费内射一片色欲 | 国产99久久精品一区二区 | 久久人人97超碰a片精品 | 亚洲人成网站在线播放942 | 国产精品永久免费视频 | 精品 日韩 国产 欧美 视频 | 久久99精品久久久久婷婷 | 欧美真人作爱免费视频 | 十八禁视频网站在线观看 | 4hu四虎永久在线观看 | ass日本丰满熟妇pics | 国产人妻人伦精品1国产丝袜 | 成人免费视频一区二区 | 宝宝好涨水快流出来免费视频 | 久久久精品欧美一区二区免费 | 国内精品久久毛片一区二区 | 天堂а√在线中文在线 | 欧美精品无码一区二区三区 | 一区二区三区高清视频一 | 国产激情综合五月久久 | 国产在线精品一区二区三区直播 | 国产午夜福利亚洲第一 | 国产精品亚洲lv粉色 | 精品国产一区二区三区四区 | 永久免费精品精品永久-夜色 | 秋霞特色aa大片 | 丰满人妻一区二区三区免费视频 | 97色伦图片97综合影院 | 午夜精品久久久内射近拍高清 | 大肉大捧一进一出视频出来呀 | 伊人久久婷婷五月综合97色 | 精品人妻人人做人人爽夜夜爽 | 无码纯肉视频在线观看 | 成人免费视频视频在线观看 免费 | 国产亚洲人成在线播放 | 荫蒂被男人添的好舒服爽免费视频 | 少妇邻居内射在线 | 亚洲人成网站免费播放 | 亚洲自偷自拍另类第1页 | 久9re热视频这里只有精品 | 成人aaa片一区国产精品 | 中文字幕av无码一区二区三区电影 | 熟妇女人妻丰满少妇中文字幕 | 午夜精品一区二区三区在线观看 | 亚洲日韩av一区二区三区四区 | 无码av免费一区二区三区试看 | 人人妻人人澡人人爽人人精品 | 亚洲天堂2017无码中文 | 亚洲自偷自偷在线制服 | 日本一区二区更新不卡 | 国产又爽又猛又粗的视频a片 | 秋霞成人午夜鲁丝一区二区三区 | 日韩欧美成人免费观看 | 久久五月精品中文字幕 | 成人影院yy111111在线观看 | 亚洲欧洲中文日韩av乱码 | 亚洲成av人综合在线观看 | 欧美性猛交内射兽交老熟妇 | 最新版天堂资源中文官网 | 玩弄人妻少妇500系列视频 | 国产成人一区二区三区在线观看 | 亚洲爆乳精品无码一区二区三区 | a国产一区二区免费入口 | 国产成人无码av在线影院 | 久久久久久久女国产乱让韩 | 99久久无码一区人妻 | 帮老师解开蕾丝奶罩吸乳网站 | 人妻少妇精品视频专区 | 丰满少妇弄高潮了www | 精品人妻中文字幕有码在线 | √天堂中文官网8在线 | 中文字幕乱码人妻无码久久 | 天堂一区人妻无码 | 精品国产一区二区三区四区 | 成人试看120秒体验区 | 成人免费视频一区二区 | 欧美人与牲动交xxxx | 国内少妇偷人精品视频 | 自拍偷自拍亚洲精品被多人伦好爽 | 久久久久免费看成人影片 | 日本爽爽爽爽爽爽在线观看免 | 99久久人妻精品免费一区 | 一本久道高清无码视频 | 熟妇女人妻丰满少妇中文字幕 | 又色又爽又黄的美女裸体网站 | 国产suv精品一区二区五 | 亚洲欧洲日本综合aⅴ在线 | 伊人久久婷婷五月综合97色 | 狠狠综合久久久久综合网 | 国产精品办公室沙发 | 荫蒂被男人添的好舒服爽免费视频 | 在线а√天堂中文官网 | 亚洲精品一区二区三区四区五区 | 午夜免费福利小电影 | 精品国产av色一区二区深夜久久 | 四虎4hu永久免费 | 国产美女精品一区二区三区 | 国产乱人无码伦av在线a | 精品久久综合1区2区3区激情 | 丰满妇女强制高潮18xxxx | 亚洲色成人中文字幕网站 | 国产欧美熟妇另类久久久 | 日本在线高清不卡免费播放 | 欧美成人午夜精品久久久 | 国产精品美女久久久 | 久久午夜无码鲁丝片午夜精品 | 亚洲娇小与黑人巨大交 | 老子影院午夜伦不卡 | 免费乱码人妻系列无码专区 | 伊人久久大香线蕉亚洲 | 一本大道伊人av久久综合 | 男人的天堂2018无码 | 熟女俱乐部五十路六十路av | 六十路熟妇乱子伦 | 窝窝午夜理论片影院 | 久久99国产综合精品 | 国内少妇偷人精品视频免费 | 国产亚洲欧美在线专区 | 中文字幕无码日韩欧毛 | 日韩少妇内射免费播放 | 色窝窝无码一区二区三区色欲 | 中文无码成人免费视频在线观看 | 亚洲精品久久久久avwww潮水 | 亚洲成色www久久网站 | 强开小婷嫩苞又嫩又紧视频 | 丝袜美腿亚洲一区二区 | 亚洲一区二区三区偷拍女厕 | 国产午夜无码精品免费看 | 香蕉久久久久久av成人 | 亚洲国产精品久久人人爱 | 欧美xxxx黑人又粗又长 | 亚洲欧洲无卡二区视頻 | 九九综合va免费看 | 国产精品a成v人在线播放 | 国内精品人妻无码久久久影院蜜桃 | 中文字幕无码乱人伦 | 国产九九九九九九九a片 | yw尤物av无码国产在线观看 | 亚洲精品欧美二区三区中文字幕 | 国产精品香蕉在线观看 | 日本在线高清不卡免费播放 | 亚洲欧美精品伊人久久 | 午夜熟女插插xx免费视频 | 成年美女黄网站色大免费全看 | 国产欧美精品一区二区三区 | 色综合久久中文娱乐网 | 一二三四社区在线中文视频 | 白嫩日本少妇做爰 | 漂亮人妻洗澡被公强 日日躁 | 国产一区二区三区精品视频 | 激情五月综合色婷婷一区二区 | 亚洲s色大片在线观看 | aa片在线观看视频在线播放 | 免费看男女做好爽好硬视频 | 久久 国产 尿 小便 嘘嘘 | 国产精品久久久久久久影院 | 久久亚洲a片com人成 | 日日摸天天摸爽爽狠狠97 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 国产手机在线αⅴ片无码观看 | 免费网站看v片在线18禁无码 | 亚洲熟妇色xxxxx欧美老妇y | 小sao货水好多真紧h无码视频 | 日日摸天天摸爽爽狠狠97 | 国产精品无码一区二区三区不卡 | 亚洲日韩av一区二区三区四区 | 少妇无码吹潮 | 精品久久久无码中文字幕 | 在线 国产 欧美 亚洲 天堂 | 久久久国产一区二区三区 | 精品一区二区不卡无码av | 乱码av麻豆丝袜熟女系列 |