Android逆シーケンス化異常EOFExceptionの解決
プロジェクトの中でずっとシーケンス化の方式でいくつかのキャッシュを配置して、今日魅族MX 5の上で反シーケンス化のキャッシュの内容が失効したことを発見して、間違いを報告します
java.io.EOFException at java.io.DataInputStream.readByte(DataInputStream.java:77) at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:505) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:752) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1113) at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:454) at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1345) at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1242) at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1835) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at java.util.ArrayList.readObject(ArrayList.java:661) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1330) at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1242) at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1835) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at com.imaginato.qravedconsumer.handler.bv.a(Unknown Source) at com.imaginato.qravedconsumer.handler.bv.a(Unknown Source) at com.imaginato.qravedconsumer.fragment.bl.a(Unknown Source) at com.imaginato.qravedconsumer.fragment.bl.doInBackground(Unknown Source) at android.os.AsyncTask$2.call(AsyncTask.java:292) at java.util.concurrent.FutureTask.run(FutureTask.java:237) 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:818)
シーケンス化されたコードは次のとおりです.
最初は、同じファイルに対してリード・スレッドとライト・スレッドが同時にストリームを確立したことによるエラーだと思っていましたが、リード・ライト・メソッドにスレッド・ロックをかけました.その後、役に立たず、リード・ライト・スレッドの時間間隔が大きく、同期はほとんど発生しません.
タスクマネージャを使用してappを強制的に閉じる場合によく発生します.
その後、シーケンス化されたファイルの破損による可能性があることが判明し、1つのスレッドでこのファイルに対して書き込み操作を実行し、スレッドが正常に終了せずに強制的に終了した場合、現在の操作のファイルが破損する可能性があるため、問題のあるコードは次の通りです.
これはFragmentのonDestroy()メソッドで、その中で「fragmentのonDestroyが実行しました!!」印刷されません.解決方法は簡単で、このIOコードをonStop()に書けばいいです.
このバグで得られた教訓は,時間をかけて操作をonDestroy()に入れないことであり,onDestroy()は実行されないか,appを実行したプロセスが終了するのを待っていない可能性があり,これはIO操作に致命的である.
java.io.EOFException at java.io.DataInputStream.readByte(DataInputStream.java:77) at java.io.ObjectInputStream.nextTC(ObjectInputStream.java:505) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:752) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at java.io.ObjectInputStream.readFieldValues(ObjectInputStream.java:1113) at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:454) at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1345) at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1242) at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1835) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at java.util.ArrayList.readObject(ArrayList.java:661) at java.lang.reflect.Method.invoke(Native Method) at java.lang.reflect.Method.invoke(Method.java:372) at java.io.ObjectInputStream.readObjectForClass(ObjectInputStream.java:1330) at java.io.ObjectInputStream.readHierarchy(ObjectInputStream.java:1242) at java.io.ObjectInputStream.readNewObject(ObjectInputStream.java:1835) at java.io.ObjectInputStream.readNonPrimitiveContent(ObjectInputStream.java:761) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1983) at java.io.ObjectInputStream.readObject(ObjectInputStream.java:1940) at com.imaginato.qravedconsumer.handler.bv.a(Unknown Source) at com.imaginato.qravedconsumer.handler.bv.a(Unknown Source) at com.imaginato.qravedconsumer.fragment.bl.a(Unknown Source) at com.imaginato.qravedconsumer.fragment.bl.doInBackground(Unknown Source) at android.os.AsyncTask$2.call(AsyncTask.java:292) at java.util.concurrent.FutureTask.run(FutureTask.java:237) 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:818)
シーケンス化されたコードは次のとおりです.
/**
* list
* @param context
* @param fileName
* @param <T>
* @return
* @author Alex
*/
public <T> List<T> getArrayListFromDisk(Context context, String fileName) {
if (context == null) return null;
ObjectInputStream ois = null;
File file = context.getCacheDir();
String path = file.getAbsolutePath().concat(fileName);
File target = new File(path);
if (!target.exists()) {
Log.i("Alex"," "+fileName);
return null;
}
List<T> arrayList = null;
synchronized (ArrayListLock) {
try {
ois = new ObjectInputStream(new FileInputStream(target));
arrayList = (ArrayList<T>) ois.readObject();
return arrayList;
} catch (ClassNotFoundException e) {
Log.i("Alex", " ", e);
} catch (IOException e) {
Log.i("Alex", " 2", e);//
} finally {
if (ois == null) return null;
try {
ois.close();
} catch (IOException e) {
Log.i("Alex", " 3", e);
}
return arrayList;
}
}
}
最初は、同じファイルに対してリード・スレッドとライト・スレッドが同時にストリームを確立したことによるエラーだと思っていましたが、リード・ライト・メソッドにスレッド・ロックをかけました.その後、役に立たず、リード・ライト・スレッドの時間間隔が大きく、同期はほとんど発生しません.
タスクマネージャを使用してappを強制的に閉じる場合によく発生します.
その後、シーケンス化されたファイルの破損による可能性があることが判明し、1つのスレッドでこのファイルに対して書き込み操作を実行し、スレッドが正常に終了せずに強制的に終了した場合、現在の操作のファイルが破損する可能性があるため、問題のあるコードは次の通りです.
@Override
public void onDestroy() {
Log.i("Alex", "fragment2 onStop ");
if (aveArrayListToDisk(getActivity(), CARDS_LIST, "/homeCards.tmp"))
JLogUtils.i("Alex", " ");
else Log.i("Alex", " ");
super.onDestroy();
Log.i("Alex", "fragment onDestroy !!!");
}
これはFragmentのonDestroy()メソッドで、その中で「fragmentのonDestroyが実行しました!!」印刷されません.解決方法は簡単で、このIOコードをonStop()に書けばいいです.
このバグで得られた教訓は,時間をかけて操作をonDestroy()に入れないことであり,onDestroy()は実行されないか,appを実行したプロセスが終了するのを待っていない可能性があり,これはIO操作に致命的である.