2008-09-19 19 views
2

我想用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) {} 
}  

回答

0

我认为你应该提交一个bugreport而不是尝试解决这个问题。

1

N系列诺基亚设备存在已知的内存泄漏。它不是特定于Java,而是在某处的操作系统的底层。

最近工作在一款针对诺基亚N90的游戏上,我遇到了类似的问题。我会遇到内存问题,这些问题会累积在应用程序的几个不同的重新启动中。解决方案只是为了降低整体质量和游戏资源的数量...

我会建议尝试更新您的固件作为新版本应该解决这个问题。但是,诺基亚并不是很容易升级固件,在大多数情况下,您必须将设备发送给诺基亚。而且,如果此应用程序不仅仅是供您个人使用,您必须期望任何使用N系列设备的人都不具备最新的固件。

最后,我会建议花一些时间在诺基亚论坛周围寻找,因为我知道有关于内存泄漏和N系列设备的帖子。这是一篇似乎解决您遇到问题的文章。

http://discussion.forum.nokia.com/forum/showthread.php?t=123486

+0

它,因为它们是随诺基亚软件更新很容易更新诺基亚N系列手机的固件。我多次更新n95上的固件。 – Jimmy 2008-09-20 21:50:50

相关问题