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;
}
}
/**
* 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>