我想用Java Midlet在諾基亞手機上反覆捕獲音頻片段。我目前的經驗是,使用Sun文檔中的代碼(請參閱:http://java.sun.com/javame/reference/apis/jsr135/javax/microedition/media/control/RecordControl.html)並將其包裝在「while(true)」循環中,但應用程序會慢慢佔用手機上的所有內存,程序最終會拋出異常並失敗開始進一步錄製。如果沒有JVM泄漏內存,您是否可以在諾基亞手機(N80/N95)上用Java Midlet錄製音頻?
消耗的內存不是Java堆內存---我的示例程序(如下)顯示Java內存大致保持靜態大約185,000字節---但底層支持庫中存在某種內存泄漏由諾基亞;我相信會發生內存泄漏,因爲如果您在運行Java應用程序一段時間後嘗試啓動另一個(非Java)應用程序(例如,Web瀏覽器),則手機將針對缺少內存的警告殺死該應用程序。
我已經嘗試了幾種不同的方法,從文檔中的Sun規範示例中採用了幾種不同的方法(每次初始化每個循環的循環,儘可能多地初始化一次,調用盡可能多的deallocate樣式的函數,絕對必要等)。似乎沒有成功。下面是一個簡單的示例程序,我認爲它應該可以工作,但在N80(儘管是固件更新)和N95上運行15分鐘左右後會崩潰。其他論壇也報告了這個問題,但在那裏提出的解決方案似乎不起作用(例如,請參見:http://discussion.forum.nokia.com/forum/showthread.php?t=129876)。
import javax.microedition.media.*;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;
public class Standalone extends MIDlet {
protected void startApp() {
final Form form = new Form("Test audio recording");
final StringItem status = new StringItem("Status","");
form.append(status);
final Command exit = new Command("Exit", Command.EXIT, 1);
form.addCommand(exit);
form.setCommandListener(new CommandListener() {
public void commandAction(Command cmd, Displayable disp) {
if (cmd == exit) {
destroyApp(false);
notifyDestroyed();
}
}
});
Thread t = new Thread(){
public void run() {
int counter = 0;
while(true) {
//Code cut 'n' paste from Sun JSR135 javadocs for RecordControl:
try {
Player p = Manager.createPlayer("capture://audio");
p.realize();
RecordControl rc = (RecordControl)p.getControl("RecordControl");
ByteArrayOutputStream output = new ByteArrayOutputStream();
rc.setRecordStream(output);
rc.startRecord();
p.start();
Thread.currentThread().sleep(5000);
rc.commit();
p.close();
} catch (Exception e) {
status.setText("completed "+counter+
" T="+Runtime.getRuntime().totalMemory()+
" F="+Runtime.getRuntime().freeMemory()+
": Error: "+e);
break;
}
counter++;
status.setText("completed "+counter+
" T="+Runtime.getRuntime().totalMemory()+
" F="+Runtime.getRuntime().freeMemory());
System.gc(); //One forum post suggests this, but doesn't help
this.yield();
}
}
};
t.start();
final Display display = Display.getDisplay(this);
display.setCurrent(form);
}
protected void pauseApp() {}
protected void destroyApp(boolean bool) {}
}
它,因爲它們是隨諾基亞軟件更新很容易更新諾基亞N系列手機的固件。我多次更新n95上的固件。 – Jimmy 2008-09-20 21:50:50