Android 面試題及答案(2)

来源:http://www.cnblogs.com/deman/archive/2016/09/25/5897069.html
-Advertisement-
Play Games

1.Activity相關。launchmode,OnSaveInstnceState,生命周期等。 4種預設的launchmode,以及OnNewIntent的回調。 OnNewIntent->OnRestart->OnStart->onResume OnActivity->OnResume. On ...


1.Activity相關。launchmode,OnSaveInstnceState,生命周期等。

 4種預設的launchmode,以及OnNewIntent的回調。

OnNewIntent->OnRestart->OnStart->onResume

OnActivity->OnResume.

OnNewIntent ,OnActivityResult?

OnNewIntent launchmode with singletask or singleInstance.

but if set these two mode. OnActivityResult will be called after startActivityforResult directly。

so normally,they can not called both.

OnSaveInstanceState:

在Activity這個方法的地方有一段描述:當activity將要被kill的時候,系統會開放這個藉口供程式員調用

然後它會把bundle信息傳遞到OnCreate & Bundle裡面。

這個方法一定會在OnStop之前被調用,but 與OnPause的順序無法確定。

某些情況下,生命周期不會走到OnDestroy,但是有些資源需要釋放。這時候,最好是事件驅動。

2.Fragment相關技術。

Fragment 的生命周期:Android四大組件之Activity & Fragement

Fragment和activity溝通,

fragmentmaneger.findFragmentById

fragmentmaneger.findFragmentByTag,

fragment之間的溝通,setArgument。

getActivity & addlistener等。

數據存儲和恢復。onSaveInstanceState:Fragment的該func同Activity同步。

FragmentTransaction transaction = fm.benginTransatcion();//開啟一個事務

transaction.add() 

往Activity中添加一個Fragment

transaction.remove()

從Activity中移除一個Fragment,如果被移除的Fragment沒有添加到回退棧(回退棧後面會詳細說),這個Fragment實例將會被銷毀。

transaction.replace()

使用另一個Fragment替換當前的,實際上就是remove()然後add()的合體~

transaction.hide()

隱藏當前的Fragment,僅僅是設為不可見,並不會銷毀

transaction.show()

顯示之前隱藏的Fragment

detach()

會將view從UI中移除,和remove()不同,此時fragment的狀態依然由FragmentManager維護。

attach()

重建view視圖,附加到UI上並顯示。

transatcion.commit()//提交一個事務

註意:常用Fragment的哥們,可能會經常遇到這樣Activity狀態不一致:State loss這樣的錯誤。主要是因為:commit方法一定要在Activity.onSaveInstance()之前調用。

上述,基本是操作Fragment的所有的方式了,在一個事務開啟到提交可以進行多個的添加、移除、替換等操作。

值得註意的是:如果你喜歡使用Fragment,一定要清楚這些方法,哪個會銷毀視圖,哪個會銷毀實例,哪個僅僅只是隱藏,這樣才能更好的使用它們。

其他問題:Android Fragment 真正的完全解析(下)

 FragmentTransaction.addToBackStack(String):如果是replace的方法,那麼當前fragment會被remove掉,所有back的時候,fragment的狀態不會保留,只會重新

創建。而如果是hide & add的方法,就會把之前的fragment重新attch上。

如果activity管理fragment,可以調用fragment的所有public方法。

可以通過findfragmentbyid & findfragmentbytag來定位fragment,然後同上。

fragment可以通過getactivity獲得實例。 

當屏幕旋轉是,fragment會被重覆創建,這是時候如果使用OnCreate的bundle參數,就可以判斷是否是第一次創建。

activity的預設實現bundle參數是有內容的。

3.序列化技術,Parcable & Serializable.

android 進程間通信數據(一)------parcel的起源

為什麼要序列化:為了跨進程通信,應為進程間通信就是二進位格式,所以序列化可以通過反序列化,把數據還原。

parcable是記憶體機的序列化,所以速度快。

4.fastJson & GSon的使用

package com.joyfulmath.publibrary.json;

