TraceView

Traceview 用來追蹤程式執行效能,主要可運用2種方式來產生效能分析圖(.trace)

A-1.使用插入code方式
在想分析的程式碼區塊插入Debug.startMethodTracing()及Debug.stopMethodTracing();
其中Debug.startMethodTracing()可指定分析圖檔名如Debug.startMethodTracing("trace_report"),在/sdcard會產生trace_report.trace檔

A-2.加入<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
否則A-1的方法會丟出Exception

A-3.執行程式

A-4.將產生的分析圖從/sdcard中複製到本機的資料夾中以方便查看,使用以下指令
./adb pull /sdcard/trace_report.trace /資料夾名稱

A-5.使用android-sdk tools的 traceview來開啟.trace檔,使用以下指令
android-sdk-linux/tools$ ./traceview /資料夾名稱/trace_report.trace

B-1.使用DDMS來產生分析圖,執行程式並切換到DDMS

B-2.點擊Start Method Profiling,開始分析

B-3.點擊Stop Method Profiling,結束分析

B-4.自動產生分析檔

以下提供簡單的分析範例,尋找程式效能熱點(HotPoint)
首先這是MainActivity
MainActivity.java
public class MainActivity extends Activity
{
   
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);      
        Debug.startMethodTracing("trace_report");
        TestString testStr = new TestString();
        Debug.stopMethodTracing();
    }

}
相當簡單,只專注在 TestString 物件的建立
接著是TestString
TestString.java
public class TestString
{
    private String mStr = new String();
   
    public TestString(){
        initStr();
    }
   
    private void initStr(){
        for(int i=0; i<10000; ++i){
            mStr = mStr.concat(""+i);
        }
    }
}
在initStr方法內為相當消耗效能的熱點,執行程式產生分析圖如下














在Incl cpu time 佔用 89.6% 為String.concat()方法,總共佔用了9.66秒,針對這裡來修改熱點
修改後的TestString.java如下
public class TestString
{
    private StringBuffer mStr = new StringBuffer();
   
    public TestString(){
        initStr();
    }
   
    private void initStr(){
        for(int i=0; i<10000; ++i){
            mStr = mStr.append(i);
        }
    }
}
採用StringBuffer取代原來的String,重新產生分析圖















可以看到StringBuffer.append()方法仍然為熱點(95.7%),佔用時間卻降到了0.73秒


XmlParser

網路上一堆範例不如自己作一遍還來的了解
直接切入主題,這裡使用DOM來轉換xml,以步驟來說明

Step1.
首先要有xml檔放到assets資料夾中,為了方便整理在assets 資料夾中另外開了一個xmlfiles資料夾,路徑如下

Project/assets/xmlfiles/command_simple_formatter.xml
<?xml version="1.0" encoding="utf-8"?>
<commands>
    <command
        id="1"
        enable="true"
        function_name="function1"
        type="FLOAT" />
    <command
        id="2"
        enable="false"
        function_name="function2"
        type="FIXED" />
</commands>

Step2.
接著建立對應的資料結構,根據xml中的tag來建立

Command.java
public class Command
{
    private int mIndex;
    private String mFunction;
    private boolean mEnable;
    private Type mType;
 
    public enum Type {
        FIXED, FLOAT
    }
 
    public void setType(Type type){
        mType = type;
    }
 
    public Type getType(){
        return mType;
    }
 
    public void setIndex(int index)
    {
        mIndex = index;
    }

    public void setFunction(String function)
    {
        mFunction = function;
    }

    public int getIndex()
    {
        return mIndex;
    }

    public String getFunction()
    {
        return mFunction;
    }
 
    public boolean getEnable(){
        return mEnable;
    }
 
    public void setEnable(boolean enable){
        mEnable = enable;
    }
}

Step3.
接著開始撰寫轉換的本體,這裡我帶入Template Method,
XmlParser.java
public abstract class XmlParser
{
    private Context mContext;

    public XmlParser(Context context) {
        mContext = context;
    }

