Android应用性能测试(客户端-服务端)平台实现

Android应用性能测试(客户端-服务端)平台实现

东海陈光剑
2014年5月23日 2:01:05

开源项目代码:  https://github.com/universsky/EmmageePlus (基于Emmagee)

/*
* Copyright (c) 2012-2013 NetEase, Inc. and other contributors
*
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
*
 *      http://www.apache.org/licenses/LICENSE-2.0
*
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
*
*/
package com . netease . qa . emmagee . service ;

import java.io.BufferedReader ;
import java.io.BufferedWriter ;
import java.io.File ;
import java.io.FileInputStream ;
import java.io.FileNotFoundException ;
import java.io.FileOutputStream ;
import java.io.FileReader ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.io.OutputStreamWriter ;
import java.text.DecimalFormat ;
import java.text.SimpleDateFormat ;
import java.util.ArrayList ;
import java.util.Calendar ;
import java.util.Properties ;

import android.app.Activity ;
import android.app.PendingIntent ;
import android.app.Service ;
import android.content.BroadcastReceiver ;
import android.content.Context ;
import android.content.Intent ;
import android.content.IntentFilter ;
import android.content.SharedPreferences ;
import android.net.wifi.WifiManager ;
import android.os.BatteryManager ;
import android.os.Build ;
import android.os.Handler ;
import android.os.IBinder ;
import android.support.v4.app.NotificationCompat ;
import android.util.Log ;
import android.view.Gravity ;
import android.view.LayoutInflater ;
import android.view.MotionEvent ;
import android.view.View ;
import android.view.View.OnClickListener ;
import android.view.View.OnTouchListener ;
import android.view.WindowManager ;
import android.widget.Button ;
import android.widget.TextView ;
import android.widget.Toast ;

import com.netease.qa.emmagee.R ;
import com.netease.qa.emmagee.activity.MainPageActivity ;
import com.netease.qa.emmagee.config.Const ;
import com.netease.qa.emmagee.utils.CpuInfo ;
import com.netease.qa.emmagee.utils.CurrentInfo ;
import com.netease.qa.emmagee.utils.EncryptData ;
import com.netease.qa.emmagee.utils.FileUpload ;
import com.netease.qa.emmagee.utils.MailSender ;
import com.netease.qa.emmagee.utils.MemoryInfo ;
import com.netease.qa.emmagee.utils.MyApplication ;

/**
* Service running in background
*
* @author andrewleo
*/
public class EmmageeService extends Service {

private final static String LOG_TAG = "Emmagee-"
+ EmmageeService . class . getSimpleName ();

private WindowManager windowManager = null ;
private WindowManager . LayoutParams wmParams = null ;
private View viFloatingWindow ;
private float mTouchStartX ;
private float mTouchStartY ;
private float startX ;
private float startY ;
private float x ;
private float y ;
private TextView txtTotalMem ;
private TextView txtUnusedMem ;
private TextView txtTraffic ;
private Button btnStop ;
private Button btnWifi ;
private int delaytime ;
private DecimalFormat fomart ;
private MemoryInfo memoryInfo ;
private WifiManager wifiManager ;
private Handler handler = new Handler ();
private CpuInfo cpuInfo ;
private String time ;
private boolean isFloating ;
private String processName , packageName , settingTempFile , startActivity ;
private int pid , uid ;
private boolean isServiceStop = false ;
private String sender , password , recipients , smtp ;
private String [] receivers ;
private EncryptData des ;

public static BufferedWriter bw ;
public static FileOutputStream out ;
public static OutputStreamWriter osw ;
public static String resultFilePath ;
public static boolean isStop = false ;

private String totalBatt ;
private String temperature ;
private String voltage ;
private CurrentInfo currentInfo ;
private BatteryInfoBroadcastReceiver batteryBroadcast = null ;

// get start time
private static final int MAX_START_TIME_COUNT = 5 ;
private static final String START_TIME = "#startTime" ;
private int getStartTimeCount = 0 ;
private boolean isGetStartTime = true ;
private String startTime = "" ;

@Override
public void onCreate () {
Log . i ( LOG_TAG , "onCreate" );
super . onCreate ();
isServiceStop = false ;
isStop = false ;
memoryInfo = new MemoryInfo ();
fomart = new DecimalFormat ();
fomart . setMaximumFractionDigits ( 2 );
fomart . setMinimumFractionDigits ( 0 );
des = new EncryptData ( "emmagee" );
currentInfo = new CurrentInfo ();
batteryBroadcast = new BatteryInfoBroadcastReceiver ();
registerReceiver ( batteryBroadcast , new IntentFilter (
"android.intent.action.BATTERY_CHANGED" ));
}

/**
     * 电池信息监控监听器
     *
     * @author andrewleo
     *
     */
public class BatteryInfoBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive ( Context context , Intent intent ) {

if ( Intent . ACTION_BATTERY_CHANGED . equals ( intent . getAction ())) {
int level = intent . getIntExtra ( BatteryManager . EXTRA_LEVEL , 0 );

int scale = intent . getIntExtra ( BatteryManager . EXTRA_SCALE , - 1 );
totalBatt = String . valueOf ( level * 100 / scale ) + "%" ;

voltage = String . valueOf ( intent . getIntExtra (
BatteryManager . EXTRA_VOLTAGE , - 1 ) * 1.0 / 1000 );

temperature = String . valueOf ( intent . getIntExtra (
BatteryManager . EXTRA_TEMPERATURE , - 1 ) * 1.0 / 10 );
}

}

}

