Android基礎(chǔ)知識匯總

PS:以記筆記的方式栗恩,匯總一些android基礎(chǔ)知識男窟。

1势决、android 四種啟動模式
1步淹、standard 標(biāo)準(zhǔn)模式
2从隆、singleTop 棧頂復(fù)用模式诚撵,activity 不在棧頂時跟standard一樣,復(fù)用時調(diào)用onNewIntent()方法
3键闺、singleInstance  棧內(nèi)復(fù)用模式,復(fù)用時清除棧內(nèi)該Activity上層的所有Activity(clear top)寿烟,調(diào)用onNewIntent()方法
4、singleTask  獨自放在一個任務(wù)棧里面辛燥,相當(dāng)于自己就是一個應(yīng)用筛武,有自己的上下文activity
2、activity或fragment被系統(tǒng)銷毀時數(shù)據(jù)緩存
activity 緩存:    onSaveInstanceState()     和   onRestoreInstanceState()
fragment緩存:    onSaveInstanceState()     和   onViewStateRestored()

3挎塌、為什么在Service中創(chuàng)建子線程而不是再Activity中徘六?
因為Activity很難對Thread進行控制,當(dāng)Activity銷毀后就沒有任何辦法獲取之前創(chuàng)建的子線程的實例了榴都。然而Service就不一樣待锈,任何Activity都可以與之關(guān)聯(lián),又能獲取原有Service穿件的Bindle實例嘴高。從而更好的控制后臺任務(wù)竿音。
4、Service兩種啟動方法及區(qū)別
startService : activity啟動service之后拴驮,service并不和activity產(chǎn)生關(guān)聯(lián)
bindService : service和activity的context關(guān)聯(lián)并啟動春瞬,生命周期與context一致。
5套啤、廣播(BroadCast Receiver)的兩種注冊狀態(tài)(靜態(tài)注冊和動態(tài)注冊)
靜態(tài)注冊:在Manifest里面注冊快鱼,應(yīng)用退出后依然在工作
動態(tài)注冊:代碼中注冊,應(yīng)用退出后無法工作
6纲岭、如何保持Android進程不被殺死
1抹竹、1px Activity進程保活止潮,應(yīng)用退出后臺時啟動1像素的Activity窃判,占用內(nèi)存小,降低被回收的概率
2、提升Service 進程優(yōu)先級
3凄吏、onDestory的時候重啟service
7婶恼、android動畫
1、tween 補間動畫:通過制定View的初末狀態(tài)和變化時間唆樊、方式,對View的內(nèi)容完成一系列的變化方式來實現(xiàn)刻蟹。Alpha , Scale , Translate , Rotate 逗旁。
2、frame 幀動畫:AnimationDrawable 控制animation-list xml布局
3舆瘪、PropertyAnimation 屬性動畫
4片效、SVG矢量動畫
8红伦、自定義View 過程:onMeasure() onLayout() onDraw()
1、自定義屬性的聲明和獲鹊硪隆:
      a昙读、分析需要的自定義屬性
      b、在res/values/attr.xml定義聲明
      c膨桥、在layout文件中進行使用
      d蛮浑、在View的構(gòu)造方法中進行獲取
2、測量onMeasure
3只嚣、布局onLayout(ViewGroup)
4沮稚、繪制onDraw
5、onTouchEvent
6介牙、onInterceptTouchEvent(ViewGroup) :事件分發(fā)
7壮虫、狀態(tài)的恢復(fù)和保存
9、android事件分發(fā)機制
dispatchTouchEvent()
onFilterTouchEventForSecurity()  ( onInterceptTouchEvent())
onTouch()
onTouchEvent()
onClick()

View中的dispatchTouchEvent()方法源碼如下:
 public boolean dispatchTouchEvent(MotionEvent event) {
        // If the event should be handled by accessibility focus first
        ......
        boolean result = false;
         ......
        if (onFilterTouchEventForSecurity(event)) {
            if ((mViewFlags & ENABLED_MASK) == ENABLED && handleScrollBarDragging(event)) {
                result = true;
            }
            //noinspection SimplifiableIfStatement
            ListenerInfo li = mListenerInfo;
            if (li != null && li.mOnTouchListener != null
                    && (mViewFlags & ENABLED_MASK) == ENABLED
                    && li.mOnTouchListener.onTouch(this, event)) {
                result = true;
            }

            if (!result && onTouchEvent(event)) {
                result = true;
            }
        }
        ......
        return result;
    }