import com.alibaba.fastjson.JSON;
import com.joyfulmath.publicutils.utils.TraceLog;

/**
 * @author deman.lu
 * @version on 2016-03-24 17:20
 * 使用fastjson 來解析該問題
 */
public class JsonUtils {

    public static <T> T parseObject(String jsonStr, Class<T> entityClass)
    {
        T ret  = null;
        try {
            ret = JSON.parseObject(jsonStr,entityClass);
        }catch (Exception e)
        {
            TraceLog.e("parseObject-something Exception with:" + e.toString());
        }

        return ret;
    }

    public static String toJSONString(Object obj) {
        String ret = null;

        try {
            ret = JSON.toJSONString(obj);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return ret;
    }
}
fastJson

 

5.多線程相關,包括handler,message looper. ExecutorService.

消息機制:android 進程/線程管理(一)----消息機制的框架 請看這個系列。

ExecutorService:線程池,可以提供關閉操作,等待關閉和直接關閉。

6.ImageLoader 原理,包括Glide,picasso,以及Fresco.

Picasso,square公司出品的圖片載入器,內部使用OKHttp執行網路請求。

可以支持URL,FILE,資料庫等路徑的載入。圖片不會縮放,

Picasso & Glide

首先Glide是基於Picasso的二次開發

with參數:Glide可以使用Activity、fragment等。所以它的載入可以和actiivty的生命周期綁定。

Glide預設圖片ARGB_565 piocasso:ARGB_8888

Glide loading Gif but Picasso cannot. but Glide will using much memory with gif.

Glide will cache with size of imageview, so each size of imageview will contains one copy.

Picasso will only has one cahce copy with fullsize. so glide is faster than picasso.

Glide 有助於減少OOM的發生。

/**
 * Created by deman on 2016/3/30.
 */
public interface IImageLoader {
    void initLoader(Context context);
    void load(String path, ImageView view, int width, int height);
    void load(String path, ImageView view);
}
IImageLoader
public class ImageLoadManger {
    private IImageLoader iImageLoader = null;

    private static ImageLoadManger sInstance = null;

    public static synchronized ImageLoadManger getsInstance() {

        if (sInstance == null) {
            sInstance = new ImageLoadManger();
        }
        return sInstance;
    }

    /**
     *  initManager
     * @param context context
     */
    public void initManager(Context context) {
        iImageLoader = new PicassoImageLoader();
        iImageLoader.initLoader(context);
    }

    /**
     * load image with path
     * @param path          path
     * @param imageView imageView
     */
    public void load(String path, ImageView imageView) {

        if(null == iImageLoader)
        {
            throw new RuntimeException("initManager has not been init");
        }
        iImageLoader.load(path, imageView);
    }

    /**
     * load image with path
     * @param path                  path
     * @param imageView         imageView
     * @param width                 width
     * @param height                height
     */
    public void load(String path, ImageView imageView,int width,int height) {
        if(null == iImageLoader)
        {
            throw new RuntimeException("initManager has not been init");
        }
        iImageLoader.load(path, imageView,width,height);
    }
}
ImageLoadManger
public class PicassoImageLoader implements IImageLoader {

    Picasso picasso;
    Context context;

    private void init()
    {
        picasso = new Picasso.Builder(context).build();
    }

    @Override
    public void initLoader(Context context) {
        this.context = context;
        init();
    }

    @Override
    public void load(String path, ImageView view,int width,int height)
    {
        if(null == path)
        {
            throw new RuntimeException("uri is null!");
        }

        if(width == 0 || height == 0)
        {
            throw new RuntimeException("width & height is 0");
        }

        picasso.load(path)
                .resize(width, height)
                .into(view);
    }