    public final List<?> parserProcess(String xmlFileName)
    {
        Document document = prepareParseComponent(xmlFileName);
        Element root = getXmlBasicRootElement(document);
        List<?> javaDatas = parseXmlContentToJavaObjects(root);

        return javaDatas;
    }
 
    private Document prepareParseComponent(String xmlFileName)
    {
        DocumentBuilder documentBuilder = getDocumentBuilder();
        InputStream inputStream = getXmlInputStream(xmlFileName);
        Document document = null;
        try {
            document = documentBuilder.parse(inputStream);
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return document;
    }

    protected abstract List<?> parseXmlContentToJavaObjects(Element root);
 
    private DocumentBuilder getDocumentBuilder()
    {
        DocumentBuilder documentBuilder = null;
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        try {
            documentBuilder = builderFactory.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }

        return documentBuilder;
    }

    /**
     *
     * @param xmlFileName : xml file need put in assets folder
     * @return InputStream
     */
    private InputStream getXmlInputStream(String xmlFileName)
    {
        AssetManager assetManager = mContext.getAssets();
        InputStream inputStream = null;
        try {
            inputStream = assetManager.open(xmlFileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return inputStream;
    }

    private Element getXmlBasicRootElement(Document document)
    {
        Element root = document.getDocumentElement();
        return root;
    }
}

Step4.
建立繼承XmlParser的類別,主要複寫parseXmlContentToJavaObjects方法
CommandSimpelXmlParser.java
public class CommandSimpleXmlParser extends XmlParser
{
    private String mElementName = "command";
    private String mId = "id";
    private String mFunctionName = "function_name";
    private String mEnable = "enable";
    private String mType = "type";
 
    public CommandSimpleXmlParser(Context context) {
        super(context);
    }

    @Override
    protected List<Command> parseXmlContentToJavaObjects(Element root)
    {
        NodeList commandNode = root.getElementsByTagName(mElementName);
        int commandsNodeSize = commandNode.getLength();
        return transXmlToCommand(commandNode,commandsNodeSize);
    }
 
    private List<Command> transXmlToCommand(NodeList nodeList,int size){
        List<Command> result = new ArrayList<Command>();
        for (int i = 0; i < size; ++i) {
            Command command = new Command();
            Element commandElement = (Element) nodeList.item(i);
            command.setIndex(transXmlIdTagToCommand(
                    commandElement, mId));
            command.setFunction(transXmlFunctionNameTagToCommand(
                    commandElement, mFunctionName));
            command.setEnable(transXmlEnableTagToCommand(
                    commandElement, mEnable));
            command.setUIType(trnasXmlTypeToCommand(
                    commandElement, mType));
            result.add(command);
            command = null;
        }
        return result;
    }
 
    private UIType trnasXmlTypeToCommand(Element element,String type){
        return Command.Type.valueOf(element.getAttribute(type));
    }
 
    private int transXmlIdTagToCommand(Element element,String id){
        return Integer.valueOf(element.getAttribute(id));
    }
 
    private String transXmlFunctionNameTagToCommand(Element element,String functionName){
        return element.getAttribute(functionName);
    }
 
    private boolean transXmlEnableTagToCommand(Element element,String enable){
        return Boolean.valueOf(element.getAttribute(enable));
    }
}

Step5.
使用轉換
XmlParserMainActivity.java
public class XmlParserMainActivity extends Activity
{
    private static final String TAG = "XmlParserMainActivity";
    private static final String COMMAND_SIMPLE_XML_FILE_PATH = "xmlfiles/command_simple_formatter.xml";
 
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        examParseSimpleXml(COMMAND_SIMPLE_XML_FILE_PATH);
    }

    private void examParseSimpleXml(String xmlFilePath)
    {
        XmlParser simpleCommandXmlParser = new CommandSimpleXmlParser(this);
        List<Command> commands = (List<Command>) simpleCommandXmlParser
                .parserProcess(xmlFilePath);
    }

}

Twitter Delicious Facebook Digg Stumbleupon Favorites More

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Affiliate Network Reviews