android 怎样写手机运行内存怎么清理文件保证程序卸载时写的

android在卸载某些程序之后,会出现一些残留文件没有随着卸载而删除掉。请问大家如何获取到这些残留文件?希望各位大牛指点指点~~~~~~
该问题被发起重新开启投票
投票剩余时间:
之前被关闭原因:
该问题被发起删除投票
投票剩余时间:
距离悬赏到期还有:
参与关闭投票者:
关闭原因:
该问题已经被锁定
锁定原因:()
保护原因:避免来自新用户不合宜或无意义的致谢、跟帖答案。
该问题已成功删除,仅对您可见,其他人不能够查看。
在api level&7上可以使用android的默认缓存目录 /Android/data/&package_name&/files/,当你的程序被卸载后,这个/Android/data/目录下的你的程序的缓存文件也被自动删除了。你可以试下,当你程序没被卸载时,/Android/data/这个目录下能看到你的包名,你把程序卸载后,你的包名在那个目录下就找不到了。你可已通过下面代码getDiskCacheDir方法生成这个文件:
public static File getDiskCacheDir(Context context, String cacheFileName) {
String cacheP
String exterState = Environment.getExternalStorageState();
cachePath = exterState.equalsIgnoreCase(Environment.MEDIA_MOUNTED)
|| (!isExternalStorageRemovable() && !exterState.equalsIgnoreCase(Environment.MEDIA_SHARED)) ? getExternalCacheDir(context).getPath()
: context.getCacheDir().getPath();
} catch (Exception e) {
File cacheDir = context.getCacheDir();
if (cacheDir == null) {
cachePath = cacheDir.getPath();
return new File(cachePath + File.separator + cacheFileName);
public static boolean isExternalStorageRemovable() {
if (Build.VERSION.SDK_INT &= 9) {
return new ExternalStorageRemovable().get();
public static File getExternalCacheDir(Context context) {
if (hasExternalCacheDir()) {
return new ExternalCacheDir().get(context);
final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
public static boolean hasExternalCacheDir() {
return Build.VERSION.SDK_INT &= Build.VERSION_CODES.FROYO;
把 /data/data/your.package.name 干掉就差不多了其他的比如 /mnt/sdcard 上的操作痕迹是不可能完全识别出来的,因为写入外部卡的时候,文件所属者并不是应用程序本身的那个账户
祝好,斑驳敬上
我觉得topkiller的意思应该是想在卸载前执行一个清理工作,将所有与APK有关的文一起删除,其中主要是SD卡上的文件,如果是/DATA目录下的话是不需要去处理的,APK没了,文件也没了,SD卡上的文件应该可以通过接收广播的方式接收到一个卸载广播,在卸载广播处理里删除。这只是我的猜测,是否能行得通不太清楚。
不是您所需,查看更多相关问题与答案
德问是一个专业的编程问答社区,请
后再提交答案
关注该问题的人
共被浏览 (13232) 次Android手机内存中文件的读写方法小结
  Android手机内存中文件的读写方法小结
这篇主要介绍了Android手机内存中文件的读写方法,实例总结了Android针对文件读写操作的相关技巧,非常具有实用价值,需要的朋友可以参考:
  如何对手机内存中的文件数据进行读写呢?
  Context提供了领个方法来打开该应用程序的数据文件夹中的文件I/O流,具体如下:
FileInputStream openFileInput(String
  打开应用程序的数据文件夹下的name文件对应的数据流
FileOutputSream openFileOutput(String name, int mode)
  打开应用程序数据文件夹下的name文件对应的输出流,mode指定文件打开的模式,该模式主要有一下4种:
  ①MODE_PRIVATE(该文件只能被当前应用程序读写)
  ②MODE_APPEND(以追加方式打开,可以在文件中追加内容)
  ③MODE_WORLD_READABLE(该文件内容可以被其他应用程序读取)
  ④MODE_WORLD_WRITEABLE(该文件内容可以被其他应用程序度,写)
  读取文件:
  假设name为要打开的文件名字
FileInputStream f = openFileInput(name);
byte[] buf = new byte[1024];
int hasRead = 0;
StringBuilder sb = new StringBuilder("");
while((hasRead =
f.read(buf)&0))
sb.append(new String(buf, 0
, hasRead));
f.close();
  获取文件内容字符串:
sb.toString();
  写文件:
  假设要写入的字符串为content
FileOutputStream f = openFileOutput(name,MODE_APPEND);
PrintStream temp = new PrintStream(f);
temp.println(content);
temp.close();
  注:应用程序的数据文件默认保存在/data/datea
/files目录下,使用openFileInput和openFileOutput方法来打开文件输入流,输出流时,打开的都是应用程序的数据文件夹里的文件,也就是说是在手机内存中的文件,而不是SD卡中的文件。
  希望本文所述对大家的Android程序设计有所帮助。博客分类:
在调试的时候一般都是在logcat中看日志的信息,以便找出BUG和调试信息,但是如果在真机上的话不可能一直连接电脑查看日志,所以生成日志文件并保存,是一个比较普遍的需求,下面就是最近实现的一个例子。欢迎大家讨论并给出别的思路。
import java.io.BufferedR
import java.io.F
import java.io.FileInputS
import java.io.FileOutputS
import java.io.IOE
import java.io.InputS
import java.io.InputStreamR
import java.io.OutputStreamW
import java.text.ParseE
import java.text.SimpleDateF
import java.util.ArrayL
import java.util.A
import java.util.C
import java.util.C
import java.util.D
import java.util.L
import android.app.AlarmM
import android.app.PendingI
import android.app.S
import android.content.BroadcastR
import android.content.C
import android.content.I
import android.content.IntentF
import android.os.E
import android.os.IB
import android.os.PowerM
import android.os.PowerManager.WakeL
import android.util.L
* 日志服务,日志默认会存储在SDcar里如果没有SDcard会存储在内存中的安装目录下面。
* 1.本服务默认在SDcard中每天生成一个日志文件,
* 2.如果有SDCard的话会将之前内存中的文件拷贝到SDCard中
* 3.如果没有SDCard,在安装目录下只保存当前在写日志
* 4.SDcard的装载卸载动作会在步骤2,3中切换
* 5.SDcard中的日志文件只保存7天
* @author Administrator
public class LogService extends Service {
private static final String TAG = "LogService";
private static final int MEMORY_LOG_FILE_MAX_SIZE = 10 * 1024 * 1024;
//内存中日志文件最大值,10M
private static final int MEMORY_LOG_FILE_MONITOR_INTERVAL = 10 * 60 * 1000;
//内存中的日志文件大小监控时间间隔,10分钟
private static final int SDCARD_LOG_FILE_SAVE_DAYS = 7;
//sd卡中日志文件的最多保存天数
private String LOG_PATH_MEMORY_DIR;
//日志文件在内存中的路径(日志文件在安装目录中的路径)
private String LOG_PATH_SDCARD_DIR;
//日志文件在sdcard中的路径
@SuppressWarnings("unused")
private String LOG_SERVICE_LOG_PATH; //本服务产生的日志,记录日志服务开启失败信息
private final int SDCARD_TYPE = 0;
//当前的日志记录类型为存储在SD卡下面
private final int MEMORY_TYPE = 1;
//当前的日志记录类型为存储在内存中
private int CURR_LOG_TYPE = SDCARD_TYPE; //当前的日志记录类型
private String CURR_INSTALL_LOG_NAME; //如果当前的日志写在内存中,记录当前的日志文件名称
private String logServiceLogName = "Log.log";//本服务输出的日志文件名称
private SimpleDateFormat myLogSdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
private OutputStreamW
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HHmmss");//日志名称格式
private WakeLock wakeL
private SDStateMonitorReceiver sdStateR //SDcard状态监测
private LogTaskReceiver logTaskR
/* 是否正在监测日志文件大小;
* 如果当前日志记录在SDcard中则为false
* 如果当前日志记录在内存中则为true*/
private boolean logSizeMoniting =
private static String MONITOR_LOG_SIZE_ACTION = "MONITOR_LOG_SIZE";
//日志文件监测action
private static String SWITCH_LOG_FILE_ACTION = "SWITCH_LOG_FILE_ACTION"; //切换日志文件action
public IBinder onBind(Intent intent) {
public void onCreate() {
super.onCreate();
register();
deploySwitchLogFileTask();
new LogCollectorThread().start();
private void init(){
LOG_PATH_MEMORY_DIR = getFilesDir().getAbsolutePath() + File.separator + "log";
LOG_SERVICE_LOG_PATH = LOG_PATH_MEMORY_DIR + File.separator + logServiceLogN
LOG_PATH_SDCARD_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator
+ "MyApp" + File.separator + "log";
createLogDir();
/* ******************************************************
writer = new OutputStreamWriter(new FileOutputStream(
LOG_SERVICE_LOG_PATH, true));
} catch (FileNotFoundException e) {
Log.e(TAG, e.getMessage(), e);
* ******************************************************/
PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
CURR_LOG_TYPE = getCurrLogType();
Log.i(TAG, "LogService onCreate");
private void register(){
IntentFilter sdCarMonitorFilter = new IntentFilter();
sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_MOUNTED);
sdCarMonitorFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
sdCarMonitorFilter.addDataScheme("file");
sdStateReceiver = new SDStateMonitorReceiver();
registerReceiver(sdStateReceiver, sdCarMonitorFilter);
IntentFilter logTaskFilter = new IntentFilter();
logTaskFilter.addAction(MONITOR_LOG_SIZE_ACTION);
logTaskFilter.addAction(SWITCH_LOG_FILE_ACTION);
logTaskReceiver = new LogTaskReceiver();
registerReceiver(logTaskReceiver,logTaskFilter);
* 获取当前应存储在内存中还是存储在SDCard中
public int getCurrLogType(){
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
return MEMORY_TYPE;
return SDCARD_TYPE;
* 部署日志切换任务,每天凌晨切换日志文件
private void deploySwitchLogFileTask() {
Intent intent = new Intent(SWITCH_LOG_FILE_ACTION);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, 1);
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
// 部署任务
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, sender);
recordLogServiceLog("deployNextTask succ,next task time is:"+myLogSdf.format(calendar.getTime()));
* 日志收集
* 1.清除日志缓存
* 2.杀死应用程序已开启的Logcat进程防止多个进程写入一个日志文件
* 3.开启日志收集进程
* 4.处理日志文件
移动 OR 删除
class LogCollectorThread extends Thread {
public LogCollectorThread(){
super("LogCollectorThread");
Log.d(TAG, "LogCollectorThread is create");
public void run() {
wakeLock.acquire(); //唤醒手机
clearLogCache();
List&String& orgProcessList = getAllProcess();
List&ProcessInfo& processInfoList = getProcessInfoList(orgProcessList);
killLogcatProc(processInfoList);
createLogCollector();
Thread.sleep(1000);//休眠,创建文件,然后处理文件,不然该文件还没创建,会影响文件删除
handleLog();
wakeLock.release(); //释放
} catch (Exception e) {
e.printStackTrace();
recordLogServiceLog(Log.getStackTraceString(e));
* 每次记录日志之前先清除日志的缓存, 不然会在两个日志文件中记录重复的日志
private void clearLogCache() {
Process proc =
List&String& commandList = new ArrayList&String&();
commandList.add("logcat");
commandList.add("-c");
proc = Runtime.getRuntime().exec(
commandList.toArray(new String[commandList.size()]));
StreamConsumer errorGobbler = new StreamConsumer(proc
.getErrorStream());
StreamConsumer outputGobbler = new StreamConsumer(proc
.getInputStream());
errorGobbler.start();
outputGobbler.start();
if (proc.waitFor() != 0) {
Log.e(TAG, " clearLogCache proc.waitFor() != 0");
recordLogServiceLog("clearLogCache clearLogCache proc.waitFor() != 0");
} catch (Exception e) {
Log.e(TAG, "clearLogCache failed", e);
recordLogServiceLog("clearLogCache failed");
} finally {
proc.destroy();
} catch (Exception e) {
Log.e(TAG, "clearLogCache failed", e);
recordLogServiceLog("clearLogCache failed");
* 关闭由本程序开启的logcat进程:
* 根据用户名称杀死进程(如果是本程序进程开启的Logcat收集进程那么两者的USER一致)
* 如果不关闭会有多个进程读取logcat日志缓存信息写入日志文件
* @param allProcList
private void killLogcatProc(List&ProcessInfo& allProcList) {
if(process != null){
process.destroy();
String packName = this.getPackageName();
String myUser = getAppUser(packName, allProcList);
recordLogServiceLog("app user is:"+myUser);
recordLogServiceLog("========================");
for (ProcessInfo processInfo : allProcList) {
recordLogServiceLog(processInfo.toString());
recordLogServiceLog("========================");
for (ProcessInfo processInfo : allProcList) {
if (processInfo.name.toLowerCase().equals("logcat")
&& processInfo.user.equals(myUser)) {
android.os.Process.killProcess(Integer
.parseInt(processInfo.pid));
//recordLogServiceLog("kill another logcat process success,the process info is:"
+ processInfo);
* 获取本程序的用户名称
* @param packName
* @param allProcList
private String getAppUser(String packName, List&ProcessInfo& allProcList) {
for (ProcessInfo processInfo : allProcList) {
if (processInfo.name.equals(packName)) {
return processInfo.
* 根据ps命令得到的内容获取PID,User,name等信息
* @param orgProcessList
private List&ProcessInfo& getProcessInfoList(List&String& orgProcessList) {
List&ProcessInfo& procInfoList = new ArrayList&ProcessInfo&();
for (int i = 1; i & orgProcessList.size(); i++) {
String processInfo = orgProcessList.get(i);
String[] proStr = processInfo.split(" ");
// USER PID PPID VSIZE RSS WCHAN PC NAME
// root 1 0 416 300 c00d4b28 0000cd5c S /init
List&String& orgInfo = new ArrayList&String&();
for (String str : proStr) {
if (!"".equals(str)) {
orgInfo.add(str);
if (orgInfo.size() == 9) {
ProcessInfo pInfo = new ProcessInfo();
pInfo.user = orgInfo.get(0);
pInfo.pid = orgInfo.get(1);
pInfo.ppid = orgInfo.get(2);
pInfo.name = orgInfo.get(8);
procInfoList.add(pInfo);
return procInfoL
* 运行PS命令得到进程信息
USER PID PPID VSIZE RSS WCHAN PC NAME
root 1 0 416 300 c00d4b28 0000cd5c S /init
private List&String& getAllProcess() {
List&String& orgProcList = new ArrayList&String&();
Process proc =
proc = Runtime.getRuntime().exec("ps");
StreamConsumer errorConsumer = new StreamConsumer(proc
.getErrorStream());
StreamConsumer outputConsumer = new StreamConsumer(proc
.getInputStream(), orgProcList);
errorConsumer.start();
outputConsumer.start();
if (proc.waitFor() != 0) {
Log.e(TAG, "getAllProcess proc.waitFor() != 0");
recordLogServiceLog("getAllProcess proc.waitFor() != 0");
} catch (Exception e) {
Log.e(TAG, "getAllProcess failed", e);
recordLogServiceLog("getAllProcess failed");
} finally {
proc.destroy();
} catch (Exception e) {
Log.e(TAG, "getAllProcess failed", e);
recordLogServiceLog("getAllProcess failed");
return orgProcL
* 开始收集日志信息
public void createLogCollector() {
String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称
List&String& commandList = new ArrayList&String&();
commandList.add("logcat");
commandList.add("-f");
//commandList.add(LOG_PATH_INSTALL_DIR + File.separator + logFileName);
commandList.add(getLogPath());
commandList.add("-v");
commandList.add("time");
commandList.add("*:I");
//commandList.add("*:E");// 过滤所有的错误信息
// 过滤指定TAG的信息
// commandList.add("MyAPP:V");
// commandList.add("*:S");
process = Runtime.getRuntime().exec(
commandList.toArray(new String[commandList.size()]));
recordLogServiceLog("start collecting the log,and log name is:"+logFileName);
// process.waitFor();
} catch (Exception e) {
Log.e(TAG, "CollectorThread == &" + e.getMessage(), e);
recordLogServiceLog("CollectorThread == &" + e.getMessage());
* 根据当前的存储位置得到日志的绝对存储路径
public String getLogPath(){
createLogDir();
String logFileName = sdf.format(new Date()) + ".log";// 日志文件名称
if(CURR_LOG_TYPE == MEMORY_TYPE){
CURR_INSTALL_LOG_NAME = logFileN
Log.d(TAG, "Log stored in memory, the path is:"+LOG_PATH_MEMORY_DIR + File.separator + logFileName);
return LOG_PATH_MEMORY_DIR + File.separator + logFileN
CURR_INSTALL_LOG_NAME =
Log.d(TAG, "Log stored in SDcard, the path is:"+LOG_PATH_SDCARD_DIR + File.separator + logFileName);
return LOG_PATH_SDCARD_DIR + File.separator + logFileN
* 处理日志文件
* 1.如果日志文件存储位置切换到内存中,删除除了正在写的日志文件
并且部署日志大小监控任务,控制日志大小不超过规定值
* 2.如果日志文件存储位置切换到SDCard中,删除7天之前的日志,移
动所有存储在内存中的日志到SDCard中,并将之前部署的日志大小
public void handleLog(){
if(CURR_LOG_TYPE == MEMORY_TYPE){
deployLogSizeMonitorTask();
deleteMemoryExpiredLog();
moveLogfile();
cancelLogSizeMonitorTask();
deleteSDcardExpiredLog();
* 部署日志大小监控任务
private void deployLogSizeMonitorTask() {
if(logSizeMoniting){ //如果当前正在监控着,则不需要继续部署
logSizeMoniting =
Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.setRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis(), MEMORY_LOG_FILE_MONITOR_INTERVAL, sender);
Log.d(TAG, "deployLogSizeMonitorTask() succ !");
//recordLogServiceLog("deployLogSizeMonitorTask() succ ,start time is " + calendar.getTime().toLocaleString());
* 取消部署日志大小监控任务
private void cancelLogSizeMonitorTask() {
logSizeMoniting =
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent intent = new Intent(MONITOR_LOG_SIZE_ACTION);
PendingIntent sender = PendingIntent.getBroadcast(this, 0, intent, 0);
am.cancel(sender);
Log.d(TAG, "canelLogSizeMonitorTask() succ");
* 检查日志文件大小是否超过了规定大小
* 如果超过了重新开启一个日志收集进程
private void checkLogSize(){
if(CURR_INSTALL_LOG_NAME != null && !"".equals(CURR_INSTALL_LOG_NAME)){
String path = LOG_PATH_MEMORY_DIR + File.separator + CURR_INSTALL_LOG_NAME;
File file = new File(path);
if(!file.exists()){
Log.d(TAG, "checkLog() ==& The size of the log is too big?");
if(file.length() &= MEMORY_LOG_FILE_MAX_SIZE){
Log.d(TAG, "The log's size is too big!");
new LogCollectorThread().start();
* 创建日志目录
private void createLogDir() {
File file = new File(LOG_PATH_MEMORY_DIR);
boolean mkOk;
if (!file.isDirectory()) {
mkOk = file.mkdirs();
if (!mkOk) {
mkOk = file.mkdirs();
/* ************************************
file = new File(LOG_SERVICE_LOG_PATH);
if (!file.exists()) {
mkOk = file.createNewFile();
if (!mkOk) {
file.createNewFile();
} catch (IOException e) {
Log.e(TAG, e.getMessage(), e);
* ************************************/
if (Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
file = new File(LOG_PATH_SDCARD_DIR);
if (!file.isDirectory()) {
mkOk = file.mkdirs();
if (!mkOk) {
recordLogServiceLog("move file failed,dir is not created succ");
* 将日志文件转移到SD卡下面
private void moveLogfile() {
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
//recordLogServiceLog("move file failed, sd card does not mount");
File file = new File(LOG_PATH_SDCARD_DIR);
if (!file.isDirectory()) {
boolean mkOk = file.mkdirs();
if (!mkOk) {
//recordLogServiceLog("move file failed,dir is not created succ");
file = new File(LOG_PATH_MEMORY_DIR);
if (file.isDirectory()) {
File[] allFiles = file.listFiles();
for (File logFile : allFiles) {
String fileName = logFile.getName();
if (logServiceLogName.equals(fileName)) {
//String createDateInfo = getFileNameWithoutExtension(fileName);
boolean isSucc = copy(logFile, new File(LOG_PATH_SDCARD_DIR
+ File.separator + fileName));
if (isSucc) {
logFile.delete();
//recordLogServiceLog("move file success,log name is:"+fileName);
* 删除内存下过期的日志
private void deleteSDcardExpiredLog() {
File file = new File(LOG_PATH_SDCARD_DIR);
if (file.isDirectory()) {
File[] allFiles = file.listFiles();
for (File logFile : allFiles) {
String fileName = logFile.getName();
if (logServiceLogName.equals(fileName)) {
String createDateInfo = getFileNameWithoutExtension(fileName);
if (canDeleteSDLog(createDateInfo)) {
logFile.delete();
Log.d(TAG, "delete expired log success,the log path is:"
+ logFile.getAbsolutePath());
* 判断sdcard上的日志文件是否可以删除
* @param createDateStr
public boolean canDeleteSDLog(String createDateStr) {
boolean canDel =
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_MONTH, -1 * SDCARD_LOG_FILE_SAVE_DAYS);//删除7天之前日志
Date expiredDate = calendar.getTime();
Date createDate = sdf.parse(createDateStr);
canDel = createDate.before(expiredDate);
} catch (ParseException e) {
Log.e(TAG, e.getMessage(), e);
return canD
* 删除内存中的过期日志,删除规则:
* 除了当前的日志和离当前时间最近的日志保存其他的都删除
private void deleteMemoryExpiredLog(){
File file = new File(LOG_PATH_MEMORY_DIR);
if (file.isDirectory()) {
File[] allFiles = file.listFiles();
Arrays.sort(allFiles, new FileComparator());
for (int i=0;i&allFiles.length-2;i++) { //"-2"保存最近的两个日志文件
File _file =
allFiles[i];
if (logServiceLogName.equals(_file.getName()) ||
_file.getName().equals(CURR_INSTALL_LOG_NAME)) {
_file.delete();
Log.d(TAG, "delete expired log success,the log path is:"+_file.getAbsolutePath());
* 拷贝文件
* @param source
* @param target
private boolean copy(File source, File target) {
FileInputStream in =
FileOutputStream out =
if(!target.exists()){
boolean createSucc = target.createNewFile();
if(!createSucc){
in = new FileInputStream(source);
out = new FileOutputStream(target);
byte[] buffer = new byte[8*1024];
while ((count = in.read(buffer)) != -1) {
out.write(buffer, 0, count);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, e.getMessage(), e);
recordLogServiceLog("copy file fail");
} finally{
if(in != null){
in.close();
if(out != null){
out.close();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage(), e);
recordLogServiceLog("copy file fail");
* 记录日志服务的基本信息 防止日志服务有错,在LogCat日志中无法查找
* 此日志名称为Log.log
* @param msg
private void recordLogServiceLog(String msg) {
if (writer != null) {
Date time = new Date();
writer.write(myLogSdf.format(time) + " : " + msg);
writer.write("\n");
writer.flush();
} catch (IOException e) {
e.printStackTrace();
Log.e(TAG, e.getMessage(), e);
* 去除文件的扩展类型(.log)
* @param fileName
private String getFileNameWithoutExtension(String fileName){
return fileName.substring(0, fileName.indexOf("."));
class ProcessInfo {
public String toString() {
String str = "user=" + user + " pid=" + pid + " ppid=" + ppid
+ " name=" +
class StreamConsumer extends Thread {
List&String&
StreamConsumer(InputStream is) {
StreamConsumer(InputStream is, List&String& list) {
this.list =
public void run() {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line =
while ((line = br.readLine()) != null) {
if (list != null) {
list.add(line);
} catch (IOException ioe) {
ioe.printStackTrace();
* 监控SD卡状态
* @author Administrator
class SDStateMonitorReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
if(Intent.ACTION_MEDIA_UNMOUNTED.equals(intent.getAction())){ //存储卡被卸载
if(CURR_LOG_TYPE == SDCARD_TYPE){
Log.d(TAG, "SDcar is UNMOUNTED");
CURR_LOG_TYPE = MEMORY_TYPE;
new LogCollectorThread().start();
//存储卡被挂载
if(CURR_LOG_TYPE == MEMORY_TYPE){
Log.d(TAG, "SDcar is MOUNTED");
CURR_LOG_TYPE = SDCARD_TYPE;
new LogCollectorThread().start();
* 日志任务接收
* 切换日志,监控日志大小
* @author Administrator
class LogTaskReceiver extends BroadcastReceiver{
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(SWITCH_LOG_FILE_ACTION.equals(action)){
new LogCollectorThread().start();
}else if(MONITOR_LOG_SIZE_ACTION.equals(action)){
checkLogSize();
class FileComparator implements Comparator&File&{
public int compare(File file1, File file2) {
if(logServiceLogName.equals(file1.getName())){
return -1;
}else if(logServiceLogName.equals(file2.getName())){
String createInfo1 = getFileNameWithoutExtension(file1.getName());
String createInfo2 = getFileNameWithoutExtension(file2.getName());
Date create1 = sdf.parse(createInfo1);
Date create2 = sdf.parse(createInfo2);
if(create1.before(create2)){
return -1;
} catch (ParseException e) {
public void onDestroy() {
super.onDestroy();
recordLogServiceLog("LogService onDestroy");
if (writer != null) {
writer.close();
} catch (IOException e) {
e.printStackTrace();
if (process != null) {
process.destroy();
unregisterReceiver(sdStateReceiver);
unregisterReceiver(logTaskReceiver);
最后不要忘记在配置文件中加入
&uses-permission android:name="android.permission.READ_LOGS" /&
浏览 28829
while ((line = br.readLine()) != null) 具体的是这行代码出错的貌似是这里有点不对劲,为什么呢???
楼主,您好,我在测试您的代码的时候,文件生成不了。在run()里面抛出的异常, java.io.IOException: stream is closed,在xml中加入了&uses-permission android:name="android.permission.READ_LOGS" /&& &uses-permission android:name="android.permission.WAKE_LOCK" /&,求指导?非常感谢楼主这个问题怎么处理的呀? 我发现是引文proc.waitFor() 这句没有起到等待的作用,所以造成继续向下执行finally语句的proc.destroy(),从而关闭了流,造成readLine的异常。但是waitFor()的APi说明是应该阻塞,等待proc执行结束呀。求楼主解释一下为什么呀?
LZ如果可能,能给一份源码么?这已经是剥离出来的源码了直接可以用的
补充一下,服务启动了,但没有生成文件,只生成目录walktour----&log ,LOG下面没有文件。楼主请帮忙一下同样的错误,&uses-permission android:name="android.permission.READ_LOGS" /&权限已经加入,不过还是只生成目录。peter_ims 写道您好,我用Intent stateService =& new Intent (this,LogService.class);startService( stateService ); 我在一个Activity里启动服务后,只生成目录,没有文件。后来在查看LogService,发现LogService都没有启动,但奇怪为什么又生成目录了这个问题应该是service生命周期的。可能是sercice没有死的原因。
补充一下,服务启动了,但没有生成文件,只生成目录walktour----&log ,LOG下面没有文件。楼主请帮忙一下有没有加入&uses-permission android:name="android.permission.READ_LOGS" /&
菜鸟问题:怎么使用LogService?Intent stateService =& new Intent (this,com.app.service.app.LogService.class);startService( stateService );
& 上一页 1
easion_zms
浏览: 79462 次
来自: 珠海
09-10 03:56:07.128: D/LogServic ...
&div class=&quote_title ...
成功,楼主好厉害。接下来看看咋用吧
垃圾残品,发出来很好玩的样子
&div class=&quote_title ...
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'}

我要回帖

更多关于 手机运行内存怎么清理 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信