@Override
public void onStart ( Intent intent , int startId ) {
Log . i ( LOG_TAG , "onStart" );
PendingIntent contentIntent = PendingIntent . getActivity (
getBaseContext (), 0 , new Intent ( this , MainPageActivity . class ),
0 );
NotificationCompat . Builder builder = new NotificationCompat . Builder (
this );
builder . setContentIntent ( contentIntent ). setSmallIcon ( R . drawable . icon )
. setWhen ( System . currentTimeMillis ()). setAutoCancel ( true )
. setContentTitle ( "Emmagee" );
startForeground ( startId , builder . build ());

pid = intent . getExtras (). getInt ( "pid" );
uid = intent . getExtras (). getInt ( "uid" );
processName = intent . getExtras (). getString ( "processName" );
packageName = intent . getExtras (). getString ( "packageName" );
settingTempFile = intent . getExtras (). getString ( "settingTempFile" );
startActivity = intent . getExtras (). getString ( "startActivity" );

cpuInfo = new CpuInfo ( getBaseContext (), pid , Integer . toString ( uid ));
readSettingInfo ( intent );
delaytime = Integer . parseInt ( time ) * 1000 ;
if ( isFloating ) {
viFloatingWindow = LayoutInflater . from ( this ). inflate (
R . layout . floating , null );
txtUnusedMem = ( TextView ) viFloatingWindow
. findViewById ( R . id . memunused );
txtTotalMem = ( TextView ) viFloatingWindow
. findViewById ( R . id . memtotal );
txtTraffic = ( TextView ) viFloatingWindow . findViewById ( R . id . traffic );
btnWifi = ( Button ) viFloatingWindow . findViewById ( R . id . wifi );

wifiManager = ( WifiManager ) getSystemService ( Context . WIFI_SERVICE );
if ( wifiManager . isWifiEnabled ()) {
btnWifi . setText ( R . string . closewifi );
} else {
btnWifi . setText ( R . string . openwifi );
}
txtUnusedMem . setText ( "计算中,请稍后..." );
txtUnusedMem . setTextColor ( android . graphics . Color . RED );
txtTotalMem . setTextColor ( android . graphics . Color . RED );
txtTraffic . setTextColor ( android . graphics . Color . RED );
btnStop = ( Button ) viFloatingWindow . findViewById ( R . id . stop );
btnStop . setOnClickListener ( new OnClickListener () {
@Override
public void onClick ( View v ) {
Intent intent = new Intent ();
intent . putExtra ( "isServiceStop" , true );
intent . setAction ( "com.netease.action.emmageeService" );
sendBroadcast ( intent );
// isServiceStop = true;
Toast . makeText ( EmmageeService . this ,
"测试结果文件:" + resultFilePath , Toast . LENGTH_LONG )
. show ();
stopSelf ();
}
});
createFloatingWindow ();
}
createResultCsv ();
handler . postDelayed ( task , 1000 );
}

/**
     * read configuration file.
     *
     * @throws IOException
     */
private void readSettingInfo ( Intent intent ) {
try {
Properties properties = new Properties ();
properties . load ( new FileInputStream ( settingTempFile ));
String interval = properties . getProperty ( "interval" ). trim ();
isFloating = "true"
. equals ( properties . getProperty ( "isfloat" ). trim ()) ? true
: false ;
sender = properties . getProperty ( "sender" ). trim ();
password = properties . getProperty ( "password" ). trim ();
recipients = properties . getProperty ( "recipients" ). trim ();
time = "" . equals ( interval ) ? "5" : interval ;
recipients = properties . getProperty ( "recipients" );
receivers = recipients . split ( "\\s+" );
smtp = properties . getProperty ( "smtp" );
} catch ( IOException e ) {
time = "5" ;
isFloating = true ;
Log . e ( LOG_TAG , e . getMessage ());
}
}

/**
     * write the test result to csv format report.
     */
