Android回调函数理解,比如我用一个activity去做显示下载进度的一个进度条,但是下载是另外一个B类来做的,这个时候我Activity获取下载的进度就可以提供一个回调接口,然后让下载类来回调就行了
Activity端
package com.Javen;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.view.View.OnClickListener;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
import android.widget.Toast;
public class HttpGetDemoActivity extends Activity
{
/** Called when the activity is first created. */
private EditText editText = null;
private Button download,delete,onlinPlay,stop = null;
private ProgressBar progressBar= null;
private SeekBar seekBar = null;
private TextView resultText = null;
private static final String TAG = "HttpGetDemoActivity";
private static final int SHOW_PROGRESSBAR = 111;
private DownloadTask task = null;
/* 下载类 */
private Downloader downloader = null;
/* 音乐播放类 */
private MusicPlayer musicPlayer = null;
private File downfile = null;
private String filename = null;
private String pathtext = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
findView();
pathtext = editText.getText().toString();
downloader = new Downloader();
musicPlayer = new MusicPlayer(seekBar);
}
private void findView()
{
editText = (EditText)findViewById(R.id.edit);
download = (Button)findViewById(R.id.download);
delete = (Button)findViewById(R.id.delete);
onlinPlay = (Button)findViewById(R.id.onlinePlay);
stop = (Button)findViewById(R.id.stop);
seekBar = (SeekBar)findViewById(R.id.seekBar);
progressBar = (ProgressBar)findViewById(R.id.progreeBar);
resultText = (TextView)findViewById(R.id.result);
ButtonClickListener clickListener = new ButtonClickListener();
SeekBarChangeEvent seekBarChangeEvent = new SeekBarChangeEvent();
download.setOnClickListener(clickListener);
delete.setOnClickListener(clickListener);
onlinPlay.setOnClickListener(clickListener);
stop.setOnClickListener(clickListener);
seekBar.setOnSeekBarChangeListener(seekBarChangeEvent);
}
private final class ButtonClickListener implements OnClickListener
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
switch (v.getId())
{
case R.id.download:
// http://abv.cn/music/光辉岁月.mp3,可以换成其他文件下载的链接
filename = pathtext.substring(pathtext.lastIndexOf("/")+1);
// try{
// //将中文转为UTF-8进行编码
// filename = URLEncoder.encode(filename, "UTF-8");
// } catch (UnsupportedEncodingException e){
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// pathtext = pathtext.substring(0, pathtext.lastIndexOf("/")+1)+filename;
if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED))
{
File savDir = Environment.getExternalStorageDirectory();
downfile = new File(savDir, filename);
downLoad(pathtext, downfile);
}
else
{
Toast.makeText(getApplicationContext(), "未插入SD卡", Toast.LENGTH_LONG).show();
}
break;
case R.id.delete:
if(downfile != null)
{
downfile.delete();
Toast.makeText(getApplicationContext(), downfile+"已删除!", Toast.LENGTH_LONG).show();
}
else
Toast.makeText(getApplicationContext(), "没有该文件", Toast.LENGTH_LONG).show();
break;
case R.id.onlinePlay:
new Thread(new Runnable()
{
@Override
public void run()
{
//把http://abv.cn/music/光辉岁月.mp3传入并 播放音乐
musicPlayer.play(pathtext);
}
}).start();
break;
case R.id.stop:
//暂停
musicPlayer.pause();
break;
default:
break;
}
}
}
private void downLoad(String pathtext, File savefile)
{
/**
* 开启线程进行下载
*/
task = new DownloadTask(pathtext, savefile);
new Thread(task).start();
}
private Handler handler = new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
switch(msg.what)
{
case SHOW_PROGRESSBAR:
/**
* 使用progressBar显示下载进度
*/
int progressValue = msg.getData().getInt("percent");
progressBar.setProgress(progressValue);
resultText.setText(progressValue+"%");
if(progressBar.getProgress() == progressBar.getMax())
{
Toast.makeText(getApplicationContext(), "下載完成", Toast.LENGTH_LONG).show();
}
break;
}
super.handleMessage(msg);
}
};
private final class DownloadTask implements Runnable
{
private String path = null;
private File file = null;
public DownloadTask(String pathtext, File savFile)
{
this.path = pathtext;
this.file = savFile;
}
/**
* 通过接口监听下载进度
*/
DownloadLinstener downloadLinstener = new DownloadLinstener()
{
@Override
public void onDownloadSize(int precent)
{
Message msg = new Message();
msg.what = SHOW_PROGRESSBAR;
msg.getData().putInt("percent", precent);
handler.sendMessage(msg);
}
};
@Override
public void run()
{
/**
* 开始下载
*/
downloader.downFile(downloadLinstener, path, file);
}
}
class SeekBarChangeEvent implements OnSeekBarChangeListener
{
int progress;
@Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser)
{
/**
* SeekBar的进度变化监听 把百分进度转变为总文件中的大小
* progress为百分比
* this.progress为实际播放文件当前位置的大小
*/
this.progress = progress* musicPlayer.mediaPlayer.getDuration()/seekBar.getMax();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
/**
* 开始拖动监听
*/
}
@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
/**
* 停止拖动监听
* seekTo()的参数是相对与影片时间的数字,而不是与seekBar.getMax()相对的数字
*/
musicPlayer.mediaPlayer.seekTo(progress);
}
}
@Override
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
musicPlayer.stop();
}
接口
package com.Javen;
public interface DownloadLinstener
{
public void onDownloadSize(int precent);
}
下载类:
package com.Javen;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
public class Downloader
{
private HttpResponse httpResponse = null;
private HttpEntity httpEntity = null;
private InputStream inputStream =null;
private OutputStream outputStream = null;
private long downLenth = 0;
//原始文件的总大小
private long fileSize = 0;
private static final String TAG = "Downloader";
public void downFile(DownloadLinstener linstener, String path, File file)
{
// TODO Auto-generated method stub
//获取一个Get对象
HttpGet httpGet = new HttpGet(path);
//获取一个客户端
HttpClient httpClient = new DefaultHttpClient();
//向服务端发送请求
try
{
httpResponse = httpClient.execute(httpGet);
httpEntity = httpResponse.getEntity();
//获取输入流
inputStream = httpEntity.getContent();
fileSize = httpEntity.getContentLength();
// BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
//创建一个可随机读取位置的file
RandomAccessFile randfile = new RandomAccessFile(file, "rwd");
byte[] buffer = new byte[1024];
int offset = 0;
while((offset = inputStream.read(buffer, 0, 1024)) != -1)
{
randfile.write(buffer, 0, offset);
downLenth += offset;
float num = (float)downLenth/(float)fileSize;
int percent = (int)(num * 100);
linstener.onDownloadSize(percent);
}
randfile.close();
inputStream.close();
downLenth = 0;
} catch (ClientProtocolException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public long getFileSize()
{
return fileSize;
}
public void setFileSize(int size)
{
fileSize = size;
}
}
1、首先写下一个接口
package com.Javen;
public interface DownloadLinstener
{
public void onDownloadSize(int precent);
}
2、其次在Activity中写下便于其他类调用的接口,以及回调后改做的动作
/**
* 通过接口监听下载进度
*/
DownloadLinstener downloadLinstener = new DownloadLinstener()
{
@Override
public void onDownloadSize(int precent)
{
Message msg = new Message();
msg.what = SHOW_PROGRESSBAR;
msg.getData().putInt("percent", precent);
handler.sendMessage(msg);
}
};
3、在下载类中进行回调
while((offset = inputStream.read(buffer, 0, 1024)) != -1)
{
randfile.write(buffer, 0, offset);
downLenth += offset;
float num = (float)downLenth/(float)fileSize;
int percent = (int)(num * 100);
linstener.onDownloadSize(percent);
}
当A类需要执行的动作是需要等待B类的操作以及数据是就可以使用回调函数,在A类定义回调函数,然后在B类中进行回调!