下载时模拟器冻结

时间:2011-07-15 09:57:29

标签: android

我正在尝试构建一个简单的应用程序来下载和播放音乐文件。我做了一个代码但是当试图测试时,应用程序冻结并显示'启动超时已过期,放弃唤醒锁'如果有人有想法,你能给我一些建议吗?以下是我的代码。

顺便说一句,我试图下载的示例文件大小约为9.1MB。

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    try {
        setDataSource("http://cfs.tistory.com/custom/blog/66/661632/skin/images/Believe.mp3");
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

private void setDataSource(String path) throws IOException {        

    URL url = new URL(path);
    HttpURLConnection cn = (HttpURLConnection) url.openConnection();
    cn.setRequestMethod("GET");
    cn.setDoOutput(true);
    cn.connect();

    String file_path = Environment.getExternalStorageDirectory()+"/download/";
    String fileName = "Temp.wav";
    File file = new File(file_path);
    file.mkdir();

    InputStream is = cn.getInputStream();
    File output_file = new File(file, fileName);
    FileOutputStream fos = new FileOutputStream(output_file);

    byte[] buffer = new byte[4096];
    int read = 0;

    while ((read = is.read(buffer)) > 0){
        fos.write(buffer, 0, read);
    }
    is.close();
    fos.close();

    mp = new MediaPlayer();
    mp.setDataSource(file_path+fileName);
    mp.prepare();
    mp.start();

}

}

**修改:**贾斯汀教我如果我把它放在onCreate()然后它会导致问题。现在我正在使用一个带有线程的按钮,但又遇到了另一个问题,即只有创建视图层次结构的原始线程可以触及其视图,并且好像它发生在'fos.close'。如果有人知道该怎么做,你能帮帮我吗?

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    tv = (TextView) findViewById(R.id.tv1);
    tv2 = (TextView) findViewById(R.id.tv2);
    tv.setText(Environment.getExternalStorageDirectory()+"/download/");

    Button btn = (Button) findViewById(R.id.button1);
    btn.setOnClickListener(new OnClickListener(){

        public void onClick(View v) {
            // TODO Auto-generated method stub
            Thread thread;
            Runnable r = new Runnable(){
                public void run(){
                    try {
                        setDataSource("http://cfs.tistory.com/custom/blog/66/661632/skin/images/Believe.mp3");
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }                       
                }
            };
            thread = new Thread(r);
            thread.start();

        }

    });
}

**错误讯息:**


07-15 04:31:45.321: ERROR/AndroidRuntime(313): android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.

2 个答案:

答案 0 :(得分:1)

问题是您的方法在很长一段时间内阻止了UI线程,因此Android强制关闭应用程序。

尝试在onCreateMethod()中的后台线程中启动长时间运行的进程,然后在完成时更新UI。

了解如何应用多线程的最佳方法是实际查看使用它的Google示例应用之一。这是第一个链接的引用。

"We highly recommend reading the source code of Shelves to see how to 
 persist tasks across configuration changes and how to cancel them 
 properly when the activity is destroyed."

更新:您应该将媒体播放器移回UI线程,然后运行后台线程,然后更新媒体播放器完成时提供的字符串。您可能需要重构以使用异步任务并将媒体播放器创建移动到onPostExecute()。您可能希望停在此处并尝试使用Async Task,并查看Shelves应用程序如何进行多线程处理。

您可以在我上面提到的第一个网址(靠近页面底部)找到Shelves应用程序的链接。

答案 1 :(得分:0)

呼叫。像这样的setDataSource

在您的活动中,制作一个处理程序以在下载音乐文件时获取控件。

Handler h1 = new Handler(){
   public void handleMessage(Message msg){
      // put the check here to see 
   }
};

new Thread(new Runnable(){

 public void run(){
   // set your datasource here 

   // back to your handler

}
}){
}.start();