1. 程式人生 > >android開發之記憶體CPU監控

android開發之記憶體CPU監控

cpu,記憶體監控作為android效能測試的一部分,在日常工作中使用也比較頻繁,一般測試人員都是直接adb命令輸出結果或者android studio上檢視記憶體,Cpu的趨勢,再深入一點就是效能分析定位了。由於本人水平有限,就先分享個android apk 監控指定應用的cpu和記憶體。先附上兩張效果圖:



原理如下

輸入需要監控的應用包名,輸入監控的間隔時間,輸入監控的總時間,點選監控就會執行監控命令,點選監控統計會在圖示顯示各項引數的最大值,最小值,平局值。點選監控詳情會跳轉到新的介面,展示詳細的監控引數

程式碼如下

1.先在manifest檔案加上如下許可權

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
2.MainActivity程式碼如下
package com.example.monitor;

import android.content.Intent;
import android.os.CountDownTimer;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MainActivity extends AppCompatActivity {
    EditText editText_times,editText_min,editText_package;
    Button button_top,button_reporte,cpu_btn,start_app,start_time;
    TextView countDown,cpu_max,cpu_min,cpu_ave,rss_max,rss_min,rss_ave,vss_max,vss_min,vss_ave;
    TextView total_time,wait_time,completa_time;
    FileUtils fu=new FileUtils();
    List cpu,rss,vss=new ArrayList<String>();

    ListUtils lu=new ListUtils();

    private Handler handler = new Handler();
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
   //監控詳情按鈕,點選後通過intent傳值到新的activity
        cpu_btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                try {
                    cpu= fu.readcpu("/mnt/sdcard/topInfo.txt",editText_package);
                    rss= fu.readrss("/mnt/sdcard/topInfo.txt",editText_package);
                    vss=fu.readvss("/mnt/sdcard/topInfo.txt",editText_package);

                    String times=fu.read("/mnt/sdcard/totime.csv");
                    String totalTime=fu.read("/mnt/sdcard/totaltime.csv");

                    Intent intent = new Intent(MainActivity.this,TopDetailActivity.class);



                    intent.putExtra("times",times);
                    intent.putExtra("totalTime",totalTime);

                    intent.putStringArrayListExtra("cpu", (ArrayList) cpu);//key就是自己定義一個String的字串就行了
                    intent.putStringArrayListExtra("vss", (ArrayList) vss);
                    intent.putStringArrayListExtra("rss", (ArrayList) rss);
                    startActivity(intent);
                } catch (Exception e) {
                    Toast toast=Toast.makeText(MainActivity.this, "監控檔案被刪除", Toast.LENGTH_SHORT);
                    toast.show();
                }
            }
        });


