編輯:關於Android編程
之所以專門寫一篇關於finalize方法的博客,是因為被這個方法坑過,在寫一個讀取jni數據類的時候,我在類的finalize方法中調用了關閉文件和釋放內存的方法,結果導致在頻繁調用這個類的時候在JNI裡面報異常,類本來就是單例的,按理分析不應該存在這樣的情況,到最後分析出來就是因為在該類的finalize方法中調用了關閉文件的方法,導致下次進入再次打開文件時,被系統調用finalize方法給關閉掉了,出現異常的代碼如下。
public class TraceHandle{
static{
try{
System.loadLibrary("TraceHandle");
}catch (UnsatisfiedLinkError ule){
Log.e("JNI", "WARNING: Could not load TraceHandle.so");
}
}
private TraceHandle( String filePath ){
mFilePath = filePath;
open( filePath );
}
/**
* 實例化TraceHandle
*
* */
public static TraceHandle create( String filePath ){
if (null == mTraceHandle){
mTraceHandle = new TraceHandle( filePath);
}
mTraceHandle.mInitCount++;
return mTraceHandle;
}
/**
* 退出時銷毀TraceHandle
*
* @return null.
*/
public TraceHandle destory( ){
mInitCount--;
if (mInitCount == 0 && mTraceHandle != null){
mTraceHandle.close();
mTraceHandle = null;
}
return null;
}
private void celan(){
if (mTraceHandle != null){
mTraceHandle.close();
mTraceHandle = null;
}
}
@Override
protected void finalize() throws Throwable{
super.finalize();
//這是被系統調用的方法,系統會根據系統環境來調用,對於程序來說它的調用實際不可預見
celan();
}
// 1、打開文件
private native int open(String tracePath );
// 2、搜索指定漢字
private native int[] search(byte[] wordArray);
// 3、必須關閉文件
private native boolean close();
private int mInitCount = 0;
private String mFilePath = null;
private static TraceHandle mTraceHandle = null;
}
經過查閱資料和閱讀《JAVA核心技術》裡面相關的章節後,問題終於搞定。在《JAVA核心技術》一書中是這樣描述finalize方法的:
“可以為任何一個類添加finalize方法。finalize方法將在垃圾回收器清除對象之前調用。在實際應用中,不要依賴於使用finalize方法回收任何短缺的資源,這是因為很難知道這個方法什麼時候才能夠調用。
如果某個資源需要在使用完畢立刻被關閉,那麼就需要由人工來管理。可以應用一個類似dispose或close的放來完成相應的清理操作。特別需要說明,如果一個類使用了這樣的方法,當對象不再被使用時一定要調用它。”
修改後的代碼如下,去掉了finalize方法:
public class TraceHandle{
static{
try{
System.loadLibrary("TraceHandle");
}catch (UnsatisfiedLinkError ule){
Log.e("JNI", "WARNING: Could not load TraceHandle.so");
}
}
private TraceHandle( String filePath ){
mFilePath = filePath;
open( filePath );
}
/**
* 實例化TraceHandle
*
* */
public static TraceHandle create( String filePath ){
if (null == mTraceHandle){
mTraceHandle = new TraceHandle( filePath);
}
mTraceHandle.mInitCount++;
return mTraceHandle;
}
/**
* 退出時銷毀TraceHandle
*
* @return null.
*/
public TraceHandle destory( ){
mInitCount--;
if (mInitCount == 0 && mTraceHandle != null){
mTraceHandle.close();
mTraceHandle = null;
}
return null;
}
private void celan(){
if (mTraceHandle != null){
mTraceHandle.close();
mTraceHandle = null;
}
}
// 1、打開文件
private native int open(String tracePath );
// 2、搜索指定漢字
private native int[] search(byte[] wordArray);
// 3、必須關閉文件
private native boolean close();
private int mInitCount = 0;
private String mFilePath = null;
private static TraceHandle mTraceHandle = null;
}參考資料:
1、Why not to use finalize() method in java
2、When is the finalize() method called in Java?
Android自定義錄像(一)之錄像功能實現(附demo源碼)
引言最近在做一個項目,是有關用手機攝像頭做圖像實時識別的。所以裡面需要自定義一個錄像功能。該demo實現了錄像和錄像後文件的保存查看,錄像會實時自動對焦(AutoFocu
ViewPageerTransform深入理解,給viewpager切換加動畫
每當viewpager上一個可見或依附的頁面發生了滾動事件就會調用PageTransformer,這讓應用可以使用自定義transformation讓viewpager某
【android】仿360手機衛士的簡易設計思路及源碼
筆者最近一直忙於滿廣州的跑,實習好難找好難找,博客也是有點久沒去更新。仿360手機衛士的實現的目的更多的是出於對常用知識點的一個鞏固吧,比較適合像我這種接觸沒多久的學習者
Android 重力傳感器在游戲開發中的應用
手勢操作可以說是智能手機的一種魅力所在,前兩節給大家講解了兩種有趣的手勢操作,將它們置於游戲當中,大大提升了