Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> App的打磨之路(上)

App的打磨之路(上)

編輯:關於Android編程

前言:

俗話說磨刀不誤砍柴工,一個優秀的產品從一個不錯的點子直到用戶的手中,是需要一個團隊不遺余力協同合作不斷打磨出來的;同樣,一個好的App除正常的代碼編寫外,還需要經過其他方面的不斷打磨才能正式交互,最終到達用戶的手中。該文主要講述一個應用除開發外還需要進行哪些工作才能合格交互,在此拋磚引玉,希望對有需要的朋友一點啟示!
該文由於內容較多故分為三篇博文來描述,主要內容包含:單元測試、性能分析、簽名、混淆、APK瘦身、反編譯、打包及加固,下文主要描述前面三個:單元測試、性能分析及簽名。

一、單元測試

單元測試是編寫測試代碼,用來檢測特定的、明確的、細顆粒的功能。單元測試不僅僅用來保證當前代碼的正確性,更重要的是用來保證代碼修復、改進或重構之後的正確性。對於想打造優秀產品的碼農來說是必不可少的,雖然在大部分公司實現有居多困難。
一般來說,單元測試任務主要包括以下幾個方面:
1. 接口功能測試
主要用來保證接口功能的正確性。
2. 數據結構測試
主要用來保證接口中的數據結構的正確性,比如變量有無初始值,是否溢出等。
3. 邊界條件測試
邊界條件判定是單元測試中最常用的,在開發中也是最容易遇到的BUG,邊界條件判定的類型主要有以下幾種情形:
- 變量是對象:如對象是否為NULL等;
- 變量是數值:數值邊界:最小值、最大值、無窮小、無窮大,溢出邊界:最小值-1、最大值+1,臨近邊界:最小值+1、最大值-1;
- 變量是字符串:字符串是否為空,字符串的長度進行數值變量的判定;
- 變量是集合:集合是否為空,集合的大小進行數值變量的判定;
4. 獨立執行通路測試
主要保證代碼的覆蓋率,如語句覆蓋:保證每一條語句都執行到,分支覆蓋:保證每一個分支都執行到,條件覆蓋:保證每一個條件都覆蓋到true和false的情形,路徑覆蓋:保證每一個路徑都執行到;
5. 異常處理通路測試
主要保證所有的異常都經過測試。

JUnit是Java單元測試框架,已經在Android Studio中默認依賴。目前主流的有JUnit3和JUnit4。JUnit3中,測試用例需要繼承TestCase類。JUnit4中,測試用例無需繼承TestCase類,只需要使用@Test等注解。以下通過一個實例來更好的展示單元測試過程:
先在應用下建立一個計算工具類,方便寫單元測試:

package com.vise.note.util;

/**
 * 計算相關工具類
 * Created by xyy on 16/6/25.
 */
public class CalculatorUtil {
    public double plus(double a, double b){
        return a + b;
    }

    public double minus(double a, double b){
        return a - b;
    }

    public double multiply(double a, double b){
        return a * b;
    }

    public double divide(double a, double b) throws Exception {
        if(b == 0){
            throw new Exception("除數不能為零!");
        }
        return a / b;
    }

}

Android Studio提供了一個快速創建測試類的方法,只需在編輯器內右鍵點擊CalculatorTest類的聲明,選擇Go to > Test,然後點擊”Create a new test…”,到此會彈出兩個選項,一個是androidTest,一個是test目錄下,由於該測試不需要用到模擬器,可以運行在本地電腦Java虛擬機上,所以此處選擇test目錄下,隨後在test與應用同包的目錄下生成CalculatorUtilTest.java文件,內容如下(方法內部實現是手動添加的):

package com.vise.note.util;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.junit.Assert.*;

/**
 * Created by xyy on 16/6/25.
 */
public class CalculatorUtilTest {

    private CalculatorUtil calculatorUtil;

    @Before
    public void setUp() throws Exception {
        calculatorUtil = new CalculatorUtil();
    }

    @After
    public void tearDown() throws Exception {
        calculatorUtil = null;
    }

    @Test
    public void testPlus() throws Exception {
        assertEquals(6d, calculatorUtil.plus(1d, 5d), 0);
    }

    @Test
    public void testMinus() throws Exception {
        assertEquals(-4d, calculatorUtil.minus(1d, 5d), 0);
    }

    @Test
    public void testMultiply() throws Exception {
        assertEquals(5d, calculatorUtil.multiply(1d, 5d), 0);
    }

    @Test
    public void testDivide() throws Exception {
        assertEquals(0.2d, calculatorUtil.divide(1d, 5d), 0);
    }
}

最後就可以直接選擇CalculatorUtilTest直接運行了。到此,單元測試就告一段落了,下面是講述性能分析,這個也很重要哦!^_^

二、性能分析

1、Memory Monitor

在Android Studio中運行項目後,點擊Android Monitor中的Monitor就可以看到如下圖所示的Memory使用及CPU運行情況:
這裡寫圖片描述
下面還可以查看GPU和Network的相關情況,其中NetWZ喎?/kf/ware/vc/" target="_blank" class="keylink">vcmu1xMa1t7HKudPDysfU7LPJ06bTw7rEtee1xLnYvPyjrDcwJdfz09K1xLXnwb/Kx7G7yc+xqMr9vt2jrLzssunOu9bD0MXPoqOstqjKsbzsy/e688youeO45tDFz6LL+cq508O19LXEo6zI57rOxr264tauvOS1xMq508PSssrHutzW2NKqtcShozwvcD4NCjxoNSBpZD0="2heap-snapshot">2、Heap Snapshot

