经验:1.在网络端接收数据后写入本地时要用write(byte[],0,len),不要用write(byte[]),因为中文传输时易报错
2.乱码问题:客户端中文需要发送到服务器时:服务器需要转码2次(第一次将字符串转码为ISO8859-1,第二次转为utf-8)
3.服务器端中文数据需要发送到客户端时:转码一次(客户端默认为utf-8)
4.使用Httpclient封装Http的好处,传入一个Map集合,只需封装一次,无需多次拼接参数,多次封装
1.POST和GET方式访问网络
POST和GET的区别
1.访问的url地址不同
get:http://localhost:8080/itheima78/servlet/LoginServlet?username=safsaf&pwd=fasd
post:http://localhost:8080/itheima78/servlet/LoginServlet
2.post方式多了四个请求头,一个请求体
4个请求头:
Content-Length: 25
Cache-Control: max-age=0
Origin: http://localhost:8080
Content-Type: application/x-www-form-urlencoded
1个请求体:
username=sdfsaf&pwd=sdgaf
3.携带数据大小不同,get:1k, post:理论无限制
GET方式进行提交
思路步骤
1.创建URL连接
2.通过URL获得httpurlconnection连接
3.设置一些包头参数
4.获得inputstream
5.接收应答信息
get方式实例:
//使用get方式请求服务器进行登录
private void login_get(String username, String password) {
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet?username="+username+"&pwd="+password;
try{
//1.创建URL
URL url = new URL(url_str);
//2.获取一个HttpConnectionUrl
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
//3.设置一些参数
cn.setRequestMethod("GET");
cn.setConnectTimeout(10*1000);
//4.获取响应码,判断
if(cn.getResponseCode() == 200){
//5.获取返回的流数据
InputStream inputStream = cn.getInputStream();
//6.流转字符串
final String result = Utils.StreamToString(inputStream);
//Toast不能放到子线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, 0).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
POST方式进行提交
1.创建URL
2.获取一个HttpConnectionUrl
3.1设置一些参数,
3.2设置一些请求头 field: 请求头的key newValue:请求头的值
String body = "username="+username+"&pwd="+password;
cn.setRequestProperty("Content-Length", body.length()+"");
cn.setRequestProperty("Cache-Control", "max-age=0");
cn.setRequestProperty("Origin", "http://192.168.17.96:8080");
cn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
4.告诉服务器客户端需要写入数据
cn.setDoOutput(true);
5.
//3.4 获取一个连接的写入流,将请求体写入
要用write(byte[],0,len),不要用write(byte[]),因为中文传输时易报错
4.获取响应码,判断
if(cn.getResponseCode() == 200){
//5.获取返回的流数据
InputStream inputStream = cn.getInputStream();
//6.流转字符串
final String result = Utils.StreamToString(inputStream);
//Toast不能放到子线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, 0).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
POST方式的实例
//使用post方式请求服务器进行登录
private void login_post(String username, String password) {
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet";
try{
//1.创建URL
URL url = new URL(url_str);
//2.获取一个HttpConnectionUrl
HttpURLConnection cn = (HttpURLConnection) url.openConnection();
//3.1设置一些参数,
cn.setRequestMethod("POST");
cn.setConnectTimeout(10*1000);
//3.2设置一些请求头 field: 请求头的key newValue:请求头的值
String body = "username="+username+"&pwd="+password;
cn.setRequestProperty("Content-Length", body.length()+"");
cn.setRequestProperty("Cache-Control", "max-age=0");
cn.setRequestProperty("Origin", "http://192.168.17.96:8080");
cn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
//3.3 告诉服务器客户端需要写入数据
cn.setDoOutput(true);
//3.4 获取一个连接的写入流,将请求体写入
cn.getOutputStream().write(body.getBytes());
//4.获取响应码,判断
if(cn.getResponseCode() == 200){
//5.获取返回的流数据
InputStream inputStream = cn.getInputStream();
//6.流转字符串
final String result = Utils.StreamToString(inputStream);
//Toast不能放到子线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, 0).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
2 get,post方式获取和提交数据乱码解决
客户端的编码需要和服务器端编码保持一致。
提交表单数据时,需要将数据进行URLEncode编码。
3.httpclient方式提交数据到服务器
HttpUrlConnection: 请求服务器时没有过多请求参数时使用,进行文件下载的时候使用。
HttpClient: 请求服务器参数比较多,由于需要进行UrlEncode编码,所以使用该方式可以批量操作。
GET 方式进行提交:
思路:
1.创建一个HttpClient对象,创建一个子类DefaultHttpClient对象
2.执行一个http请求, 需要封装一个请求方式HttpUriRequest,是一个接口,已知的子类有HttpGet, HttpPost,可以指定访问的url地址
3.根据httpResponse获取响应码,判断响应码
4.获取服务器返回的结果
5.流转字符串
代码
//实际开发中传入URL和Map参数集合
private void login_g et(String username, String password) {
try{
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet?"+"username="+URLEncoder.encode(username, "utf-8")+"&pwd="+URLEncoder.encode(password,"utf-8");
//1.创建一个HttpClient对象,创建一个子类DefaultHttpClient对象
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
//2.执行一个http请求, 需要封装一个请求方式HttpUriRequest,是一个接口,已知的子类有HttpGet, HttpPost,可以指定访问的url地址
HttpGet httpGet = new HttpGet(url_str);//创建一个请求方式
HttpResponse httpResponse = defaultHttpClient.execute(httpGet);//执行一个请求
//3.根据httpResponse获取响应码,判断响应码
int code = httpResponse.getStatusLine().getStatusCode();
if(code == 200){
//4.获取服务器返回的结果
HttpEntity entity = httpResponse.getEntity();//获取一个实体对象
InputStream inputStream = entity.getContent();//根据httpClient对象获取流信息
//5.流转字符串
final String result = Utils.StreamToString(inputStream);
//Toast不能放到子线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, 0).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
POST方式提交
思路:
1.创建一个HttpClient对象,创建一个子类DefaultHttpClient对象
2.执行一个http请求, 需要封装一个请求方式HttpUriRequest,是一个接口,已知的子类有HttpGet, HttpPost,可以指定访问的url地址
2.1为HttpPost封装请求体
ArrayList parameters = new ArrayList();//创建一个list集合用来存储服务器所需要的参数
parameters.add(new BasicNameValuePair("username", username));//存储username
parameters.add(new BasicNameValuePair("pwd", password));//存储password
//创建一个HttpEntity对象
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
//为HttpPost设置请求体
httpPost.setEntity(entity);//HttpEntity是一个接口,可以创建一个HttpEntity子类对象UrlEncodedFormEntity。
2.3 执行一个http post请求
HttpResponse httpResponse = defaultHttpClient.execute(httpPost);//执行一个请求
//3.根据httpResponse获取响应码,判断响应码
int code = httpResponse.getStatusLine().getStatusCode();
if(code == 200){
//4.获取服务器返回的结果
代码:
private void login_post(String username, String password) {
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet";
try{
//1.创建一个HttpClient对象,创建一个子类DefaultHttpClient对象
DefaultHttpClient defaultHttpClient = new DefaultHttpClient();
//2.执行一个http请求, 需要封装一个请求方式HttpUriRequest,是一个接口,已知的子类有HttpGet, HttpPost,可以指定访问的url地址
//2.1 创建一个Post请求方式
HttpPost httpPost = new HttpPost(url_str);
//2.2 为HttpPost封装请求体
ArrayList parameters = new ArrayList();//创建一个list集合用来存储服务器所需要的参数
parameters.add(new BasicNameValuePair("username", username));//存储username
parameters.add(new BasicNameValuePair("pwd", password));//存储password
//创建一个HttpEntity对象
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(parameters,"utf-8");
//为HttpPost设置请求体
httpPost.setEntity(entity);//HttpEntity是一个接口,可以创建一个HttpEntity子类对象UrlEncodedFormEntity。
//2.3 执行一个http post请求
HttpResponse httpResponse = defaultHttpClient.execute(httpPost);//执行一个请求
//3.根据httpResponse获取响应码,判断响应码
int code = httpResponse.getStatusLine().getStatusCode();
if(code == 200){
//4.获取服务器返回的结果
HttpEntity entity1 = httpResponse.getEntity();//获取一个实体对象
InputStream inputStream = entity1.getContent();//根据httpClient对象获取流信息
//5.流转字符串
final String result = Utils.StreamToString(inputStream);
//Toast不能放到子线程中执行
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context, result, 0).show();
}
});
}
}catch (Exception e) {
e.printStackTrace();
}
}
4开源项目get post 方式提交 (asyncHttpClient)
get方式进行网络请求::
//使用get方式请求服务器进行登录
private void login_get(String username, String password) {
try{
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet?"+"username="+URLEncoder.encode(username, "utf-8")+"&pwd="+URLEncoder.encode(password,"utf-8");
//1.创建AsynchttpClient对象,该方式请求网络不需要创建子线程,结果不需要发送到主线程处理。
AsyncHttpClient httpClient = new AsyncHttpClient();
//2.执行get方法,请求服务器
httpClient.get(url_str, new AsyncHttpResponseHandler() {
//请求网络成功调用该方法 statusCode:状态码 headers:头信息 responseBody:相应的结果,以字节数据封装
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
//验证结果
if(statusCode == 200){
final String result = new String (responseBody);
Toast.makeText(context, result, 0).show();
}
}
//请求网络失败调用该方法
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
}
});
}catch (Exception e) {
e.printStackTrace();
}
}
post方式进行网络请求::
//使用post方式请求服务器进行登录
private void login_post(String username, String password) {
String url_str = "http://192.168.17.96:8080/itheima78/servlet/LoginServlet";
try{
//1.创建AsynchttpClient对象,该方式请求网络不需要创建子线程,结果不需要发送到主线程处理。
AsyncHttpClient httpClient = new AsyncHttpClient();
//2.1 创建一个RequestParams对象,封装请求体
RequestParams params = new RequestParams();
params.put("username", username);
params.put("pwd",password);
//2.2执行一个post方法
httpClient.post(url_str, params, new AsyncHttpResponseHandler() {
//运行在主线程
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if(statusCode == 200){
final String result = new String (responseBody);//将服务器返回的byte数组转换成字符串
Toast.makeText(context, result, 0).show();
}
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
}
});
}catch (Exception e) {
e.printStackTrace();
}
5 文件上传的操作
使用AsyncHttpCleint实现文件的上传:
//1.获取用户输入的文件路径
String path = et_filepath.getText().toString().trim();
//2.请求网络将文件上传到服务器
String url_str = "http://192.168.17.96:8080/itheima78/servlet/UploaderServlet";
//2.1创建一个AsynchttpClient对象
AsyncHttpClient asyncHttpClient = new AsyncHttpClient();
//2.2创建一个RequestParams对象封装文件
RequestParams requestParams = new RequestParams();
try {
requestParams.put("file", new File(path));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//2.3执行post请求
asyncHttpClient.post(url_str, requestParams, new AsyncHttpResponseHandler() {
@Override
public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
if(statusCode == 200){
Toast.makeText(MainActivity.this, "文件上传成功", 0).show();
}else{
Toast.makeText(MainActivity.this, "文件上传失败", 0).show();
}
}
@Override
public void onFailure(int statusCode, Header[] headers,
byte[] responseBody, Throwable error) {
Toast.makeText(MainActivity.this, "onFailure:文件上传失败", 0).show();
}
});
6.多线程下载思路
搬砖的流程(文件下载的流程):
1.确定有多少块砖;(确定服务器需要下载的文件大小)
try{
URL url=newURL("http://169.254.23.156:8080/itheima78/feiq.exe");
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setReadTimeout(5000);
//所有的操作都在code=200的条件下
if(con.getResponseCode()==200)
{
//获取文件大小
file_size= con.getContentLength();
2.找一个能存放这么多砖的仓库存放。(找一个存储空间,创建一个和服务器文件大小一样的临时文件,来占位。)
File file=newFile(path+"feiq.temp");
RandomAccessFile ran=newRandomAccessFile(file,"rwd");
ran.setLength(file_size);
3.确定找多少个人来搬。(确定要开启多少个线程)
4.分配任务,确定每个人搬几块砖,搬哪几块砖;(确定每个线程下载多长字节及这些字节的开始位置和结束位置。)
download_block=file_size/thread_count;
//创建每个线程开始下载
for(intthreadid=0;threadid<thread_count;threadid++)
{
//制定每个线程下载多少,有几个线程
begin_pos=threadid*download_block;
if(threadid!=thread_count)
end_pos=(threadid+1)*download_block-1;
else
end_pos=file_size-1;
newThread(newdown(begin_pos,end_pos,threadid)).start();
5.开始搬砖。(开启这些线程,进行文件下载,其实就是读服务器的流中的数据.)
try{
URL url =newURL("http://169.254.23.156:8080/itheima78/feiq.exe");
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setReadTimeout(5000);
//设置部分请求资源
if(newFile(path+threadid+".txt").exists()){
FileInputStream fileInputStream =newFileInputStream(newFile(path+threadid+".txt"));
BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(fileInputStream));
String lastPosition_str = bufferedReader.readLine();
fileInputStream.close();
bufferedReader.close();
last_pos= Integer.valueOf(lastPosition_str);//上次下载的结束位置
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}else{
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}
if(con.getResponseCode()==206)
{
synchronized(down.class){
flag=flag+1;
}
File file=newFile(path+"feiq.temp");
RandomAccessFile ran=newRandomAccessFile(file,"rwd");
InputStream in=con.getInputStream();
//设置读取的起始点
ran.seek(begin_pos);
finalProgressBar pb=map.get(threadid);
hand.post(newRunnable() {
@Override
publicvoidrun() {
pb.setMax(download_block);
}
});
intlen=0;
byte[]buff=newbyte[1024];
while((len=in.read(buff))!=-1)
{
ran.write(buff, 0,len);
total+=len;
//System.out.println(threadid+"线程下载了"+total);
hand.post(newRunnable() {
@Override
publicvoidrun() {
pb.setProgress(last_pos-begin_pos+total);
}
});
//△△△△△1.保存当前线程本次下载的位置。 有问题
intcurrentThreadDownloadPostion =last_pos+total;
System.out.println(threadid+" 下载:"+currentThreadDownloadPostion);
RandomAccessFile randomAccessFile2 =newRandomAccessFile(newFile(path+threadid+".txt"),"rwd");
randomAccessFile2.write(String.valueOf(currentThreadDownloadPostion).getBytes());
//关闭文件流,接下来才能操作删除文件
randomAccessFile2.close();
}
in.close();
ran.close();
}
}catch(MalformedURLException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}catch(IOException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}finally
{
synchronized(down.class) {
flag=flag-1;
newFile(path+threadid+".txt").delete();
if(flag==0)
{
System.out.println("下载完毕");
if(!newFile(path+"feiq.temp").renameTo(newFile(path+"feiq22.exe")))
{
System.out.println("重命名失败");
}
6.确定砖办完了。(确定每个线程都下载完了,这样才算文件下载完毕),注意需要加同步锁,因为多个线程操作同一个数据
完整代码:
publicclassdownload_break {
privatestaticintfile_size;
privatestaticintthread_count;
privatestaticintbegin_pos;
privatestaticintend_pos;
privatestaticintdownload_block;
privateStringpath;
Map< Integer, ProgressBar>map;
privateHandlerhand;
/**
*@paramargs
*/
publicdownload_break(intthreadcount,String path,Map< Integer, ProgressBar> map,Handler hand)
{
this.thread_count=threadcount;
this.path=path;
this.map=map;
this.hand=hand;
}
publicvoiddown_load (){
//TODOAuto-generated method stub
//1.获取文件的大小
try{
URL url=newURL("http://169.254.23.156:8080/itheima78/feiq.exe");
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setReadTimeout(5000);
//所有的操作都在code=200的条件下
if(con.getResponseCode()==200)
{
//获取文件大小
file_size= con.getContentLength();
//创建占位文件
File file=newFile(path+"feiq.temp");
RandomAccessFile ran=newRandomAccessFile(file,"rwd");
ran.setLength(file_size);
//thread_count=4;
download_block=file_size/thread_count;
//创建每个线程开始下载
for(intthreadid=0;threadid<thread_count;threadid++)
{
begin_pos=threadid*download_block;
if(threadid!=thread_count)
end_pos=(threadid+1)*download_block-1;
else
end_pos=file_size-1;
newThread(newdown(begin_pos,end_pos,threadid)).start();
}
//制定每个线程下载多少,有几个线程
}
}catch(MalformedURLException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}catch(IOException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}
}
classdownimplementsRunnable
{
privateintbegin_pos;
privateintend_pos;
privateinttotal=0;
privateintthreadid;
privateintflag=0;
privateintlast_pos;
publicdown(intbegin_pos,intend_pos,intthreadid)
{
this.begin_pos=begin_pos;
this.end_pos=end_pos;
this.threadid=threadid;
last_pos=begin_pos;
}
publicvoidrun() {
try{
URL url =newURL("http://169.254.23.156:8080/itheima78/feiq.exe");
HttpURLConnection con=(HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
con.setReadTimeout(5000);
//设置部分请求资源
if(newFile(path+threadid+".txt").exists()){
FileInputStream fileInputStream =newFileInputStream(newFile(path+threadid+".txt"));
BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(fileInputStream));
String lastPosition_str = bufferedReader.readLine();
fileInputStream.close();
bufferedReader.close();
last_pos= Integer.valueOf(lastPosition_str);//上次下载的结束位置
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}else{
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}
if(con.getResponseCode()==206)
{
synchronized(down.class){
flag=flag+1;
}
File file=newFile(path+"feiq.temp");
RandomAccessFile ran=newRandomAccessFile(file,"rwd");
InputStream in=con.getInputStream();
//设置读取的起始点
ran.seek(begin_pos);
finalProgressBar pb=map.get(threadid);
hand.post(newRunnable() {
@Override
publicvoidrun() {
pb.setMax(download_block);
}
});
intlen=0;
byte[]buff=newbyte[1024];
while((len=in.read(buff))!=-1)
{
ran.write(buff, 0,len);
total+=len;
//System.out.println(threadid+"线程下载了"+total);
hand.post(newRunnable() {
@Override
publicvoidrun() {
pb.setProgress(last_pos-begin_pos+total);
}
});
//△△△△△1.保存当前线程本次下载的位置。 有问题
intcurrentThreadDownloadPostion =last_pos+total;
System.out.println(threadid+" 下载:"+currentThreadDownloadPostion);
RandomAccessFile randomAccessFile2 =newRandomAccessFile(newFile(path+threadid+".txt"),"rwd");
randomAccessFile2.write(String.valueOf(currentThreadDownloadPostion).getBytes());
//关闭文件流,接下来才能操作删除文件
randomAccessFile2.close();
}
in.close();
ran.close();
}
}catch(MalformedURLException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}catch(IOException e) {
//TODOAuto-generated catch block
e.printStackTrace();
}finally
{
synchronized(down.class) {
flag=flag-1;
newFile(path+threadid+".txt").delete();
if(flag==0)
{
System.out.println("下载完毕");
if(!newFile(path+"feiq.temp").renameTo(newFile(path+"feiq22.exe")))
{
System.out.println("重命名失败");
}
}
}
}
}
}
}
7.断点续传原理及思路
1.保存当前线程本次下载的位置。
intcurrentThreadDownloadPostion =last_pos+total;
System.out.println(threadid+" 下载:"+currentThreadDownloadPostion);
//记录断点必须用RandomAccessFile直接写入硬盘,否则不能正常记录
RandomAccessFilerandomAccessFile2 =newRandomAccessFile(newFile(path+threadid+".txt"),"rwd");
randomAccessFile2.write(String.valueOf(currentThreadDownloadPostion).getBytes());
//关闭文件流,接下来才能操作删除文件
randomAccessFile2.close();
2. 下次下载,读取上次线程下载的结束位置,当做本次下载的开始位置。
if(newFile(path+threadid+".txt").exists()){
FileInputStream fileInputStream =newFileInputStream(newFile(path+threadid+".txt"));
BufferedReader bufferedReader =newBufferedReader(newInputStreamReader(fileInputStream));
String lastPosition_str = bufferedReader.readLine();
fileInputStream.close();
bufferedReader.close();
last_pos= Integer.valueOf(lastPosition_str);//上次下载的结束位置
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}else{
//☆☆☆☆☆☆☆请求部分资源,要使用Range请求头
con.setRequestProperty("Range","bytes="+last_pos+"-"+end_pos);
}
9 Android版本多线程下载带进度条显示
protectedvoidonCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bt_down= (Button)findViewById(R.id.bt_daown);
et_thredcount= (EditText) findViewById(R.id.et_threadcount);
bt_down.setOnClickListener(this);
path=Environment.getExternalStorageDirectory().getPath()+"/";
}
@Override
publicvoidonClick(View v) {
threadcount=Integer.parseInt(et_thredcount.getText().toString().trim());
finalMap< Integer, ProgressBar> map_threadbar=newHashMap();
//创建进度条
LinearLayout ly_bar=(LinearLayout) findViewById(R.id.ll_view);
if(threadcount==0)
{
Toast.makeText(this,"不能为空", 0);
return;
}
for(inti=0;i
{
//不能使用R.id.processbar?
ProgressBar pb=(ProgressBar)View.inflate(this, R.layout.processbar,null);
ly_bar.addView(pb);
map_threadbar.put(i,pb);
}
newThread(newRunnable() {
@Override
publicvoidrun() {
download_break down=newdownload_break(threadcount,path, map_threadbar,hand);
down.down_load();
}
}).start();
ly_bar.removeAllView();
}
}