private void createResultCsv () {
Calendar cal = Calendar . getInstance ();
SimpleDateFormat formatter = new SimpleDateFormat ( "yyyyMMddHHmmss" );
String mDateTime ;
if (( Build . MODEL . equals ( "sdk" )) || ( Build . MODEL . equals ( "google_sdk" )))
mDateTime = formatter . format ( cal . getTime (). getTime () + 8 * 60 * 60
* 1000 );
else
mDateTime = formatter . format ( cal . getTime (). getTime ());

if ( android . os . Environment . getExternalStorageState (). equals (
android . os . Environment . MEDIA_MOUNTED )) {
resultFilePath = android . os . Environment
. getExternalStorageDirectory ()
+ File . separator
+ "Emmagee_TestResult_" + mDateTime + ".csv" ;
} else {
resultFilePath = getBaseContext (). getFilesDir (). getPath ()
+ File . separator + "Emmagee_TestResult_" + mDateTime
+ ".csv" ;
}
try {
File resultFile = new File ( resultFilePath );
resultFile . createNewFile ();
out = new FileOutputStream ( resultFile );
osw = new OutputStreamWriter ( out , "UTF-8" );
bw = new BufferedWriter ( osw );
long totalMemorySize = memoryInfo . getTotalMemory ();
String totalMemory = fomart . format (( double ) totalMemorySize / 1024 );
bw . write ( "应用包名:," + packageName + "\r\n" + "应用名称: ," + processName
+ "\r\n" + "应用PID: ,"
+ pid
+ "\r\n"
+ "内存大小(MB):,"
+ totalMemory . replaceAll ( "," , "" ) // 1,980MB-->1980MB
+ "MB\r\n" + "CPU型号:," + cpuInfo . getCpuName () + "\r\n"
+ "系统版本:," + memoryInfo . getSDKVersion () + "\r\n" + "手机型号:,"
+ memoryInfo . getPhoneType () + "\r\n" + "UID:," + uid
+ "\r\n" + "启动时间:," + START_TIME + "\r\n" );

bw . write ( "时间" + "," + "应用占用内存PSS(MB)" + "," + "应用占用内存比(%)" + ","
+ " 机器剩余内存(MB)" + "," + "应用占用CPU率(%)" + "," + "CPU总使用率(%)"
+ "," + "流量(KB)" + "," + "电量(%)" + "," + "电流(mA)" + ","
+ "温度(C)" + "," + "电压(V)" + "\r\n" );

} catch ( IOException e ) {
Log . e ( LOG_TAG , e . getMessage ());
}
}

/**
     * create a floating window to show real-time data.
     */
private void createFloatingWindow () {
SharedPreferences shared = getSharedPreferences ( "float_flag" ,
Activity . MODE_PRIVATE );
SharedPreferences . Editor editor = shared . edit ();
editor . putInt ( "float" , 1 );
editor . commit ();
windowManager = ( WindowManager ) getApplicationContext ()
. getSystemService ( "window" );
wmParams = (( MyApplication ) getApplication ()). getMywmParams ();
wmParams . type = 2002 ;
wmParams . flags |= 8 ;
wmParams . gravity = Gravity . LEFT | Gravity . TOP ;
wmParams . x = 0 ;
wmParams . y = 0 ;
wmParams . width = WindowManager . LayoutParams . WRAP_CONTENT ;
wmParams . height = WindowManager . LayoutParams . WRAP_CONTENT ;
wmParams . format = 1 ;
windowManager . addView ( viFloatingWindow , wmParams );
viFloatingWindow . setOnTouchListener ( new OnTouchListener () {
public boolean onTouch ( View v , MotionEvent event ) {
x = event . getRawX ();
y = event . getRawY () - 25 ;
switch ( event . getAction ()) {
case MotionEvent . ACTION_DOWN :
startX = x ;
startY = y ;
mTouchStartX = event . getX ();
mTouchStartY = event . getY ();
Log . d ( "startP" , "startX" + mTouchStartX + "====startY"
+ mTouchStartY );
break ;
case MotionEvent . ACTION_MOVE :
updateViewPosition ();
break ;

case MotionEvent . ACTION_UP :
updateViewPosition ();
// showImg();
mTouchStartX = mTouchStartY = 0 ;
break ;
}
return true ;
}
});

btnWifi . setOnClickListener ( new OnClickListener () {
@Override
public void onClick ( View v ) {
try {
btnWifi = ( Button ) viFloatingWindow . findViewById ( R . id . wifi );
String buttonText = ( String ) btnWifi . getText ();
String wifiText = getResources (). getString (
R . string . openwifi );
if ( buttonText . equals ( wifiText )) {
wifiManager . setWifiEnabled ( true );
btnWifi . setText ( R . string . closewifi );
} else {
wifiManager . setWifiEnabled ( false );
btnWifi . setText ( R . string . openwifi );
}
} catch ( Exception e ) {
Toast . makeText ( viFloatingWindow . getContext (), "操作wifi失败" ,
Toast . LENGTH_LONG ). show ();
Log . e ( LOG_TAG , e . toString ());
}
}
});
}

// /**
// * show the image.
// */
// private void showImg() {
// if (Math.abs(x - startX) < 1.5 && Math.abs(y - startY) < 1.5 &&
// !btnStop.isShown()) {
// btnStop.setVisibility(View.VISIBLE);
// } else if (btnStop.isShown()) {
// btnStop.setVisibility(View.GONE);
// }
// }

