现在安装Android系统的手机版本和设备千差万别,在模拟器上运行良好的程序安装到某款手机上说不定就出现崩溃的现象,开发者个人不可能购买所有设备逐个调试,所以在程序发布出去之后,如果出现了崩溃现象,开发者应该及时获取在该设备上导致崩溃的信息,这对于下一个版本的bug修复帮助极大,所以今天就来介绍一下如何在程序崩溃的情况下收集相关的设备参数信息和具体的异常信息,并发送这些信息到服务器供开发者分析和调试程序。
我们先建立一个crash项目,项目结构如图:
在MainActivity.java代码中,代码是这样写的:
package com.scott.crash;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
private String s;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
System.out.println(s.equals("any string"));
}
}
我们在这里故意制造了一个潜在的运行期异常,当我们运行程序时就会出现以下界面:
这些信息对于开发者来说帮助极大,所以我们需要将此日志文件上传到服务器,有关文件上传的技术,请参照Android中使用HTTP服务相关介绍。
不过在使用HTTP服务之前,需要确定网络畅通,我们可以使用下面的方式判断网络是否可用:
/**
* 网络是否可用
*
* @param context
* @return
*/
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager mgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo[] info = mgr.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
然后构建java,CrashServer
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Locale;
/**
* Android CrashInfo server
* @author monkey_DEV
* 时间 2013年10月17日 16:06:39
*
*/
public class CarshServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(10021);
while (true) {
Socket socket = serverSocket.accept();
String connectHostAddress = socket.getInetAddress()
.getHostAddress();
System.out.println("The" + connectHostAddress + "connected");
// 从客户端读取数据的流
BufferedReader bufferReader = new BufferedReader(
new InputStreamReader(socket.getInputStream()));
//日志存储路径
File file = new File("D:\\crashLog\\");
// 判断文件夹是否存在,如果不存在则创建文件夹
if (!file.exists()) {
file.mkdir();
}
// 将数据存数在本地文件中的流
BufferedWriter bufferWriter = new BufferedWriter(
new FileWriter("D:\\crashLog\\" + getFormatedDate()
+ ".crashLog"));
// 向客户端发送数据的流
BufferedWriter bufferWriterOutput = new BufferedWriter(
new OutputStreamWriter(socket.getOutputStream()));
// 读取客户端发来的数据,并存入本地文件
String line = null;
while ((line = bufferReader.readLine()) != null) {
bufferWriter.write(line);
bufferWriter.newLine();
bufferWriter.flush();
}
System.out.println("Application crashLog has stored.");
// 返回数据至客户端
bufferWriterOutput
.write("The device CrashInfo has been sent to the server successfully!");
bufferWriterOutput.newLine();
bufferWriterOutput.flush();
bufferWriter.close();
socket.close();
}
// serverSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private static String getFormatedDate() {
long time = System.currentTimeMillis();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH-mm-ss",
Locale.CHINA);
return f.format(time);
}
}
打开相应Crash日志查看程序崩溃原因