最近刚刚接触AsyncTask,了解了执行一个异步任务类的基本过程,然后自己动手做了一个后台下载MP3,前台显示进度的小测试,作为对知识的一次巩固,代码如下:
新建工程MyAsyncTask,其目录结构如下:
然后修改/res/layout/main.xml,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/async" />
<Button
android:id="@+id/download"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/download" />F
<TextView
android:id="@+id/tv"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/progress" />
<ProgressBar
android:id="@+id/pb"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:style="?android:attr/progressBarStyleHorizontal" />
<Button
android:id="@+id/play"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/play"
android:visibility="invisible" />
</LinearLayout>
然后我们来看以下MyAsyncTaskActivity.java文件,代码如下:
package zjut.tsw;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.app.Activity;
import android.graphics.Color;
import android.media.MediaPlayer;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
public class MyAsyncTaskActivity extends Activity {
private static final String TAG = "MyAsyncTask";
private Button button, playbutton; // download button
private TextView tv; // show current progress
private ProgressBar pb;
private URLConnection conn;
private InputStream is;
private OutputStream os;
private MediaPlayer mediaPlayer;
DownTask dTask;
private int fileLength; // record file length
private static final String path = "http://zhangmenshiting2.baidu.com/data2/music/1660059/1660059.mp3?xcode=eb6c7cdd460a6dc8d7cc566215bc9331&mid=0.30489911336903";
/* change path value to your favourite music URL */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
tv = (TextView) findViewById(R.id.tv);
button = (Button) findViewById(R.id.download);
playbutton = (Button) findViewById(R.id.play);
pb = (ProgressBar) findViewById(R.id.pb);
pb.setVisibility(View.INVISIBLE); // set invisible
mediaPlayer = new MediaPlayer();
mediaPlayer.setLooping(false); // no looping
// register listener
button.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
dTask = new DownTask();
dTask.execute(path); // a task can be executed only once
button.setEnabled(false);
}
});
playbutton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
try {
if (mediaPlayer.isPlaying()) {
mediaPlayer.pause();
} else {
mediaPlayer.start();
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
});
}
class DownTask extends AsyncTask<String, Integer, String> {
// first parameter relates to execute method's parameter
// second parameter relates to doInBackground method's parameter
// third parameter relates to onProgressUpdate method's parameter
@Override
protected void onPreExecute() {
// UI thread
fileLength = 0;
pb.setVisibility(View.VISIBLE);
super.onPreExecute();
}
// after executing onPreExecute method,immediately execute
// doInBackground method
@Override
protected String doInBackground(String... params) {
// non-UI thread
// this method is abstract, it must be override!!
// it can't operate UI thread
// normally here put some time-assuming codes
/* download music resource from Internet */
try {
URL url = new URL(params[0]); // this parameter comes from
// execute method
conn = url.openConnection(); // create connection
File file = createDirFile(); // create directory and file in SD
// card
if (file == null) {
Log.e(TAG, "file is null");
}
is = conn.getInputStream();
int downedFileLength = 0;
fileLength = conn.getContentLength(); // get total file length
os = new FileOutputStream(file);
byte[] buffer = new byte[1024 * 4]; // cache byte array 4MB
int num = 0;
num = is.read(buffer);
while (num != -1) {
downedFileLength += num;
os.write(buffer, 0, num);
os.flush();
pb.setProgress(Math
.round(((downedFileLength + 0.0f) / fileLength) * 100));
publishProgress(downedFileLength); // this will call
// onProgressUpdate
// method
num = is.read(buffer);
}
} catch (MalformedURLException e) {
Log.e(TAG, e.getMessage());
} catch (IOException e) {
Log.e("IO", e.getMessage());
} finally {
try {
if (is != null) {
is.close();
is = null;
}
if (os != null) {
os.close();
os = null;
}
} catch (IOException e) {
Log.i(TAG, e.getMessage());
}
}
String size = String.valueOf((fileLength + 0.0f) / (1024 * 1024));
return "Download Completed! Total size:"
+ size.substring(0, size.indexOf(".") + 2) + "MB";
}
@Override
protected void onProgressUpdate(Integer... progress) {
// UI thread
tv.setText(Math.round(((progress[0] + 0.0f) / fileLength) * 100)
+ "%");
super.onProgressUpdate(progress);
}
@Override
protected void onPostExecute(String result) {
// UI thread
// After doInBackground method done,transfer its return value to
// this method
// result 是doInBackground的返回值
pb.setVisibility(View.INVISIBLE);
tv.setTextColor(Color.RED);
tv.setText(result);
playbutton.setVisibility(View.VISIBLE);
try {
mediaPlayer.setDataSource("/sdcard/DownFile/music.mp3");
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
super.onPostExecute(result);
}
}
public File createDirFile() {
String savePAth = Environment.getExternalStorageDirectory()
+ "/DownFile";
File file1 = new File(savePAth);
if (!file1.exists()) {
file1.mkdir(); // create directory
}
String savePathString = Environment.getExternalStorageDirectory()
+ "/DownFile/" + "music.mp3"; /*
* change extension according to
* your music type(.wma .mp3)
*/
File file = new File(savePathString);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
return null;
}
}
return file;
}
}
最后,别忘了在AndroidManifest.xml中添加必要的权限 :
<uses-permission android:name="android.permission.INTERNET" ></uses-permission>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" ></uses-permission>
大功告成。