//監控報告按鈕
        button_reporte.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                new Thread() {
                    @Override
                    public void run() {//在run()方法實現業務邏輯;
                        //...

                        //更新UI操作;
                        handler.post(new Runnable() {
                            @Override
                            public void run() {
                                List<String>str_cpu= null;
                                List<String>str_vss= null;
                                List<String>str_rss= null;
                                try {
                                    str_cpu = fu.readcpu("/mnt/sdcard/topInfo.txt",editText_package);
                                    str_rss=fu.readrss("/mnt/sdcard/topInfo.txt",editText_package);
                                    str_vss=fu.readvss("/mnt/sdcard/topInfo.txt",editText_package);

                                    List cpu_info=lu.StrToInt(str_cpu);
                                    List rss_info=lu.StrToInt(str_rss);
                                    List vss_info=lu.StrToInt(str_vss);
                                    double ave=lu.listAverage(cpu_info);
                                    double ave1=lu.listAverage(rss_info);
                                    double ave2=lu.listAverage(vss_info);


                                    Log.i("cpuinfo", Collections.max(str_cpu));
                                    Log.i("cpuinfo", Collections.min(str_cpu));
                                    Log.i("cpuinfo", cpu_info+"");
                                    Log.i("cpuinfo", ave+"");
                                    cpu_max.setText(Collections.max(str_cpu)+"%");
                                    cpu_min.setText(Collections.min(str_cpu)+"%");
                                    cpu_ave.setText(ave+"%");

                                    rss_max.setText(Collections.max(str_rss)+"K");
                                    rss_min.setText(Collections.min(str_rss)+"K");
                                    rss_ave.setText(ave1+"K");

                                    vss_max.setText(Collections.max(str_vss)+"K");
                                    vss_min.setText(Collections.min(str_vss)+"K");
                                    vss_ave.setText(ave2+"K");


                                } catch (IOException e) {
                                    Toast toast=Toast.makeText(MainActivity.this, "監控失敗", Toast.LENGTH_SHORT);
                                    toast.show();
                                }catch (NoSuchElementException elementException){
                                    Toast toast=Toast.makeText(MainActivity.this, "監控應用未啟動", Toast.LENGTH_SHORT);
                                    toast.show();
                                }
                            }
                        });

                    }
                }.start();
            }
        });

        //監控按鈕
        button_top.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                if(editText_times.getText().toString().equals("")||editText_min.getText().toString().equals("")){
                    Toast toast=Toast.makeText(MainActivity.this, "監控總時間和監控時間是必填引數", Toast.LENGTH_SHORT);
                    toast.show();
                }
                else{
                    String total=editText_min.getText().toString();


                    threadpool(5);
                    //timer.start();
                    int totalTime=Integer.parseInt(total);
                    new CountDownTimer(totalTime*1000*60, 1000) {

                        @Override
                        public void onTick(long millisUntilFinished) {
                            button_top.setEnabled(false);
                            button_top.setText("監控中");
                            countDown.setText((millisUntilFinished/1000)+"S");
                        }

                        @Override
                        public void onFinish() {
                            button_top.setEnabled(true);
                            button_top.setText("啟動監控");
                            countDown.setEnabled(true);
                            countDown.setText("ok");
                        }
                    }.start();
                }


            }
        });


    }

    private void initView() {
        editText_min=(EditText) findViewById(R.id.ed_topmin);
        editText_times=(EditText)findViewById(R.id.ed_toptimes);
        editText_package=(EditText)findViewById(R.id.ed_package);
        button_top=(Button)findViewById(R.id.button_topbegin);
        button_reporte=(Button) findViewById(R.id.button_reporte);
        cpu_btn=(Button)findViewById(R.id.cpu_btn);



        countDown=(TextView)findViewById(R.id.timer);
        cpu_max=(TextView)findViewById(R.id.cpu_max);
        cpu_min=(TextView)findViewById(R.id.cpu_min);
        cpu_ave=(TextView) findViewById(R.id.cpu_ave);
        rss_max=(TextView) findViewById(R.id.rss_max);
        rss_min=(TextView)findViewById(R.id.rss_min);
        rss_ave=(TextView) findViewById(R.id.rss_ave);

        vss_max=(TextView) findViewById(R.id.vss_max);
        vss_min=(TextView) findViewById(R.id.vss_min);
        vss_ave=(TextView)findViewById(R.id.vss_ave);

    }

    public void threadpool(int case_num) {
        ExecutorService cacheThreadPool = Executors.newFixedThreadPool(5);
        if (case_num == 5) {
            cacheThreadPool.execute(new Runnable() {
                // final int index =1;
                @Override
                public void run() {
                    // String times=editText_times.getText().toString();
                    String times = editText_times.getText().toString();
                    //監控間隔時間
                    int times_num = Integer.parseInt(times);
                    String min = editText_min.getText().toString();
                    //監控總時間
                    int min_num = Integer.parseInt(min);
                    //次數
                    int n = min_num * 60 / times_num;

                    //如果監控檔案不存在則建立檔案
                    if (fu.topfileIsExists("/mnt/sdcard/totaltime.csv") == false) {
                        ShellUtils.execCommand("touch /mnt/sdcard/totaltime.csv", true);
                    }
                    if (fu.topfileIsExists("/mnt/sdcard/totime.csv") == false) {
                        ShellUtils.execCommand("touch /mnt/sdcard/totime.csv", false);
                    }

                    fu.writeTofile("/mnt/sdcard/totaltime.csv", min);
                    fu.writeTofile("/mnt/sdcard/totime.csv", times);
                    ShellUtils.execCommand("top -m 5 -d " + times + " -n " + n + " >/mnt/sdcard/topInfo.txt", false);

                }
            });

        }

    }

}
3.MainActivity佈局程式碼如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_tool"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:id="@+id/ed_package"
            android:background="@drawable/edittext_border"
            android:hint="輸入每次監控的應用包名"/>
        <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:inputType="number"
            android:id="@+id/ed_toptimes"
            android:maxLength="3"
            android:background="@drawable/edittext_border"
            android:hint="輸入每次監控的時間間隔單位為秒"/>

        <EditText
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:inputType="number"
            android:id="@+id/ed_topmin"
            android:maxLength="5"
            android:background="@drawable/edittext_border"

            android:hint="輸入監控的時間單位為分鐘"
            />
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button_topbegin"
            android:text="啟動監控"/>


        <TextView
            android:layout_width="40dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:gravity="center"
            android:background="@drawable/open_a_red_envelope_centre_open"
            android:id="@+id/timer"
            />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/button_reporte"
            android:text="監控統計"

            />
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/cpu_btn"
            android:text="監控詳情"/>

    </LinearLayout>
    <TableLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        >

        <TableRow>
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" 監控項 "
                />
            <TextView

                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" 最大值 "
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" 最小值 "
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" 平均值 "
                />


        </TableRow>

        <TableRow>
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" cpu指標 "
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/cpu_max"
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/cpu_min"
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/cpu_ave"
                />

        </TableRow>

        <TableRow>
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" rss指標 "
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/rss_max"
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/rss_min"

                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/rss_ave"

                />

        </TableRow>

        <TableRow>
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:text=" vss指標 "
                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/vss_max"

                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/vss_min"

                />
            <TextView
                android:layout_height="wrap_content"
                android:layout_width="wrap_content"
                android:background="@drawable/textview_border"
                android:id="@+id/vss_ave"

                />

        </TableRow>

    </TableLayout>


    </LinearLayout>