private Runnable task = new Runnable () {

public void run () {
if (! isServiceStop ) {
dataRefresh ();
handler . postDelayed ( this , delaytime );
if ( isFloating ) {
windowManager . updateViewLayout ( viFloatingWindow , wmParams );
}
// get app start time from logcat on every task running
getStartTimeFromLogcat ();
} else {
Intent intent = new Intent ();
intent . putExtra ( "isServiceStop" , true );
intent . setAction ( "com.netease.action.emmageeService" );
sendBroadcast ( intent );
stopSelf ();
}
}
};

/**
     * Try to get start time from logcat.
     */
private void getStartTimeFromLogcat () {
if (! isGetStartTime || getStartTimeCount >= MAX_START_TIME_COUNT ) {
return ;
}
try {
// filter logcat by Tag:ActivityManager and Level:Info
String logcatCommand = "logcat -v time -d ActivityManager:I *:S" ;
Process process = Runtime . getRuntime (). exec ( logcatCommand );
BufferedReader bufferedReader = new BufferedReader (
new InputStreamReader ( process . getInputStream ()));
StringBuilder strBuilder = new StringBuilder ();
String line = "" ;

while (( line = bufferedReader . readLine ()) != null ) {
strBuilder . append ( line );
strBuilder . append ( "\r\n" );
String regex = ".*Displayed.*" + startActivity
+ ".*\\+(.*)ms.*" ;
Log . d ( "my logs" , regex );
if ( line . matches ( regex )) {
Log . w ( "my logs" , line );
if ( line . contains ( "total" )) {
line = line . substring ( 0 , line . indexOf ( "total" ));
}
startTime = line . substring ( line . lastIndexOf ( "+" ) + 1 ,
line . lastIndexOf ( "ms" ) + 2 );
Toast . makeText ( EmmageeService . this , "启动时间:" + startTime ,
Toast . LENGTH_LONG ). show ();
isGetStartTime = false ;
break ;
}
}
getStartTimeCount ++;
// Log.w("my logs", "Start Time Log:" + strBuilder.toString());
Log . w ( LOG_TAG , "getStartCount:" + getStartTimeCount );
} catch ( IOException e ) {
Log . d ( LOG_TAG , e . getMessage ());
}
}

/**
     * refresh the performance data showing in floating window.
     *
     * @throws FileNotFoundException
     *
     * @throws IOException
     */
private void dataRefresh () {
int pidMemory = memoryInfo . getPidMemorySize ( pid , getBaseContext ());
long freeMemory = memoryInfo . getFreeMemorySize ( getBaseContext ());
String freeMemoryKb = fomart . format (( double ) freeMemory / 1024 );
String processMemory = fomart . format (( double ) pidMemory / 1024 );
String currentBatt = String . valueOf ( currentInfo . getCurrentValue ());
// 异常数据过滤
Log . d ( "my logs-before" , currentBatt );
try {
if ( Math . abs ( Double . parseDouble ( currentBatt )) >= 500 ) {
currentBatt = "N/A" ;
} else {
currentBatt = currentBatt + "mA" ;
}
} catch ( Exception e ) {
currentBatt = "N/A" ;
}
Log . d ( "my logs-after" , currentBatt );
ArrayList < String > processInfo = cpuInfo . getCpuRatioInfo ( totalBatt ,
currentBatt , temperature , voltage );
if ( isFloating ) {
String processCpuRatio = "0" ;
String totalCpuRatio = "0" ;
String trafficSize = "0" ;
int tempTraffic = 0 ;
double trafficMb = 0 ;
boolean isMb = false ;
if (! processInfo . isEmpty ()) {
processCpuRatio = processInfo . get ( 0 );
totalCpuRatio = processInfo . get ( 1 );
trafficSize = processInfo . get ( 2 );
if (!( "" . equals ( trafficSize )) && !( "-1" . equals ( trafficSize ))) {
tempTraffic = Integer . parseInt ( trafficSize );
if ( tempTraffic > 1024 ) {
isMb = true ;
trafficMb = ( double ) tempTraffic / 1024 ;
}
}
// 如果cpu使用率存在且都不小于0,则输出
if ( processCpuRatio != null && totalCpuRatio != null ) {
txtUnusedMem . setText ( "应用/剩余内存:" + processMemory + "/"
+ freeMemoryKb + "MB" );
txtTotalMem . setText ( "应用/总体CPU:" + processCpuRatio + "%/"
+ totalCpuRatio + "%" );
String batt = "电流:" + currentBatt ;
if ( "-1" . equals ( trafficSize )) {
txtTraffic . setText ( batt + ",流量:N/A" );
} else if ( isMb )
txtTraffic . setText ( batt + ",流量:"
+ fomart . format ( trafficMb ) + "MB" );
else
txtTraffic . setText ( batt + ",流量:" + trafficSize + "KB" );
}
// 当内存为0,and cpu使用率为0时则是被测应用退出
if ( "0" . equals ( processMemory ) && "0.00" . equals ( processCpuRatio )) {
closeOpenedStream ();
isServiceStop = true ;
return ;
}
}

}
}

/**
     * update the position of floating window.
     */
