Google Play에 어제 업데이트 된 앱이 있습니다. 앱이 Android 4.x가 설치된 삼성 기기에서만 충돌하는 Crashlytics에서 수많은 보고서를 받기 시작했습니다 (4.1.2 - 4.4.4).Android 기기의 경우에만 java.lang.OutOfMemoryError가 적용됩니다.
다음과 같이 예외의 추적은 다음과 같습니다 나는 다음과 같은 추적받은 다른 경우
Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
Caused by java.lang.OutOfMemoryError
at java.util.Arrays.copyOfRange(Arrays.java:2684)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:467)
at javax.crypto.Cipher.doFinal(Cipher.java:1204)
at com.ijsoft.cpul.Util.DbMainFunctions.com.ijsoft.cpul.Util.AES256Cipher.decrypt(DbMainFunctions.java:2059)
at com.ijsoft.cpul.Util.DbMainFunctions.initializeDb(DbMainFunctions.java:94)
at com.ijsoft.cpul.SplashActivity$InitializeDb.doInBackground$9ecd34e(SplashActivity.java:2095)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
: 오류가 발생하는 위치
Fatal Exception: java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:299)
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)
at java.util.concurrent.FutureTask.setException(FutureTask.java:124)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
Caused by java.lang.OutOfMemoryError
at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:201)
at com.ijsoft.cpul.Util.DbMainFunctions.initializeDb(DbMainFunctions.java:90)
at com.ijsoft.cpul.SplashActivity$InitializeDb.doInBackground$9ecd34e(SplashActivity.java:2095)
at android.os.AsyncTask$2.call(AsyncTask.java:287)
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)
at java.util.concurrent.FutureTask.run(FutureTask.java:137)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
at java.lang.Thread.run(Thread.java:856)
나는 코드의 일부를 남겨 :
AES256Cipher.java
APK에 포함 된 자산 디렉토리에서 AES256와 (자산 파일 이름) 그 시점이 암호화 된 파일을 얻을 수 있습니다에서DbMainFunctions.java
public synchronized static int initializeDb(int release, Context context) {
int resultCode = 0;
try {
// Get the encrypted json file (database) from Assets
AssetManager am = context.getAssets();
InputStream is = am.open("assets");
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buff = new byte[4096];
int i;
while ((i = is.read(buff, 0, buff.length)) > 0) {
baos.write(buff, 0, i);
}
is.close();
baos.close();
resultCode = updateDb(baos.toByteArray(), release, context);
//baos.close();
} catch (Exception e) {
Log.e("DbMainFunctions", e.getMessage());
//e.printStackTrace();
resultCode = -1;
}
return resultCode;
}
public synchronized static int updateDb(byte[] cipherJson, int release, Context context) {
int resultCode = 0;
AES256Cipher aes256;
try {
aes256 = new AES256Cipher();
cipherJson = aes256.decrypt(cipherJson, context);
} catch (UnsupportedEncodingException | NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException |
InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
Log.e("DbMainFuctions", e.getMessage());
return -2;
}
...
}
내 응용 프로그램 않습니다. 그런 다음 파일이 해독되고 Byte Array에 저장됩니다. 파일의 크기는 약 4.4MB입니다. initializeDb() 메서드는 doInBackground()에서 AsyncTask에서 호출됩니다. 즉, 이전 코드가 모두 AsyncTask에서 실행됩니다.