    @Override
    public void load(String path, ImageView view) {
        if(null == path)
        {
            throw new RuntimeException("uri is null!");
        }

        picasso.load(path)
                .into(view);
    }
}
PicassoImageLoader

Glide 500K,Picasso 100K

Fresco,是facebook開源的一套圖片載入框架。它的使用是基於view級別的。SimpleDraweeView

Fresco, image pipline技術,三級緩存。所以不容易oom。

第一層。bitmap緩存:在5.0上,使用java heap,5.0一下,使用ashme記憶體,減少GC發生的概率。

app到後臺,bitmap緩存被清空。

第二層,記憶體緩存。存放原始的壓縮圖片。

第三層,磁碟緩存,不會被清空。

Fresco對記憶體的節省效果很大,尤其是低端機,可以減少OOM的幾率。

包比較大,而且使用起來也複雜。

7.Adapter 和 ListView 組合。

 

8.用戶Cookie設計。token的流程包括登陸流程。

 登陸設計:

1)登陸跳轉

首先是登陸到指定頁面,比如MainActivity,

還有就是登陸後,回到上一頁。

這2中需要在登陸的時候考慮到。

2)登陸的密碼驗證

密碼加密後傳輸,以參數的形式。

API使用https請求。

登陸成功後,需要把userinfo存到本地,以便退出後,可以自動登陸。

3)自動登陸

token機制。每次登陸成功後,本地保存一個token信息,同時token可以保存過期的信息機制。

token過期後,所有先關API(需要驗證token信息的),都會返回相同的code信息,然後統一處理。

彈出AlertDialog,讓用戶去判斷是否需要登陸。

9.網路請求的封裝。

Volley

Volley+okhttp

Retrofit

其中Retrofit+okHttp+Picasso 是square公司統一齣品的。

主流的套路是,把每個框架都分開了,這樣便於替換。

Retrofit+okHttp /Volley+Okhttp   add  fastjson , Glide/Fresco + buttnkinfe/dragger2/androidannotation + Rebotim.

Android 框架學習之 第一天 okhttp & Retrofit

10.Android & H5 的交互。

H5調用andoriod代碼:

webSettings.setJavaScriptEnabled(true);

mWebView.addJavascriptInterface(new DemoJavaScriptInterface(), "demo");

js回調,@JavascriptInterface

android 調用JS

mWebView.loadUrl("javascript:wave()");

跳轉協議:

當JS回調的時候,可以在shouldOverrideUrlLoading的時候

把URL配置成一個協議。

 

11.代碼混淆。

 混淆的開啟:androidstudio:

在gradle裡面,有

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

關鍵是minifyEnabled 編程true,混淆編譯就會打開。

一般需要配置proguard-rules.pro

proguard4大過程:

壓縮,位元組碼優化,混淆,預檢。

proguard 可以配置版本:

proguard在sdk裡面。

proguard可以配置過程:

-dontshrink 不壓縮輸入的類文件

-dontoptimize 不優化輸入的類文件

-dontobfuscate 不混淆輸入的類文件

12.android打包機制

包括sdk的命令。

Android原理揭秘之APk生成過程

打包過程:aapt用來生成資源文件R.java

java編譯器->class文件,然後dex編譯成.dex文件。

aapt放置的resource

打包成apk文件。

其他的最終會生成dex文件。+sign 過程,就是APK,當然可能需要壓縮優化。

13.線上Crash分析並修複的能力。

首先是,對於沒有處理的crash地方,通過UnCaughtExceptionHandler 來處理和收集日誌。

三步:

收集日誌併發送到伺服器

提示用戶處理

保存到SD

需要把proguardmapping文件保存下來,以便線上app分析問題。

14.記憶體泄露,包括記憶體優化,記憶體泄露的場景,以及MAT工具的使用。

 請參見Android 高級面試題及答案

 

15.Monkey機制。 Android開發如何對一款App進行monkey測試。

monkey就是對屏幕進行隨機事件發送,一般次數都在1W次以上,主要測試結果是crash,ANR的事件。

monkey對象是apk

monkey的事件流是隨機的。

monkey的文檔:http://developer.android.com/guide/developing/tools/monkey.html

16.調試工具,包括DDMS,android studio的調試功能。

androidstudio工具:

AndroidMonitor:StartMethodTracing 測試method執行時間。