private void updateViewPosition () {
wmParams . x = ( int ) ( x - mTouchStartX );
wmParams . y = ( int ) ( y - mTouchStartY );
windowManager . updateViewLayout ( viFloatingWindow , wmParams );
}

/**
     * close all opened stream.
     */
public static void closeOpenedStream () {
try {
if ( bw != null ) {
// bw.write("注释:已知部分不支持的机型可在此查阅:https://github.com/NetEase/Emmagee/wiki/Some-devices-are-not-supported \r\n");
bw . write ( "N/A:表示不支持或者数据异常\r\n" );
bw . write ( "电流:小于0是放电大于0是充电\r\n启动时间:为空是应用已启动或者未搜集到启动时间\r\n" );

bw . close ();
}
if ( osw != null )
osw . close ();
if ( out != null )
out . close ();
} catch ( Exception e ) {
Log . d ( LOG_TAG , e . getMessage ());
}
}

@Override
public void onDestroy () {
Log . i ( LOG_TAG , "onDestroy" );
if ( windowManager != null )
windowManager . removeView ( viFloatingWindow );
handler . removeCallbacks ( task );
closeOpenedStream ();

// replace the start time in file

if (! "" . equals ( startTime )) {
// START_TIME = "#startTime"
replaceFileString ( resultFilePath , START_TIME , "启动时间:" + startTime
+ "\r\n" );
} else {
replaceFileString ( resultFilePath , START_TIME , "N/A" );
}
isStop = true ;
unregisterReceiver ( batteryBroadcast );

boolean isSendMailSuccessfully = false ;
boolean isUploadServerSuccessfully = false ;
// http://10.125.1.58:88/perf.html?run_stamp=20140522154031
// http://10.125.1.58:88/img/Emmagee_TestResult_20140522104413.csv

String attach_url = Const . serverUrl
+ resultFilePath . substring ( resultFilePath . lastIndexOf ( "_" ) + 1 ,
resultFilePath . indexOf ( ".csv" ));

try {
FileUpload up = new FileUpload ();

isUploadServerSuccessfully = up . send ( Const . uploadServerUrl ,
resultFilePath );

isSendMailSuccessfully = MailSender . sendTextMail ( sender ,
des . decrypt ( password ), smtp ,
"Emmagee Performance Test Report" , "Performance Report: "
+ attach_url + "\nCSV Data See attachment:" ,
resultFilePath , receivers );

} catch ( Exception e ) {
isSendMailSuccessfully = false ;
}

if ( isUploadServerSuccessfully ) {
Toast . makeText ( this , "测试结果报表上传服务器:" + Const . uploadServerUrl ,
Toast . LENGTH_LONG ). show ();
} else {
Toast . makeText ( this ,
"测试结果未成功上传服务器,结果保存在:" + EmmageeService . resultFilePath ,
Toast . LENGTH_LONG ). show ();
}

if ( isSendMailSuccessfully ) {
Toast . makeText ( this , "测试结果报表已发送至邮箱:" + recipients ,
Toast . LENGTH_LONG ). show ();
} else {
Toast . makeText ( this ,
"测试结果未成功发送至邮箱,结果保存在:" + EmmageeService . resultFilePath ,
Toast . LENGTH_LONG ). show ();
}
super . onDestroy ();
stopForeground ( true );
}

/**
     * Replaces all matches for replaceType within this replaceString in file on
     * the filePath
     *
     * @param filePath
     * @param replaceType
     * @param replaceString
     */
private void replaceFileString ( String filePath , String replaceType ,
String replaceString ) {
try {
File file = new File ( filePath );
BufferedReader reader = new BufferedReader ( new FileReader ( file ));
String line = "" , oldtext = "" ;
while (( line = reader . readLine ()) != null ) {
oldtext += line + "\r\n" ;
}
reader . close ();
// replace a word in a file
String newtext = oldtext . replaceAll ( replaceType , replaceString );
BufferedWriter writer = new BufferedWriter ( new OutputStreamWriter (
new FileOutputStream ( filePath ), "UTF-8" ));
writer . write ( newtext );
writer . close ();
} catch ( IOException e ) {
Log . d ( LOG_TAG , e . getMessage ());
}
}

@Override
public IBinder onBind ( Intent intent ) {
return null ;
}
}


230204408402532.png

/**
 * CSVFileIO.java
 * universsky.ct.result
 * ReportServlet
 */
package universsky.ct.result;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import com.csvreader.CsvReader;
import com.csvreader.CsvWriter;
/**
 * @author 东海陈光剑 2014年5月22日 下午2:41:20
 * 
 */