可以看到onFilterTouchEventSecurity() 為開關(guān)环础,并且當(dāng)onTouch()方法返回True時囚似,之后不會調(diào)用onTouchEvent()方法,并且進一步查看TextView的onTouchEvent()源碼可以看到里面調(diào)用了onClick()方法线得。

如下log可以看到調(diào)用的相關(guān)方法饶唤,推測出事件的傳遞機制:
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventLayout: dispatchTouchEvent: 1
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventLayout: onFilterTouchEventForSecurity: 
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventButton: dispatchTouchEvent: 1
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventButton: onFilterTouchEventForSecurity: 1
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventActivity: onTouch: 1
09-04 14:45:11.519 2998-2998/com.sleep.sunshine I/TestTouchEventButton: onTouchEvent: 1
09-04 14:45:11.521 2998-2998/com.sleep.sunshine I/TestTouchEventActivity: onClick: 
10、Handler消息機制
handler.png
Handler 
Looper :輪詢器贯钩,每個線程只能有一個Looper
MessageQueue:消息隊列募狂,儲存消息,先進先出
Message
11角雷、子線程中創(chuàng)建handler
1祸穷、方法1:利用子線程的Looper
 new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler(){
                    @Override
                    public void handleMessage(Message msg) {
                        super.handleMessage(msg);
                    }
                };
                handler.sendEmptyMessage(1);
                Looper.loop();
            }
        }).start();

2、方法2:獲取主線程的looper勺三,或者說是UI線程的looper
new Thread(new Runnable() {  
            public void run() {  
                Handler handler = new Handler(Looper.getMainLooper()){ // 區(qū)別在這@坠觥!B鸺帷祈远!  
                    @Override  
                    public void handleMessage(Message msg) {  
                        Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show();  
                    }  
                };  
                handler.sendEmptyMessage(1);  
            };  
        }).start();  
12、內(nèi)存泄漏
原因:生命周期長的對象持有生命周期短的對象的引用導(dǎo)致該對象不能及時回收商源,導(dǎo)致內(nèi)存泄漏车份。

容易導(dǎo)致內(nèi)存泄露的地方:
1、單例對象初始化時持有外部對象的引用(其他類或者context)
2牡彻、非靜態(tài)內(nèi)部類默認持有外部類的引用扫沼,這時候創(chuàng)建內(nèi)部類的靜態(tài)實例會造成內(nèi)存泄露
3、匿名內(nèi)部類和異步線程:匿名內(nèi)部類會持有外部類的引用
4、handler造成內(nèi)存泄漏:延時消息可能會導(dǎo)致handler與activity生命周期不一致充甚。(用弱引用)
5以政、cursor 霸褒、bitmap 伴找、broadcast 、soeket 废菱、stream 等及時關(guān)閉
handler弱引用示例:
private static class MyHandler extends Handler {
    private final WeakReference<SampleActivity> mActivity;

    public MyHandler(SampleActivity activity) {
      mActivity = new WeakReference<SampleActivity>(activity);
    }

    @Override
    public void handleMessage(Message msg) {
      SampleActivity activity = mActivity.get();
      if (activity != null) {
        // ...
      }
    }
  }

  private final MyHandler mHandler = new MyHandler(this);

  /**
   * Instances of anonymous classes do not hold an implicit
   * reference to their outer class when they are "static".
   */
  private static final Runnable sRunnable = new Runnable() {
      @Override
      public void run() { /* ... */ }
  };
13技矮、Android 性能優(yōu)化
1、合理管理內(nèi)存:
     a殊轴、節(jié)制使用service
     b衰倦、界面不可見時釋放內(nèi)存,bitmap不要加載不需要的分辨率等
     c旁理、少用依賴注入框架
2樊零、分析內(nèi)存使用情況,解決內(nèi)存泄露等問題:LeakCanary等工具
3孽文、高性能編碼驻襟,如:
      a、字符串拼接時用StringBuffer或者StringBuilder  ,少用String
      b芋哭、多用系統(tǒng)API
      c沉衣、ArrayList 遍歷傳統(tǒng)方式最快,數(shù)組等用增強for循環(huán)最快等
      d减牺、避免在內(nèi)部調(diào)用Getters/Setters方法