DDMS也有traceView,功能是一樣的。

測試View的佈局:hierachyviewer.

debug:高級調試功能:

Evaluate Expression:在run菜單下麵,有這個選項,它的功能同watch差不多,但是它可以測試執行語句。

條件斷點:在迴圈裡面,你只對i=9感興趣,你怎麼辦,在斷點的位置,右擊,出現條件。

日誌斷點:也是一個非常實用的技能,當我們某些情況下需要列印日誌,但是每次編譯非常耗時,這個時候,我們實用日誌斷點,可以列印日誌,而

不修改源代碼。在Debug視窗裡面的console裡面可以看到列印的日誌。

方法斷點:方法斷點就是在函數名的這一樣,斷點,它會在函數入口和結束的地方斷點。

異常斷點:就是Run->View blockpoint->javaException.

屬性斷點:就是在某個屬性被修改或者訪問的時候,但是多線程複雜環境下,很難發現。Run->View blockpoint->javaFieldWatchpoints.

DDMS:Android Studio中怎麼使用DDMS工具?

17.單元測試,Junit的使用,包括其他測試框架。

 

public class ExampleTest extends InstrumentationTestCase {

    public void test() throws Exception {
        final int expected = 1;
        final int reality = 1;
        assertEquals(expected, reality);
    }

    public void test_2() throws Exception{
        final int expected = 2;
        final int reality = 3;
        assertEquals(expected,reality);
    }
}

需要在configration裡面配置。

18.GIT的高級功能,Stage,rebase,revert,stash,cherry pick & sub module

stage是index區, 一個概念,對應work區 和history區

revert:就是把某次歷史提交給取消掉,but它的提交記錄會被保留,也就是可以提交到遠程庫。

reset:只是回退歷史,回退內容可以被保留在work區域。

cherry pick:branch2 上的某條修改,需要merge到branch3上,but我只是需要這一條修改,用這條指令。

sub module:用處不是很大。

19.插件化編程。

專開一篇講解

20.設計模式,對常見設計模式的熟悉程度。

 TBD.

21.熱修複技術。

 TBD.

22.React +Native框架

TBD.

23.消息推送原理

 TBD.


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 禮物說仿寫(updating...) 源碼下載:http://code.662p.com/view/14507.html api: 禮物說 首頁精選 banner2: http://api.liwushuo.com/v2/secondary_banners?gender=1&generation=2 ...
  • 1 Data 執行時要操作的數據 在目標<data/>標簽中包含了以下幾種子元素,他們定義了url的匹配規則: android:scheme 匹配url中的首碼,除了“http”、“https”、“tel”...之外,我們可以定義自己的首碼 android:host 匹配url中的主機名部分,如“g ...
  • ...
  • 本文地址:http://www.cnblogs.com/wuyudong/p/5906735.html,轉載請註明源地址。 本文將實現標題欄下麵的textview中的文字跑馬燈的效果,就是將一行文字水平迴圈滾動,效果如下: 實現代碼如下: 如果其他地方也需要這樣的跑馬燈效果,複製代碼比較麻煩。這裡使 ...
  • 很多應用都會在界面中使用某種列表控制項:用戶可以選中、刪除或重新排列列表中的項目。這些控制項其實都是UITableView 對象,可以用來顯示一組對象,例如,用戶地址薄中的一組人名。 UITableView 對象雖然只能顯示一行數據,但是沒有行數限制。 編寫新的應用程式 JXHomepwner 應用 創 ...
  • 本文實現當從splash界面進入hone界面的時候,產生一種漸進淡入的動畫效果,在onCreate中調用一個方法initAnimation(),代碼如下: 其中rl_root在類中定義 private RelativeLayout rl_root; 其中rl_root為splash界面相對佈局的id ...
  • 開發中經常需要使用Shape和Selector,如果每個都用xml設置的話,會占用apk大小,同時命名多了也會混亂,使用代碼來設置會方便很多。 需要用到2個類:GradientDrawable和StateListDrawable 相關API: setColor(rgb); //填充顏色setGrad ...
  • 使用巨集的目的是什麼? 由於實際開發中,有時候一些設置信息需要重覆使用(例如設置列印信息、配置顏色、配置寬度等),如果每次都手動去敲每次都去創建會很麻煩。雖然巨集使用的時候會占用記憶體,可是目前來說大部分開發者都在使用。 1.創建PCH 文件 2.打開配置面板 按照下圖操作 3.按照下圖找到相關配置 4. ...