4.String轉list工具類
package com.example.monitor;

import android.util.Log;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/9/6.
 */

public class ListUtils {

    public List StrToInt(List<String> str){
        List cpu_num=new ArrayList();
        for(int i = 0;i<str.size();i++){
            int a;
            String b=str.get(i);
            a=Integer.parseInt(b.trim());
            cpu_num.add(a);
        }
        return cpu_num;
    }
    public double listAverage(List<Integer> list){
       int sum=0;
        double average;
        for (int i = 0; i < list.size(); i++) {
            sum+=list.get(i);
        }
        if(list.size()==0){
            average=0;

        }
        else{
            average = sum / list.size();

        }
        Log.i("ave","======"+average);

       return average;

    }
}
5.檔案處理工具類
package com.example.monitor;

import android.widget.EditText;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/8/9.
 */

public class FileUtils {

    // 判斷檔案是否存在
    public static void judeDirExists(File file) {

        if (file.exists()&&file.isDirectory()) {
                System.out.println("dir exists");

        } else {
            System.out.println("dir not exists, create it ...");
            file.mkdir();
        }

    }


    public boolean topfileIsExists(String path){
        try{
            File f=new File(path);
            if(!f.exists()){
                return false;
            }

        }catch (Exception e) {
            // TODO: handle exception
            return false;
        }
        return true;
    }
    //寫入到csv中
    public void writeTofile(String filepath, String content){
        String path=filepath;
        File writepath=new File(path);
        FileWriter writer=null;
        try {
            //"E:\\YallaTest\\YallaResult.csv"
            // 開啟一個寫檔案器,建構函式中的第二個引數true表示以追加形式寫檔案
            writer = new FileWriter(writepath,false);
            writer.write(content);
            //\r\n表示換行
            //,表示換一格
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if(writer != null){
                    writer.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }
    public String read(String path) throws IOException{
        BufferedReader br = new BufferedReader(new FileReader(path));
        StringBuffer sb = new StringBuffer();
        String line = null;
        while((line= br.readLine()) != null) {
            sb.append(line);
        }

        System.out.println(sb.toString()); //sb包含所有文字內容
        return sb.toString();
    }
    public List readcpu(String path,EditText editText) throws IOException{
        String aa=editText.getText().toString();
        BufferedReader br = new BufferedReader(new FileReader(path));
        List list_str=new ArrayList();
        String line = null;
        while((line= br.readLine()) != null) {

            if(line.contains(aa)){
                String m=line.substring(line.indexOf("%")-2, line.indexOf("%"));
                //System.out.println(m);
                list_str.add(m);
            }

        }

       // System.out.println(sb.toString()); //sb包含所有文字內容
        return list_str;
    }

    public List readvss(String path,EditText editText) throws IOException{
        String aa=editText.getText().toString();
        BufferedReader br = new BufferedReader(new FileReader(path));
        List list_str=new ArrayList();
        String line = null;
        while((line= br.readLine()) != null) {
            if(line.contains(aa)){
                String q=line.substring(line.indexOf("K")-7, line.indexOf("K"));
                list_str.add(q);
            }

        }

        // System.out.println(sb.toString()); //sb包含所有文字內容
        return list_str;
    }

    public List readrss(String path,EditText editText) throws IOException{
        String aa=editText.getText().toString();
        BufferedReader br = new BufferedReader(new FileReader(path));
        List list_str=new ArrayList();
        String line = null;
        while((line= br.readLine()) != null) {
            if(line.contains(aa)){
                String g=line.substring(line.indexOf("K",line.indexOf("K")+1 )-6, line.indexOf("K",line.indexOf("K")+1 ));
                list_str.add(g);
            }

        }

        // System.out.println(sb.toString()); //sb包含所有文字內容
        return list_str;
    }


}
6.shell工具類
package com.example.monitor;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;

/**
 * Created by Administrator on 2017/7/13.
 * 有效啟動shell類
 */

public class ShellUtils {

    public static final String COMMAND_SU       = "su";
    public static final String COMMAND_SH       = "sh";
    public static final String COMMAND_EXIT     = "exit\n";
    public static final String COMMAND_LINE_END = "\n";

    private ShellUtils() {
        throw new AssertionError();
    }

    /**
     * check whether has root permission
     *
     * @return
     */
    public static boolean checkRootPermission() {
        return execCommand("echo root", true, false).result == 0;
    }

    /**
     * execute shell command, default return result msg
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot) {
        return execCommand(new String[] {command}, isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List<String> commands, boolean isRoot) {
        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, true);
    }

    /**
     * execute shell commands, default return result msg
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot) {
        return execCommand(commands, isRoot, true);
    }

    /**
     * execute shell command
     *
     * @param command command
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(String command, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(new String[] {command}, isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     *
     * @param commands command list
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return
     * @see ShellUtils#execCommand(String[], boolean, boolean)
     */
    public static CommandResult execCommand(List<String> commands, boolean isRoot, boolean isNeedResultMsg) {
        return execCommand(commands == null ? null : commands.toArray(new String[] {}), isRoot, isNeedResultMsg);
    }

    /**
     * execute shell commands
     *
     * @param commands command array
     * @param isRoot whether need to run with root
     * @param isNeedResultMsg whether need result msg
     * @return <ul>
     *         <li>if isNeedResultMsg is false, {@link CommandResult#successMsg} is null and
     *         {@link CommandResult#errorMsg} is null.</li>
     *         <li>if {@link CommandResult#result} is -1, there maybe some excepiton.</li>
     *         </ul>
     */
    public static CommandResult execCommand(String[] commands, boolean isRoot, boolean isNeedResultMsg) {
        int result = -1;
        if (commands == null || commands.length == 0) {
            return new CommandResult(result, null, null);
        }

        Process process = null;
        BufferedReader successResult = null;
        BufferedReader errorResult = null;
        StringBuilder successMsg = null;
        StringBuilder errorMsg = null;

        DataOutputStream os = null;
        try {
            process = Runtime.getRuntime().exec(isRoot ? COMMAND_SU : COMMAND_SH);
            os = new DataOutputStream(process.getOutputStream());
            for (String command : commands) {
                if (command == null) {
                    continue;
                }

                // donnot use os.writeBytes(commmand), avoid chinese charset error
                os.write(command.getBytes());
                os.writeBytes(COMMAND_LINE_END);
                os.flush();
            }
            os.writeBytes(COMMAND_EXIT);
            os.flush();

            result = process.waitFor();
            // get command result
            if (isNeedResultMsg) {
                successMsg = new StringBuilder();
                errorMsg = new StringBuilder();
                successResult = new BufferedReader(new InputStreamReader(process.getInputStream()));
                errorResult = new BufferedReader(new InputStreamReader(process.getErrorStream()));
                String s;
                while ((s = successResult.readLine()) != null) {
                    successMsg.append(s);
                }
                while ((s = errorResult.readLine()) != null) {
                    errorMsg.append(s);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }
                if (successResult != null) {
                    successResult.close();
                }
                if (errorResult != null) {
                    errorResult.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            if (process != null) {
                process.destroy();
            }
        }
        return new CommandResult(result, successMsg == null ? null : successMsg.toString(), errorMsg == null ? null
                : errorMsg.toString());
    }

    /**
     * result of command
     * <ul>
     * <li>{@link CommandResult#result} means result of command, 0 means normal, else means error, same to excute in
     * linux shell</li>
     * <li>{@link CommandResult#successMsg} means success message of command result</li>
     * <li>{@link CommandResult#errorMsg} means error message of command result</li>
     * </ul>
     *
     * @author <a href="http://www.trinea.cn" target="_blank">Trinea</a> 2013-5-16
     */
    public static class CommandResult {

        /** result of command **/
        public int    result;

        /** success message of command result **/
        public String successMsg;

        /** error message of command result **/
        public String errorMsg;

        public CommandResult(int result) {
            this.result = result;
        }

        public CommandResult(int result, String successMsg, String errorMsg) {
            this.result = result;
            this.successMsg = successMsg;
            this.errorMsg = errorMsg;
        }
    }
}
7.新建一個activity命名為TopDetailActivity
package com.example.monitor;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;



import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TopDetailActivity extends AppCompatActivity {

    private TextView textView_title;
    ArrayList<String> cpuList,rssList,vssList = new ArrayList<String>();
    String title;
    ListView listView_detail;
    List<Map<String,String>> mapList=new ArrayList<>();


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getSupportActionBar().hide();
        setContentView(R.layout.activity_top_detail);
        textView_title=(TextView) findViewById(R.id.monitor_title);
        listView_detail=(ListView) findViewById(R.id.listview_monitor);

        cpuList = getIntent().getStringArrayListExtra("cpu");
        vssList = getIntent().getStringArrayListExtra("vss");
        rssList = getIntent().getStringArrayListExtra("rss");
        // title=getIntent().getStringExtra("title");
        String times=getIntent().getStringExtra("times");
        String totalTime=getIntent().getStringExtra("totalTime");
        textView_title.setText("監控總時間為"+totalTime+"分鐘,監控間隔時間為"+times+"S");


        for(int i=0;i<vssList.size();i++){
            Map<String, String> items=new HashMap<String,String>();
            if(i==0){
                items.put("cpuinfo","CPU            ");
                items.put("rssinfo","RSS                     ");
                items.put("vssinfo","VSS            ");
            }
            else{
                items.put("cpuinfo",cpuList.get(i)+"%            ");
                items.put("rssinfo",rssList.get(i)+"K            ");
                items.put("vssinfo",vssList.get(i)+"K            ");
            }

            mapList.add(items);
        }
        SimpleAdapter simplead = new SimpleAdapter(this, mapList,
                R.layout.monitor_item, new String[] { "cpuinfo", "rssinfo","vssinfo"},
                new int[] {R.id.monitor_cpuitem,R.id.monitor_rssitem,R.id.monitor_vssitem});
        listView_detail.setAdapter(simplead);


    }
}
8.TopDetailActivity佈局程式碼如下
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    <TextView
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:id="@+id/monitor_title"/>

    <ListView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:id="@+id/listview_monitor"></ListView>

</LinearLayout>
9.新建一個佈局檔案monitor_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal" android:layout_width="match_parent"
    android:layout_height="match_parent"

    >
    <TextView
        android:layout_width="wrap_content"
        android:id="@+id/monitor_cpuitem"
        android:layout_height="30dp"
         />
    <TextView
        android:layout_width="wrap_content"
        android:id="@+id/monitor_rssitem"
        android:layout_height="30dp"
        />
    <TextView
        android:layout_width="wrap_content"
        android:id="@+id/monitor_vssitem"
        android:layout_height="30dp"
        />


</LinearLayout>
10.在drawable目錄下新建edittext_border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <stroke android:width="1dip" android:color="#afd54f"/>
</shape>
11.在drawable目錄下新建textview_border.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <solid android:color="#ffffff" />
    <stroke android:width="1dip" android:color="#4fa5d5"/>
</shape>