android突然无访问内存,各位遇到过对自己的内部存储空间没有访问权限的情况吗?...

收集崩溃log的代码

package packagename.report;

import android.content.Context;

import android.content.SharedPreferences;

import android.database.sqlite.SQLiteCantOpenDatabaseException;

import android.os.SystemClock;

import packagename.LauncherProvider;

import packagename.next.utils.ErrorReportUtils;

import packagename.timeline.TimelineUtils;

import java.io.BufferedReader;

import java.io.File;

import java.io.IOException;

import java.io.InputStreamReader;

import java.util.Random;

import androidx.annotation.Keep;

/**

* @author SHBU

*/

public class SqlCantOpenCrashAnalyzer {

private static boolean chmodRetried = false;

/**

* a workaround for online crash: sql open exception

*

* @param context

*/

public static void uploadDatabaseFileInfoAndRetry(Context context, String dbName, SQLiteCantOpenDatabaseException sqlCantOpen) {

// collect file info

StringBuilder stringBuilder = new StringBuilder();

int retryTime = 0;

try {

String key = "retryTime";

SharedPreferences testSP = context.getSharedPreferences("sqlCrashTestSP", Context.MODE_PRIVATE);

retryTime = testSP.getInt(key, 0);

testSP.edit().putInt(key, ++retryTime).commit();

stringBuilder.append("\nretryTime:").append(retryTime);

} catch (Throwable e) {

e.printStackTrace();

stringBuilder.append("\nSPExpt:").append(e.getMessage()).append(",type:").append(e.getClass().getName());

}

if (retryTime > 8) {

android.os.Process.killProcess(android.os.Process.myPid());

return;

}

// abs path should be /data/user/0/packagename/databases/launcher.db

File databaseFile = context.getDatabasePath(dbName);

// abs path should be /data/user/0/packagename/files

File filesDir = context.getFilesDir();

// abs path should be /data/user/0/packagename/cache

File cacheDir = context.getCacheDir();

File eCacheDir = context.getExternalCacheDir();

File userDir = new File("/data/user");

// abs path should be /data/user/0/packagename/databases

File databaseDir = databaseFile.getParentFile();

// abs path should be /data/user/0/packagename

File homeDir = databaseDir.getParentFile();

// abs path should be /data/user/0/packagename

File homeDir1 = filesDir.getParentFile();

// runCommAndLog("getenforce", "getenforce", stringBuilder);// no permission for exec this command

logFileInfoAndTryChmodForDir(context, databaseFile, stringBuilder);

logFileInfoAndTryChmodForDir(context, databaseDir, stringBuilder);

logFileInfoAndTryChmodForDir(context, homeDir, stringBuilder);

logFileInfoAndTryChmodForDir(context, filesDir, stringBuilder);

if (!homeDir.getAbsolutePath().equals(homeDir1.getAbsolutePath())) {

logFileInfoAndTryChmodForDir(context, homeDir1, stringBuilder);

}

logFileInfoAndTryChmodForDir(context, cacheDir, stringBuilder);

logFileInfoAndTryChmodForDir(context, eCacheDir, stringBuilder);

boolean fileExist = databaseFile.exists();

boolean deleteSucc = false;

if (fileExist) {

boolean fileIsDirectory = databaseFile.isDirectory();

if (fileIsDirectory) {

boolean fileIsDirectoryDeletable = databaseFile.delete();

stringBuilder.append("\ndbFileDirectoryDeletable: ").append(fileIsDirectoryDeletable);

if (fileIsDirectoryDeletable) {

deleteSucc = true;

}

} else {

// try delete db file

try {

deleteSucc = databaseFile.delete();

stringBuilder.append("\ndbFileCanDelete: ").append(deleteSucc);

// if rename strategy once worked and try rename it to the original one

if (deleteSucc && !LauncherProvider.useNewDBName) {

File dbFile = context.getDatabasePath(LauncherProvider.DATABASE_NAME_NEW);

if (dbFile.exists()) {

boolean renameTo = dbFile.renameTo(context.getDatabasePath(LauncherProvider.DATABASE_NAME));

stringBuilder.append("\ndbFileCanRenameTo: ").append(renameTo);

}

}

} catch (Throwable e) {

stringBuilder.append("\ndbFileCanDelete: ").append("exception:").append(e.getClass().getName()).append("-").append(e.getMessage());

}

}

}

String timelineEnabled;

try {

boolean timelineOn = TimelineUtils.isTimelineEnabled(context);

if (timelineOn) {

timelineEnabled = "y";

} else {

timelineEnabled = "n";

}

} catch (Throwable e) {

timelineEnabled = "error:" + e.getMessage() + ", " + e.getClass().getName();

e.printStackTrace();

}

stringBuilder.append("\ntimelineOn").append(timelineEnabled);

String message = stringBuilder.append("\noriginal message: ").append(sqlCantOpen.getMessage()).toString();

logFileInfoAndTryChmodForDir(context, userDir, stringBuilder);

// already retried with new DB name, no need to retry

if (LauncherProvider.useNewDBName) {

onAllMethodFailed(context, sqlCantOpen, message);

return;

}

if (!deleteSucc) {

LauncherProvider.useNewDBName = true;

}

throw new RetryException(message);

}

public static void onAllMethodFailed(Context context, Throwable throwable, String message) {

Random random = new Random();

int i = random.nextInt(100);

RuntimeException runtimeException = new RuntimeException(message, throwable);

if (i == 0) {

throw runtimeException;

} else {

ErrorReportUtils.sendErrorEvent("All Failed!" + message, runtimeException);

// before suicide, sleep main thread to give sendError thread more time

SystemClock.sleep(3 * 1000);

// just kill launcher to avoid too many crash upload

android.os.Process.killProcess(android.os.Process.myPid());

}

}

private static void logFileInfoAndTryChmodForDir(Context context, File file, StringBuilder stringBuilder) {

if (file == null) {

stringBuilder.append("\nfileObj: ").append("null");

return;

}

long freeSpace = file.getFreeSpace();

long totalSpace = file.getTotalSpace();

long usableSpace = file.getUsableSpace();

stringBuilder.append("\nfilePath: ").append(file.getAbsolutePath());

stringBuilder.append("\npFUTSpace: ").append(freeSpace).append(",").append(usableSpace).append(",").append(totalSpace);

boolean fileExist = file.exists();

stringBuilder.append("\nfileExist: ").append(fileExist);

if (fileExist) {

stringBuilder.append("\nfileCanRead: ").append(file.canRead());

stringBuilder.append("\nfileCanWrite: ").append(file.canWrite());

stringBuilder.append("\nfileCanExecute: ").append(file.canExecute());

stringBuilder.append("\nfileLength: ").append(file.length());

boolean fileIsDirectory = file.isDirectory();

stringBuilder.append("\nfileIsDirectory: ").append(fileIsDirectory);

}

runCommAndLog("ls -Zl " + file.getAbsolutePath(), "ls", stringBuilder);

int exitCode = runCommAndLog("chmod -R 770 " + file.getAbsolutePath(), "chmod", stringBuilder);

// trigger retry

if (exitCode == 0 && !chmodRetried) {

chmodRetried = true;

throw new RetryException("chmod succ!" + stringBuilder.append("\nEnd.").toString());

} else {

runCommAndLog("restorecon -RF " + file.getAbsolutePath(), "restorecon", stringBuilder);

stringBuilder.append("\nchmodRetried: ").append(chmodRetried);

}

}

private static int runCommAndLog(String comm, String preffix, StringBuilder stringBuilder) {

java.lang.Process exec = null;

BufferedReader bufferedReader = null;

int exitCode = -1;

stringBuilder.append("\ncomm: ").append(comm);

try {

exec = Runtime.getRuntime().exec(comm);

exitCode = exec.waitFor();

if (exitCode == 0) {

bufferedReader = new BufferedReader(new InputStreamReader(exec.getInputStream()));

stringBuilder.append("\n").append(preffix).append("Output: ");

} else {

stringBuilder.append("\nerrorCode: ").append(exitCode);

bufferedReader = new BufferedReader(new InputStreamReader(exec.getErrorStream()));

stringBuilder.append("\n").append(preffix).append("ErrorOutput: ");

}

String line = null;

while ((line = bufferedReader.readLine()) != null) {

stringBuilder.append(line).append('\n');

}

stringBuilder.append(".");

} catch (Throwable ex) {

stringBuilder.append("\n").append(preffix).append("Exception: ").append(ex.getClass().getName()).append(":").append(ex.getMessage());

ex.printStackTrace();

} finally {

if (exec != null) {

exec.destroy();

}

if (bufferedReader != null) {

try {

bufferedReader.close();

} catch (IOException e1) {

e1.printStackTrace();

}

}

}

return exitCode;

}

@Keep

public static class RetryException extends RuntimeException {

RetryException(String message) {

super(message);

}

RetryException(String message, Throwable e) {

super(message, e);

}

}

}

`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值