4豌习、布局優(yōu)化、避免復(fù)雜布局或者嵌套布局
14拔疚、取消Android TextView 內(nèi)邊距’
android:includeFontPadding=“false"
15肥隆、Android彈出軟鍵盤后點擊鍵盤外面關(guān)閉
@Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
            View v = getCurrentFocus();
            if (isShouldHideInput(v, ev)) {

                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
                }
            }
            return super.dispatchTouchEvent(ev);
        }
        // 必不可少,否則所有的組件都不會有TouchEvent了
        if (getWindow().superDispatchTouchEvent(ev)) {
            return true;
        }
        return onTouchEvent(ev);
    }

    public boolean isShouldHideInput(View v, MotionEvent event) {
        if (v != null && (v instanceof EditText)) {
            int[] leftTop = {0, 0};
            //獲取輸入框當(dāng)前的location位置
            v.getLocationInWindow(leftTop);
            int left = leftTop[0];
            int top = leftTop[1];
            int bottom = top + v.getHeight();
            int right = left + v.getWidth();
            if (event.getX() > left && event.getX() < right
                    && event.getY() > top && event.getY() < bottom) {
                // 點擊的是輸入框區(qū)域稚失,保留點擊EditText的事件
                return false;
            } else {
                //使EditText觸發(fā)一次失去焦點事件
                v.setFocusable(false);
//                v.setFocusable(true); //這里不需要是因為下面一句代碼會同時實現(xiàn)這個功能
                v.setFocusableInTouchMode(true);
                return true;
            }
        }
        return false;
    }
16栋艳、gson 解析List<T>
Gson gson = new Gson();
Type founderListType = new TypeToken<ArrayList<Founder>>(){}.getType();
List<Founder> founderList = gson.fromJson(founderJson, founderListType);
17、RecyclerView加載更多
 /**
     * 提前多少個item觸發(fā)加載更多
     */
    private int visibleThreshold = 2;

     recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    LinearLayoutManager layoutManager = (LinearLayoutManager)         recyclerView.getLayoutManager();
                    int itemCount = layoutManager.getItemCount();
                    int lastPosition = layoutManager.findLastVisibleItemPosition();
                    //如果當(dāng)前不是正在加載更多墩虹,并且到了該加載更多的位置嘱巾,加載更多。
                    if (!isLoading && (lastPosition >= (itemCount - visibleThreshold))) {
                        loadMore();
                    }
                }
            });
18诫钓、Android5.0水波紋效果ripple實現(xiàn)
// 波紋有邊界
android:background="?android:attr/selectableItemBackground"  
// 波紋超出邊界  
android:background="?android:attr/selectableItemBackgroundBorderless"  

<a />
19旬昭、混淆代碼后崩潰日志中不顯示行號的問題

原因是在混淆代碼時默認會去掉class文件中的調(diào)試信息(源碼的行號、源文件信息等)菌湃,需要在混淆配置文件中申明保持這些信息:

-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
20问拘、adb 命令和adb shell命令
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子骤坐,更是在濱河造成了極大的恐慌绪杏,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纽绍,死亡現(xiàn)場離奇詭異蕾久,居然都是意外死亡,警方通過查閱死者的電腦和手機拌夏,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進店門僧著,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人障簿,你說我怎么就攤上這事盹愚。” “怎么了站故?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵皆怕,是天一觀的道長。 經(jīng)常有香客問我西篓,道長愈腾,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任污淋,我火速辦了婚禮顶滩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘寸爆。我一直安慰自己礁鲁,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布赁豆。 她就那樣靜靜地躺著仅醇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪魔种。 梳的紋絲不亂的頭發(fā)上析二,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機與錄音节预,去河邊找鬼叶摄。 笑死,一個胖子當(dāng)著我的面吹牛安拟,可吹牛的內(nèi)容都是我干的蛤吓。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼糠赦,長吁一口氣:“原來是場噩夢啊……” “哼会傲!你這毒婦竟也來了锅棕?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤淌山,失蹤者是張志新(化名)和其女友劉穎裸燎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泼疑,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡德绿,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了王浴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片脆炎。...
    茶點故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡梅猿,死狀恐怖氓辣,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情袱蚓,我是刑警寧澤钞啸,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站喇潘,受9級特大地震影響体斩,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜颖低,卻給世界環(huán)境...
    茶點故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一絮吵、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧忱屑,春花似錦蹬敲、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至从铲,卻和暖如春瘪校,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背名段。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工阱扬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人伸辟。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓麻惶,卻偏偏與公主長得像,于是被迫代替她去往敵國和親自娩。 傳聞我的和親對象是個殘疾皇子用踩,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,654評論 2 354

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