一周排行
    -Advertisement-
    Play Games
  • 前言 本文介紹一款使用 C# 與 WPF 開發的音頻播放器,其界面簡潔大方,操作體驗流暢。該播放器支持多種音頻格式(如 MP4、WMA、OGG、FLAC 等),並具備標記、實時歌詞顯示等功能。 另外,還支持換膚及多語言(中英文)切換。核心音頻處理採用 FFmpeg 組件,獲得了廣泛認可,目前 Git ...
  • OAuth2.0授權驗證-gitee授權碼模式 本文主要介紹如何筆者自己是如何使用gitee提供的OAuth2.0協議完成授權驗證並登錄到自己的系統,完整模式如圖 1、創建應用 打開gitee個人中心->第三方應用->創建應用 創建應用後在我的應用界面,查看已創建應用的Client ID和Clien ...
  • 解決了這個問題:《winForm下,fastReport.net 從.net framework 升級到.net5遇到的錯誤“Operation is not supported on this platform.”》 本文內容轉載自:https://www.fcnsoft.com/Home/Sho ...
  • 國內文章 WPF 從裸 Win 32 的 WM_Pointer 消息獲取觸摸點繪製筆跡 https://www.cnblogs.com/lindexi/p/18390983 本文將告訴大家如何在 WPF 裡面,接收裸 Win 32 的 WM_Pointer 消息,從消息裡面獲取觸摸點信息,使用觸摸點 ...
  • 前言 給大家推薦一個專為新零售快消行業打造了一套高效的進銷存管理系統。 系統不僅具備強大的庫存管理功能,還集成了高性能的輕量級 POS 解決方案,確保頁面載入速度極快,提供良好的用戶體驗。 項目介紹 Dorisoy.POS 是一款基於 .NET 7 和 Angular 4 開發的新零售快消進銷存管理 ...
  • ABP CLI常用的代碼分享 一、確保環境配置正確 安裝.NET CLI: ABP CLI是基於.NET Core或.NET 5/6/7等更高版本構建的,因此首先需要在你的開發環境中安裝.NET CLI。這可以通過訪問Microsoft官網下載並安裝相應版本的.NET SDK來實現。 安裝ABP ...
  • 問題 問題是這樣的:第三方的webapi,需要先調用登陸介面獲取Cookie,訪問其它介面時攜帶Cookie信息。 但使用HttpClient類調用登陸介面,返回的Headers中沒有找到Cookie信息。 分析 首先,使用Postman測試該登陸介面,正常返回Cookie信息,說明是HttpCli ...
  • 國內文章 關於.NET在中國為什麼工資低的分析 https://www.cnblogs.com/thinkingmore/p/18406244 .NET在中國開發者的薪資偏低,主要因市場需求、技術棧選擇和企業文化等因素所致。歷史上,.NET曾因微軟的閉源策略發展受限,儘管後來推出了跨平臺的.NET ...
  • 在WPF開發應用中,動畫不僅可以引起用戶的註意與興趣,而且還使軟體更加便於使用。前面幾篇文章講解了畫筆(Brush),形狀(Shape),幾何圖形(Geometry),變換(Transform)等相關內容,今天繼續講解動畫相關內容和知識點,僅供學習分享使用,如有不足之處,還請指正。 ...
  • 什麼是委托? 委托可以說是把一個方法代入另一個方法執行,相當於指向函數的指針;事件就相當於保存委托的數組; 1.實例化委托的方式: 方式1:通過new創建實例: public delegate void ShowDelegate(); 或者 public delegate string ShowDe ...