Emulator freezes while downloading
I'm trying to build a simple application to download and play a music file. I made a code but when try to test it, the application freezes and shows 'Launch timeout has expired, giving up wake lock' If anyone has an idea, would you please give me little advice? Below is my code.
By the way, the sample file I'm trying to download has about 9.1MB size.
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();
}
}
** Modified: ** Justin taught me if I just put it on onCreate() then it causes a problem. Now I'm using a button with a thread but got another problem that says only the original thread that created a view hierarchy can touch its views and seems like it's happening at 'fos.close'. If anyone knows what to do, would you please help me?
@Override
public voi开发者_如何学JAVAd 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();
}
});
}
** Error Messages: **
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.
The problem is that your method is blocking the UI Thread for an extended period and so Android is Force Closing the application.
Try launching the long running process in a background thread in the onCreateMethod() and then update the UI when its finished.
- http://developer.android.com/resources/articles/painless-threading.html
- http://developer.android.com/resources/faq/commontasks.html
- http://www.androidacademy.com/1-tutorials/43-hands-on/115-threading-with-android-part1
The best way to learn about how to apply multi-threading is to actually view one of the google sample apps that uses it. Here's a quote from the first link.
"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."
Update: You should move the media player back into the UI thread, and have the background thread run and then update the string that feeds the media player when it's finished. You may need to refactor to use an Async Task and move the media player creation into the onPostExecute(). You may want to stop here and experiment with Async Task and see how the Shelves app does multi-threading.
You can find links to the Shelves application in the first URL that I posed above (near the bottom of the page).
calling. setDataSource like this
In your activity make one handler to get the control when music file has been downloaded.
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();
精彩评论