依據上面Memory Monitor描述,找到Memory中第三個圖標“Dump Java Heap”,每次點擊之後會生成一個.hprof的文件,點擊一個.hprof文件,查看右側的Analyzer Tasks,能看到兩個選項,一個是‘Detect Leaeked Activites’,另一個是’Find Duplicate Strings’,點擊右上角的綠色播放按鈕,會自動分析heap dump去定位洩露的activity和重復的string,出現如下的Analysis Results:
這裡寫圖片描述
這裡寫圖片描述
從上面兩幅圖中可以看出,第一個選項表示查看的信息可以有三種類型:App heap/Image heap/Zygote heap.分別代表App堆內存信息,圖片堆內存信息,Zygote進程的堆內存信息。還有一個選項可以選擇Class List View和Package Tree View兩種視圖展示方式。

各屬性中英文對照表

名稱 意義 Total Count 內存中該類的對象個數 Heap Count 堆內存中該類的對象個數 Sizeof 物理大小 Depth 深度 Shallow size 對象本身占有內存大小 Retained Size 釋放該對象後,節省的內存大小 Dominating Size 管轄的內存大小
3、LeakCanary
使用方法
在 build.gradle 中加入引用,不同的編譯使用不同的引用:
dependencies {
   debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3'
   releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3'
}

在 Application 中:

public class ExampleApplication extends Application {

  @Override public void onCreate() {
    super.onCreate();
    LeakCanary.install(this);
  }
}

應用運行起來後,LeakCanary會自動去分析當前的內存狀態,如果檢測到洩漏會發送到通知欄,點擊通知欄就可以跳轉到具體的洩漏分析頁面。

工作機制
1、RefWatcher.watch() 創建一個 KeyedWeakReference 到要被監控的對象。
2、然後在後台線程檢查引用是否被清除,如果沒有,調用GC。
3、如果引用還是未被清除,把 heap 內存 dump 到 APP 對應的文件系統中的一個 .hprof 文件中。
4、在另外一個進程中的 HeapAnalyzerService 有一個 HeapAnalyzer 使用HAHA 解析這個文件。
5、得益於唯一的 reference key, HeapAnalyzer 找到 KeyedWeakReference,定位內存洩露。
6、HeapAnalyzer 計算 到 GC roots 的最短強引用路徑,並確定是否是洩露。如果是的話,建立導致洩露的引用鏈。
7、引用鏈傳遞到 APP 進程中的 DisplayLeakService, 並以通知的形式展示出來。
更多關於LeakCanary的使用介紹請參考:LeakCanary 中文使用說明

注:以上都是針對Android Studio IDE的性能分析方式。

三、簽名

簽名的前提得有簽名文件,生成簽名文件的方式大同小異,IDE基本都有這個功能,這裡以Android Studio為列講述生成簽名文件的過程。選擇工具欄Build->Generate Signed APK,打開後選擇對應的module,點擊next,如圖所示:
這裡寫圖片描述
點擊Create new,進入如下界面:
這裡寫圖片描述

信息注釋
Key store path:簽名文件路徑
Password:簽名庫密碼
Confirm:確認簽名庫密碼
Alias:別名
Password:該別名下簽名密碼
Confirm:確認該別名下簽名密碼
Validity:認證年限
First and Last Name:你的全名
Organizational Unit:組織單位
Organization:組織
City or Locality:城市或地區
State or Province:川或省
Country Code:國家代碼

按照指示填寫對應信息,點擊OK就生成了簽名文件。
還一種方式是使用命令的方式創建,進入Java的bin目錄下,如我的Java目錄為:/Library/Java/Home/bin,通過keytool工具來創建keystore庫,輸入以下命令:

keytool -genkeypair -alias - xyy.keystore -keyalg RSA -validity 100 -keystore xyy.keystore
命令說明如下:
-genkeypair:指定生成數字證實
-alias:指定生成數字證書的別名
-keyalg:指定生成數字證書的算法  這裡如RSA算法
-validity:指定生成數字證書的有效期
-keystore :指定生成數字證書的存儲路徑(這裡默認在keytool目錄下)

再按照提示一步步輸入對應的信息,最後就生成了一個名為xyy.keystore的簽名文件。
有了簽名文件後,將簽名文件放到對應需要簽名的工程目錄module下,再在module對應的build文件中添加如下簽名信息(簽名信息對應輸入自己設置的秘鑰信息):

android{
    ...
    signingConfigs {
        debug {
            storeFile file("xyy.keystore")
            storePassword "xyy"
            keyAlias "Note"
            keyPassword "xyy"
        }

        release {
            storeFile file("xyy.keystore")
            storePassword "xyy"
            keyAlias "Note"
            keyPassword "xyy"
        }
    }

    buildTypes {
        debug {
            minifyEnabled false
            zipAlignEnabled true
            shrinkResources false
            signingConfig signingConfigs.debug
        }

        release {
            //是否混淆(注:如果混淆文件未配置使用false)
            minifyEnabled false
            //是否支持Zip Align
            zipAlignEnabled true
            //是否清理無用資源
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            //使用簽名配置
            signingConfig signingConfigs.release

        }
    }
    ...
}

這樣配置完後每次build工程生成的文件都會使用debug下的簽名信息了

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved