亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > Android > 正文

Android面試題詳細整理系列(一)

2019-11-09 18:31:50
字體:
來源:轉載
供稿:網友

以下這些面試題都是筆者在(2016年12月-2017年1月)這段時間所面試android工程師的總結而來,面試的公司包括巨頭阿里,百度,搜狐等,還有新貴公司如多點在線科技,國美金融,智課網,陌陌科技,豬八戒等,還有小型活力公司如軟都科技,星云顏值,英克科技等,不足之處,還望各位不吝賜教。

1.如何在子線程創建handler?

熟悉handler機制的童鞋都知道,通常handler是在主線程創建,但有些時候要在子線程創建handler,應該怎么辦(什么時候? 面試的時候 哈哈)不要急 辦法總該有 嘿嘿 方法1:(直接獲取當前子線程的looper)

new Thread(new Runnable() { public void run() { Looper.PRepare(); // 此處獲取到當前線程的Looper,并且prepare() Handler handler = new Handler(){ @Override public void handleMessage(Message msg) { Toast.makeText(getapplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); Looper.loop(); }; }).start();

方法2(獲取主線程的looper,或者說是UI線程的looper)

new Thread(new Runnable() { public void run() { Handler handler = new Handler(Looper.getMainLooper()){ // 區別在這?。。?! @Override public void handleMessage(Message msg) { Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show(); } }; handler.sendEmptyMessage(1); }; }).start();

2.應用程序ANR產生的原因?如何定位ANR

大家面試的時候肯定會發現,有經驗的老司機提問時都是先拋出一個簡單問題,然后由此引出很多深層次的問題,關鍵在后邊,這是面試百度時候的一個問題(筆者去的是百度科技園 老偏僻了)且聽我娓娓道來

產生的原因大家都知道是在主線程里做了耗時的操作導致的,ANR一般有三種類型: 1:KeyDispatchTimeout(5 seconds) –主要類型 按鍵或觸摸事件在特定時間內無響應 2:BroadcastTimeout(10 seconds) BroadcastReceiver在特定時間內無法處理完成 3:ServiceTimeout(20 seconds) –小概率類型 Service在特定的時間內無法處理完成 那我們就要著手解決主要類型,具體如何定位,有以下幾種思路: 1.通過ANR日志定位問題 當ANR發生時,我們往往通過Logcat和traces文件(目錄/data/anr/)的相關信息輸出去定位問題。主要包含以下幾方面: 1)基本信息,包括進程名、進程號、包名、系統build號、ANR 類型等等; 2)CPU使用信息,包括活躍進程的CPU平均占用率、IO情況等等; 3)線程堆棧信息,所屬進程包括發生ANR的進程、其父進程、最近有活動的3個進程等等。 但是在平常測試中,ANR有基本測試不到,因為ANR基本發生在垃圾設備中,弱網絡,頻繁操作。而且問題不必現,即使看到了問題,定位麻煩:要去data/anr.txt文件里面查找,必須root,比較麻煩。

2.引入ANR檢測工具 由于anr問題不必現,因此引入以下ANR檢測工具,當anr問題出現時,自動dump手機中的日志信息如trace文件、堆棧信息等,基本原理如下:

2.1、基本原理 檢測到UI主線程卡頓時間超過設定的時間,如4s,即dump trace文件以及堆棧信息,同時拋出異常,收集信息,根據這些文件信息即可定位到發生anr的原因 2.2、ANR檢測工具在Baidu Browser中的應用 2.2.1如何在源代碼中插入anr檢測工具

步驟一:源代碼libs中添加anr.jar

步驟二:在 Application 的onCreate中添加初始化sdk的代碼

initSDK(Context context, String appKey, boolean watchdog, int time)

其中time表示檢測判定線程是否超時(發生anr)的門限值,單位:ms

步驟三:正常編譯打包apk

2.2.2如何測試發現并定位anr問題

安裝步驟2.2.1編譯打包插入anr檢測的apk

測試app,任意操作(monkey/case),當發生anr時,會自動殺掉進程,并在本地生成日志文件日志路徑:/sdcard/lynq_anr下有兩個文件夾

以Baidu Browser啟動為例。 Baidu Browser啟動過程主線程過長,在低端機上容易導致發生anr;線程超時,app進程kill掉,查看手機本地trace日志,Crash信息包括trace文件以及堆棧信息 分析trace文件 Trace文件通過DDMS可以查看具體發生ANR卡頓的原因 通過real Time/Call從大到小排序,找到對應的與代碼相關消耗時間最大的方法可以看出書簽數據庫初始化消耗CPU時間最長。

3.android的context是指什么,在一個應用程序中有多少Context實例?

這個問題還是很好回答的嘛,首先Context描述的是一個應用程序環境的信息,即上下文,是一個抽象類。 這里寫圖片描述

因此總Context實例個數=Service個數+Activity個數+1個A品牌力cationContext個數

4.Jni開發步驟?

1)使用Android Studio開發工具,下載NDK 2)創建含有native方法的java類 3)通過javah命令生成.h文件 4)在.c文件中實現以上方法 5)編寫Android.mk文件 6)用NDK工具編譯生成.so文件 7)把.so文件復制到lib下

5.事件沖突解決方案

針對滑動沖突這里給出兩種解決方案:外部攔截法,內部攔截法。 1)外部攔截法 情景:一個ViewPager嵌套了一個Listview,一個是左右滑動,一個上下滑動。這個時候我們可以用外部攔截法,來處理沖突。在父容器ViewPager中,重寫onInterceptTouchEvent()方法,判斷當左右滑動時就攔截事件,上下滑動就不攔截,將事件交由子元素Listview來處理。首先我們需要重寫一個ViewPager,叫MyViewPager,然后重寫onInterceptTouchEvent()方法。具體代碼如下:

public class MyViewPager extends ViewPager { private int startX; private int startY; public MyViewPager(Context context) { super(context); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: startX= (int) ev.getX(); startY= (int) ev.getY(); break; case MotionEvent.ACTION_MOVE: int dX= (int) (ev.getX()-startX); int dY= (int) (ev.getY()-startX); if(Math.abs(dX)>Math.abs(dY)){//左右滑動 return true; }else {//上下滑動 return false; } case MotionEvent.ACTION_UP: break; } return super.onInterceptTouchEvent(ev); }}

2)內部攔截法 情景:一個ViewPager嵌套了一個ViewPager,兩個都是左右滑動。這個時候我們可以用內部攔截法,來處理沖突。即重寫子元素的dispatchTouchEvent()方法,并調用getParent().requestDisallowInterceptTouchEvent(true)是父容器不能攔截子元素需要的事件。下面來看具體代碼:

public boolean dispatchTouchEvent(MotionEvent event) { ... switch (action) { case MotionEvent.ACTION_MOVE: getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_MOVE: if(子元素需要處理此事件) getParent().requestDisallowInterceptTouchEvent(true); break; case MotionEvent.ACTION_UP: { break; } ... return super.dispatchTouchEvent(event);; }

當然,還需要修改父容器的onInterceptTouchEvent()方法,代碼如下:

@Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action=ev.getAction(); if(action==MotionEvent.ACTION_DOWN){ return false; }else { return true; } }

6.如何查看Activty任務棧結構?

剛聽到問題,小哥我一下蒙蔽了,細細一想,有以下解決方案 方法一:通過ActivityManager獲取狀態 Android提供了ActivityManger來幫助開發者了解運行期間的狀態,通過調用getRunningTasks(int)方法,就可以在得到RunningTaskInfo的列表,其代表著當前Android設備正在運行著的Task。從RunningTaskInfo中又可以進一步得到更多的信息。

ActivityManager am = (ActivityManager)getSystemService(Context.ACTIVITY_SERVICE);List<RunningTaskInfo> runningTaskInfoList = am.getRunningTasks(10);for (RunningTaskInfo runningTaskInfo : runningTaskInfoList) { log("id: " + runningTaskInfo.id); log("descr方法二:手動記錄和管理Activities棧 Activity的創建和銷毀都會有相應的回調函數:onCreate(),onDestroy()。因此可以自建一個靜態全局Stack對象,在onCreate()時候講當前Activity對象加入到Stack中,而在onDestroy()時把它從Stack中移除。這樣我們就隨時可以知道當前Activity的詳細情況了。

方法三:使用adb shell指令 Android還為開發者提供了adb(Android Debug Bridge),這是非常強大的調試工具。最常用的自然是logcat來顯示日志記錄。另外一個很強大的指令就是這里要提到的dumpsys。dumpsys還可以添加不同的參數來指示需要輸出哪一類Service的信息。對于本文提到的內容,需要查看的就是activity,指令就是:

adb shell dumpsys activity

輸入上述指令,就能得到關于設備非常長的一段訊息,單是也能清晰看出它們比較詳細的分類

ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents) * PendingIntentRecord{42b05f20 com.android.vending startService} ... ... ... ...ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts) Historical broadcasts [foreground]: #0: BroadcastRecord{430d2fb8 u-1 android.intent.action.TIME_TICK} act=android.intent.action.TIME_TICK flg=0x50000014 (has extras) extras: Bundle[{android.intent.extra.ALARM_COUNT=1}] ... ... ... ...ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers) Published single-user content providers (by class): * ContentProviderRecord{429d18a8 u0 com.android.phone/.IccProvider} proc=ProcessRecord{429765d8 858:com.android.phone/1001} singleton=true authority=icc ... ... ... ...ACTIVITY MANAGER SERVICES (dumpsys activity services) User 0 active services: * ServiceRecord{429f8668 u0 com.android.bluetooth/.hid.HidService} app=null created=-1h44m27s317ms started=false connections=0 ... ... ... ...ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities) Stack #0: Task id #28 TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1} Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10c00000 cmp=com.android.systemui/.recent.RecentsActivity (has extras) } Hist #0: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28} Intent { act=com.android.systemui.recent.action.TOGGLE_RECENTS flg=0x10800000 cmp=com.android.systemui/.recent.RecentsActivity bnds=[328,886][656,1176] } ProcessRecord{42968230 695:com.android.systemui/u0a12} ... ... ... ...ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes) Process LRU list (sorted by oom_adj, 28 total, non-act at 3, non-svc at 3): PERS #27: sys F/ /P trm: 0 605:system/1000 (fixed) ... ... ... ...

每一個類別都有一個括號內容,給出了更加詳細的指令來查看該類別下更多具體內容。因此再來嘗試指令:

db shell dumpsys activity activities

就能看到下邊的結果

CTIVITY MANAGER ACTIVITIES (dumpsys activity activities) Stack #0: Task id #28 * TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1} ... ... ... ... * Hist #0: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28} ... ... ... ... Task id #1 * TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1} ... ... ... ... * Hist #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1} ... ... ... ... Running activities (most recent first): TaskRecord{43525058 #28 A=com.android.systemui U=0 sz=1} Run #1: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28} TaskRecord{429a35f8 #1 A=com.android.launcher U=0 sz=1} Run #0: ActivityRecord{429a1760 u0 com.android.launcher/com.android.launcher2.Launcher t1} mLastPausedActivity: ActivityRecord{428d1ae8 u0 com.android.systemui/.recent.RecentsActivity t28} Stack #1: Task id #25 * TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5} numActivities=5 rootWasReset=false userId=0 mTaskType=0 numFullscreen=5 mOnTopOfHome=true intent={cmp=com.iderzheng/.SingleTaskActivity} realActivity=com.iderzheng/.SingleTaskActivity Activities=[ActivityRecord{42a7e160 u0 com.iderzheng/.SingleTaskActivity t25}, ActivityRecord{42bffdf0 u0 com.iderzheng/.StandardActivity t25}, ActivityRecord{42e9e8f8 u0 com.iderzheng/.SingleTopActivity t25}, ActivityRecord{434c2238 u0 com.iderzheng/.StandardActivity t25}, ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25}] askedCompatMode=false lastThumbnail=null lastDescription=null lastActiveTime=6229735 (inactive for 357s) * Hist #4: ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25} packageName=com.iderzheng processName=com.iderzheng launchedFromUid=10124 launchedFromPackage=com.iderzheng userId=0 app=ProcessRecord{4312cbb0 3700:com.iderzheng/u0a124} Intent { cmp=com.iderzheng/.SingleTopActivity bnds=[328,580][656,870] } frontOfTask=false task=TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5} taskAffinity=com.iderzheng realActivity=com.iderzheng/.SingleTopActivity baseDir=/data/app/com.iderzheng-1.apk dataDir=/data/data/com.iderzheng stateNotNeeded=false componentSpecified=true mActivityType=0 compat={320dpi} labelRes=0x7f0a0013 icon=0x7f020057 theme=0x7f0b0000 config={1.0 310mcc?mnc en_US ldltr sw384dp w384dp h567dp 320dpi nrml port finger -keyb/v/h -nav/h s.7} launchFailed=false launchCount=0 lastLaunchTime=-1h40m33s397ms haveState=false icicle=null state=RESUMED stopped=false delayedResume=false finishing=false keysPaused=false inHistory=true visible=true sleeping=false idle=true fullscreen=true noDisplay=false immersive=false launchMode=1 frozenBeforeDestroy=false thumbnailNeeded=false forceNewConfig=false mActivityType=APPLICATION_ACTIVITY_TYPE thumbHolder: 42b0ee20 bm=null desc=null waitingVisible=false nowVisible=true lastVisibleTime=-5m56s862ms ... ... ... ... Running activities (most recent first): TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5} Run #7: ActivityRecord{4279d2d8 u0 com.iderzheng/.SingleTopActivity t25} TaskRecord{429e9558 #24 A=com.iderzheng U=0 sz=1} Run #6: ActivityRecord{429d5408 u0 com.iderzheng/.SingleInstanceActivity t24} TaskRecord{42b0ee20 #25 I=com.iderzheng/.SingleTaskActivity U=0 sz=5} Run #5: ActivityRecord{434c2238 u0 com.iderzheng/.StandardActivity t25} Run #4: ActivityRecord{42e9e8f8 u0 com.iderzheng/.SingleTopActivity t25} Run #3: ActivityRecord{42bffdf0 u0 com.iderzheng/.StandardActivity t25} Run #2: ActivityRecord{42a7e160 u0 com.iderzheng/.SingleTaskActivity t25} TaskRecord{4282e508 #23 A=com.iderzheng U=0 sz=2} Run #1: ActivityRecord{429655d8 u0 com.iderzheng/.StandardActivity t23} Run #0: ActivityRecord{429564e0 u0 com.iderzheng/.MainActivity t23} ... ... ... ... Recent tasks: ... ... ... ...

整個log顯示了當前所有在運行的任務棧,它們的id分別是什么。對于每個Task,也有Activity數量等信息,同時也列出了其中的Activity列表,并且對于每個Activity也有比較詳細的描述,比如啟動它的Intent的內容。

如果覺得內容過多,只想看看棧的內容,也可以直接跳到”Running activities (most recent first)”那部分,比較簡潔而又明了的列出了棧中得Activity列表,就能知道當按下返回鍵的時候會應該會回到哪個Activity以后是要退出程序。

在寫這篇文章時參考了很多同行的博客,在此特別感謝Iden,Vonnie Jade,baidu_mtc的博客,hongdameng的專欄等同行。希望大家共同成長,共同進步。

我是kris,See you next time?。。?/p>

http://blog.iderzheng.com/debug-activity-task-stack-with-adb-shell-dumpsys/ 使用adb shell dumpsys檢測Android的Activity任務棧(Iden) http://www.cnblogs.com/yxx123/p/5250101.html Android滑動事件沖突(Vonnie Jade) http://blog.csdn.net/baidu_mtc/article/details/50396143 ANR檢查定位分析工具(baidu_mtc的博客)

http://blog.csdn.net/hongdameng/article/details/42639961# Android子線程創建Handler方法(hongdameng的專欄)


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久九九有精品国产23| 国产精品96久久久久久| 欧美小视频在线观看| 欧美视频二区36p| 久久精品成人一区二区三区| 亚洲美女激情视频| 国产精品永久免费在线| 富二代精品短视频| 色午夜这里只有精品| 欧美丰满少妇xxxx| 亚洲精品美女在线观看| 成人动漫网站在线观看| 国产成人在线视频| 国产成人精品电影久久久| 高清日韩电视剧大全免费播放在线观看| 国产深夜精品福利| 久久成人这里只有精品| 亚洲午夜女主播在线直播| 91精品国产色综合久久不卡98| 高清视频欧美一级| 中文字幕亚洲二区| 欧美精品激情blacked18| 欧美一级电影在线| 性金发美女69hd大尺寸| 久久精品中文字幕免费mv| 色哟哟亚洲精品一区二区| 日本免费在线精品| 亚洲成人激情视频| 欧美男插女视频| 久久国产一区二区三区| 精品久久久久久久久久久久久| 国产精品一区二区三区在线播放| 高跟丝袜一区二区三区| 在线观看亚洲区| 欧美成人手机在线| 91精品国产91久久久久| 亚洲一级免费视频| 国产精品 欧美在线| 色偷偷偷亚洲综合网另类| 久热精品视频在线观看一区| 国产婷婷成人久久av免费高清| 久久久影视精品| 日韩精品在线免费| 欧美日韩中文字幕在线视频| 欧美另类xxx| 91chinesevideo永久地址| 欧美精品成人91久久久久久久| 日本人成精品视频在线| 日韩精品在线免费播放| 成人午夜高潮视频| 色综合影院在线| 国产偷国产偷亚洲清高网站| 久久久久久久电影一区| 亚洲a区在线视频| 国产视频亚洲视频| 国产精品久久久久久久久借妻| 成人av在线天堂| 国产精品999999| 日韩中文字幕在线看| 欧美xxxx做受欧美| 91在线播放国产| 日韩高清av一区二区三区| 久久中文字幕国产| 久久久亚洲国产天美传媒修理工| 色偷偷88888欧美精品久久久| 日产精品99久久久久久| 欧美精品video| 中文字幕v亚洲ⅴv天堂| 69视频在线免费观看| 国产精品久久久久影院日本| 日韩在线播放视频| 欧美裸身视频免费观看| 青青草国产精品一区二区| 91成人性视频| 国产精品三级久久久久久电影| 日韩美女激情视频| 视频一区视频二区国产精品| 成人激情在线观看| 欧美激情区在线播放| 亚洲视频第一页| 日韩成人中文字幕在线观看| 精品视频中文字幕| 色噜噜国产精品视频一区二区| 日本久久久久久| 91精品国产电影| 日韩av毛片网| 亚洲淫片在线视频| 91福利视频网| 日本久久久久久久久久久| 日韩在线精品视频| 日韩中文字幕网站| 精品日本高清在线播放| 欧美国产在线电影| 国产国语videosex另类| 高清一区二区三区四区五区| 日韩精品福利在线| 91干在线观看| 国产欧美日韩高清| 91精品久久久久久综合乱菊| 国产91在线视频| 国产主播精品在线| 欧美裸体男粗大视频在线观看| 亚洲精品美女在线观看播放| 懂色aⅴ精品一区二区三区蜜月| 欧美电影免费观看| 日韩免费观看高清| 国产一区二区三区毛片| 在线观看免费高清视频97| 国产成人涩涩涩视频在线观看| 欧美最顶级丰满的aⅴ艳星| 九九综合九九综合| 欧美性猛交视频| 亚洲精品国产精品国产自| 91精品国产免费久久久久久| 亚洲国产小视频| 成人黄色午夜影院| 久久亚洲精品网站| 久久久久国色av免费观看性色| 不卡av电影在线观看| 久久视频在线观看免费| 色综合久久悠悠| 一区二区三区视频在线| 在线视频欧美日韩| 亚洲国内精品视频| 91亚洲人电影| 欧美激情综合色综合啪啪五月| 欧美美女操人视频| 欧美在线一级视频| 国产日韩精品一区二区| 在线视频欧美日韩精品| 精品一区电影国产| 在线观看国产精品91| 中文字幕亚洲激情| 3344国产精品免费看| 欧美中文在线字幕| 欧美老妇交乱视频| 91高清视频免费观看| 久久免费在线观看| 精品呦交小u女在线| 日韩在线免费高清视频| 久久精品中文字幕电影| 色系列之999| 亚洲国产毛片完整版| 在线视频日本亚洲性| 亚洲欧美激情精品一区二区| 曰本色欧美视频在线| 日韩久久免费电影| 久久免费成人精品视频| 欧美日韩免费区域视频在线观看| 亚洲aⅴ男人的天堂在线观看| 午夜精品久久久久久久男人的天堂| 久久69精品久久久久久久电影好| 日韩美女视频免费看| 最好看的2019的中文字幕视频| 亚洲wwwav| 亚洲第一男人天堂| 欧美激情第一页xxx| 国产成人精品电影| 欧美激情奇米色| 欧美日韩国产成人在线观看| 国产欧美日韩中文| 欧美成人在线网站| 国产成人拍精品视频午夜网站| 欧美区二区三区|