我正在尝试构建一个简单的应用程序来下载和播放音乐文件。我做了一个代码但是当试图测试时,应用程序冻结并显示'启动超时已过期,放弃唤醒锁'如果有人有想法,你能给我一些建议吗?以下是我的代码。
顺便说一句,我试图下载的示例文件大小约为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.
答案 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();