public class CSVFileIO {
    /**
     * @param args
     */
    public static void main(String[] args) {
        String run_stamp = "20140522154031";
        CSVFileIO csv = new CSVFileIO();
        List<HashMap<String, ArrayList<String>>> result = csv.query(run_stamp);
        System.out.println(result);
    }
    public List<HashMap<String, ArrayList<String>>> query(String run_stamp) {
        List<HashMap<String, ArrayList<String>>> result = new ArrayList<HashMap<String, ArrayList<String>>>();
        String csvFilePath = "C:\\autoTest\\httpd\\htdocs\\img\\Emmagee_TestResult_"
                + run_stamp + ".csv";
        ArrayList<String[]> csvList = new ArrayList<String[]>(); // 用来保存数据
        try {
            CsvReader reader = new CsvReader(csvFilePath, ',',
                    Charset.forName("UTF-8")); // 编码读
            // reader.readHeaders(); // 跳过表头 如果需要表头的话,不要写这句。
            while (reader.readRecord()) { // 逐行读入除表头的数据
                csvList.add(reader.getValues());
            }
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        HashMap<String, ArrayList<String>> DCMap = new HashMap<String, ArrayList<String>>();
        ArrayList<String> package_name = new ArrayList<String>();
        package_name.add(csvList.get(0)[1]);
        DCMap.put("package_name", package_name);
        ArrayList<String> app_name = new ArrayList<String>();
        app_name.add(csvList.get(1)[1]);
        DCMap.put("app_name", app_name);
        ArrayList<String> pid = new ArrayList<String>();
        pid.add(csvList.get(2)[1]);
        DCMap.put("pid", pid);
        ArrayList<String> mem = new ArrayList<String>();
        mem.add(csvList.get(3)[1]);
        DCMap.put("mem", mem);
        ArrayList<String> cpu_type = new ArrayList<String>();
        cpu_type.add(csvList.get(4)[1]);
        DCMap.put("cpu_type", cpu_type);
        ArrayList<String> sys_version = new ArrayList<String>();
        sys_version.add(csvList.get(5)[1]);
        DCMap.put("sys_version", sys_version);
        ArrayList<String> mobile_type = new ArrayList<String>();
        mobile_type.add(csvList.get(6)[1]);
        DCMap.put("mobile_type", mobile_type);
        ArrayList<String> uid = new ArrayList<String>();
        uid.add(csvList.get(7)[1]);
        DCMap.put("uid", uid);
        ArrayList<String> start_time = new ArrayList<String>();
        start_time.add(csvList.get(8)[1]);
        DCMap.put("start_time", start_time);
        // //
        int L = csvList.size();
        ArrayList<String> time = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            time.add(csvList.get(i)[0]);
        }
        DCMap.put("time", time);
        ArrayList<String> pss = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            pss.add(csvList.get(i)[1]);
        }
        DCMap.put("pss", pss);
        ArrayList<String> mem_ratio = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            mem_ratio.add(csvList.get(i)[2]);
        }
        DCMap.put("mem_ratio", mem_ratio);
        ArrayList<String> mem_free = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            mem_free.add(csvList.get(i)[3]);
        }
        DCMap.put("mem_free", mem_free);
        ArrayList<String> cpu_ratio = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            cpu_ratio.add(csvList.get(i)[4]);
        }
        DCMap.put("cpu_ratio", cpu_ratio);
        ArrayList<String> ttl_cpu_ratio = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            ttl_cpu_ratio.add(csvList.get(i)[5]);
        }
        DCMap.put("ttl_cpu_ratio", ttl_cpu_ratio);
        ArrayList<String> traffic = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            traffic.add(csvList.get(i)[6]);
        }
        DCMap.put("traffic", traffic);
        ArrayList<String> battery = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            battery.add(csvList.get(i)[7]);
        }
        DCMap.put("battery", battery);
        ArrayList<String> current = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            current.add(csvList.get(i)[8]);
        }
        DCMap.put("current", current);
        ArrayList<String> temperature = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            temperature.add(csvList.get(i)[9]);
        }
        DCMap.put("temperature", temperature);
        ArrayList<String> voltage = new ArrayList<String>();
        for (int i = 10; i < L - 3; i++) {
            voltage.add(csvList.get(i)[10]);
        }
        DCMap.put("voltage", voltage);
        result.add(DCMap);
        return result;
    }
    /**
     * 读取CSV文件
     */
    public static void readCsv(String csvFilePath) {
        try {
            ArrayList<String[]> csvList = new ArrayList<String[]>(); // 用来保存数据
            CsvReader reader = new CsvReader(csvFilePath, ',',
                    Charset.forName("UTF8")); // 一般用这编码读就可以了
            // reader.readHeaders(); // 跳过表头 如果需要表头的话,不要写这句。
            while (reader.readRecord()) { // 逐行读入除表头的数据
                csvList.add(reader.getValues());
            }
            reader.close();
            for (int row = 0; row < csvList.size(); row++) {
                String[] cell = csvList.get(row);
                if (cell.length == 2) {
                    System.out.print(cell[0] + "\t");
                    System.out.print(cell[1] + "\t");
                    // for (int i = 0; i < cell.length; i++) {
                    // System.out.print(cell[i] + "\t");
                    // }
                }
                if (cell.length == 11) {
                    for (int i = 0; i < cell.length; i++) {
                        System.out.print(cell[i] + "\t");
                    }
                }
                System.out.println();
            }
        } catch (Exception ex) {
            System.out.println(ex);
        }
    }
    /**
     * 写入CSV文件
     */
    public static void WriteCsv() {
        try {
            String csvFilePath = "D:/log/Alarm20101125.csv";
            CsvWriter wr = new CsvWriter(csvFilePath, ',',
                    Charset.forName("SJIS"));
            String[] contents = { "告警信息""非法操作""没有权限""操作失败" };
            wr.writeRecord(contents);
            wr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}



<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <title>性能测试报告</title>
    <script src="http://g.tbcdn.cn/kissy/k/1.4.0/seed-min.js"></script>
<style type="text/css">   
body {
 background-color: #EEEEEE; 
}                             
p.serif{font-family:"Times New Roman",Georgia,Serif}
p.sansserif{font-family:Arial,Verdana,Sans-serif}
 
</style>                     
 
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
        <script type="text/javascript">
 
        var run_stamp0 = 20140522154031;       
        var href = location.href;
        var m, run_stamp;
 
        m = href.match(/stamp=(\d+)/);
        if(!m) run_stamp = run_stamp0;
        else run_stamp = m[1];
 
        $.ajax({
        url : 'http://10.125.1.58:8888/ReportServlet/csv?run_stamp='+run_stamp, //请求地址
        type : 'GET', //POST或GET请求
        data : {
                siteName : "http://10.125.1.58:8888" //参数 JSON格式 如果是GET请求可以直接在URL里写
        },
        dataType : 'jsonp',//json 或者 jsonp 默认是html
        timeout : 10000,
        error : function() {
                alert('Time out loading : http://10.125.1.58:8888/ReportServlet/csv?run_stamp='+run_stamp);
        },
        success : function(JSON) {
        /* basic_info */   
        var content="";
        content += "应用程序名:<strong>"+JSON.result[0].app_name[0]+"</strong><br>";
        content += "应用包名:<strong>"+JSON.result[0].package_name[0]+"</strong><br>";
        content += "应用PID:<strong>"+JSON.result[0].pid[0]+"</strong><br>";
        content += "应用UID:<strong>"+JSON.result[0].uid[0]+"</strong><br>";
        content += "内存大小(MB):<strong>"+JSON.result[0].mem[0]+"</strong><br>";
        content += "CPU型号:<strong>"+JSON.result[0].cpu_type[0]+"</strong><br>";
        content += "系统版本:<strong>"+JSON.result[0].sys_version[0]+"</strong><br>";
        content += "手机型号:<strong>"+JSON.result[0].mobile_type[0]+"</strong><br>";
 
        content += "启动时间:<strong>"+JSON.result[0].start_time[0]+"</strong><br>";
 
        $("#basic_info").each(function(){
            $(this).html(content);
        });
 
 
 
 
        /* charts */
        ///
        var pss=[];
        /*
        series: [{
                name: 'Tokyo',
                data: [7.0, 6.9, 9.5, 14.5, 18.2, 21.5, 25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
            }, {
                name: 'New York',
                data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
            }, {
                name: 'Berlin',
                data: [-0.9, 0.6, 3.5, 8.4, 13.5, 17.0, 18.6, 17.9, 14.3, 9.0, 3.9, 1.0]
            }, {
                name: 'London',
                data: [3.9, 4.2, 5.7, 8.5, 11.9, 15.2, 17.0, 16.6, 14.2, 10.3, 6.6, 4.8]
            }]
        */
            var SIZE = JSON.result[0].pss.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].pss[j]);
            }
            var item={};
            item.name = 'pss';
            item.data = y
            pss.push(item);
 
            $('#container_pss').highcharts({
            title: {
                text: '应用占用内存PSS(MB)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: 'PSS(MB)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '应用占用内存PSS(MB)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: pss
        });
        ///
        var mem_ratio=[];
 
            var SIZE = JSON.result[0].mem_ratio.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].mem_ratio[j]);
            }
            var item={};
            item.name = 'mem_ratio';
            item.data = y
            mem_ratio.push(item);
 
            $('#container_mem_ratio').highcharts({
            title: {
                text: '应用占用内存比(%)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '应用占用内存比(%)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '应用占用内存比(%)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: mem_ratio
        });
 
        ///
        var cpu_ratio=[];
 
            var SIZE = JSON.result[0].cpu_ratio.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].cpu_ratio[j]);
            }
            var item={};
            item.name = 'cpu_ratio';
            item.data = y
            cpu_ratio.push(item);
 
            $('#container_cpu_ratio').highcharts({
            title: {
                text: '应用占用CPU率(%)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '应用占用CPU率(%)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '应用占用CPU率%'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: cpu_ratio
        });
        ///
        var ttl_cpu_ratio=[];
 
            var SIZE = JSON.result[0].ttl_cpu_ratio.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].ttl_cpu_ratio[j]);
            }
            var item={};
            item.name = 'ttl_cpu_ratio';
            item.data = y
            ttl_cpu_ratio.push(item);
 
            $('#container_ttl_cpu_ratio').highcharts({
            title: {
                text: 'CPU总使用率(%)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: 'CPU总使用率(%)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: 'CPU总使用率%'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: ttl_cpu_ratio
        });
 
        ///
        var mem_free=[];
 
            var SIZE = JSON.result[0].mem_free.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].mem_free[j]);
            }
            var item={};
            item.name = 'mem_free';
            item.data = y
            mem_free.push(item);
 
            $('#container_mem_free').highcharts({
            title: {
                text: '剩余内存(MB)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '剩余内存(MB)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: 'MB'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: mem_free
        });
 
        ///
        var traffic=[];
 
            var SIZE = JSON.result[0].traffic.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].traffic[j]);
            }
            var item={};
            item.name = 'traffic';
            item.data = y
            traffic.push(item);
 
            $('#container_traffic').highcharts({
            title: {
                text: '流量(KB)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '流量(KB)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '流量(KB)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: traffic
        });
 
        ///
        var battery=[];
 
            var SIZE = JSON.result[0].battery.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].battery[j]);
            }
            var item={};
            item.name = 'battery';
            item.data = y
            battery.push(item);
 
            $('#container_battery').highcharts({
            title: {
                text: '电量(%)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '电量(%)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '电量(%)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: battery
        });
 
        ///
        var current=[];
 
            var SIZE = JSON.result[0].current.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].current[j]);
            }
            var item={};
            item.name = 'current';
            item.data = y
            current.push(item);
 
            $('#container_current').highcharts({
            title: {
                text: '电流(mA)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '电流(mA)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '电流(mA)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: current
        });
        ///
        var voltage=[];
 
            var SIZE = JSON.result[0].voltage.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].voltage[j]);
            }
            var item={};
            item.name = 'voltage';
            item.data = y
            voltage.push(item);
 
            $('#container_voltage').highcharts({
            title: {
                text: '电压(V)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '电压(V)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '电压(V)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: voltage
        });
 
        ///
        var temperature=[];
 
            var SIZE = JSON.result[0].temperature.length;
            var y = new Array(SIZE);
            for(j=0; j<SIZE; j++){
               y[j]=parseInt(JSON.result[0].temperature[j]);
            }
            var item={};
            item.name = 'temperature';
            item.data = y
            temperature.push(item);
 
            $('#container_temperature').highcharts({
            title: {
                text: '温度(C)',  
            },
            xAxis: {
                labels: {
                    enabled: false
                }
            },               
            yAxis: {
                min: 0,
                title: {
                    text: '温度(C)'
                },
                plotLines: [{
                    value: 0,
                    width: 1,
                    color: '#808080'
                }]
            },
            tooltip: {
                valueSuffix: '温度(C)'
            },
            legend: {
                layout: 'vertical',
                align: 'right',
                verticalAlign: 'middle',
                borderWidth: 0
            },
            series: temperature
        });
    /*********************************************************************************************/
    }});
        //
 
 
        </script>
 
        <script src="js/highcharts.js"></script>
        <script src="js/modules/data.js"></script>
        <script src="js/modules/exporting.js"></script>   
 
</head>
 
<body class="serif">
    <br><br><br>
    <h2 align="center"style=font-family:微软雅黑>Android应用性能测试报告</h2>
 
              <p align="right">
                <label for="issue_issue_author_id">联系人:陈光剑</label>
                 <a href="http://www.taobao.com/webww/ww.php?ver=3&touid=universsky1&siteid=cntaobao&status=2&charset=utf-8" class="inline-item" target="_blank" title="universsky1"><img alt="universsky1" border="0" src="http://amos.alicdn.com/realonline.aw?v=2&uid=universsky1&site=cntaobao&s=2&charset=utf-8" /></a><a href="http://amos.alicdn.com/msg.aw?v=2&uid=universsky1&site=cnalichn&s=11&charset=UTF-8" class="inline-item" target="_blank" title="universsky1"></a>
              </p>
 
    <div id=time align="right" style=font-family:Verdana></div>
    <script>setInterval("time.innerHTML='今天是'+new Date().toLocaleString()+' 星期'+'日一二三四五六'.charAt(new Date().getDay())+' ';",1000);</script>
 
    <div id="basic_info"></div>
 
    <div id="container_pss" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_mem_ratio" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_cpu_ratio" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_ttl_cpu_ratio" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_mem_free" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_traffic" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_battery" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_current" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_voltage" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
    <div id="container_temperature" style="min-width: 100px; height: 200px; margin: 0 auto"></div>
    <br>
 
 
    <div id="download_img" align="center" ><a href="http://10.125.1.58:88/apk/Emmagee.apk"><img src="http://10.125.1.58:88/apk/qrcode.png"></img></a></div>
    <div id="download" align="center" ><a href="http://10.125.1.58:88/apk/Emmagee.apk">性能测试工具Emmagee下载</a></div>
 
</body>
</html>



230204484027754.png 230204490273397.png
230204493244839.png

230204496845497.png




转载于:https://www.cnblogs.com/universsky/p/c6bdadfe9b9cd700ba4a7d6773064a85.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值