问题:对于单线程现在慢的问题,和在网上看到别人多线程下载的例子,自己写了多线程下载的小例子
由于Cpu是按时间片分时调用线程的,多线程可以获得更多的时间片,提高资源的利用率,比如线程一进行IO操作,线程二进行cpu操作。
本文假设一个UI(main)thread控制界面的,一个管理线程loader thread负责多个下载线程down threads下载,并实时的将多个线程线程的数据显示在UI线程。为了使问题简单话,假设下载线程每次下载1个数据,每个down threads要下载的数据量len相同。
有以下几个问题要解决:
a)loader thread每过一段时间把下载的数据显示在UI界面上,由于UI界面只有UI线程可以控制和设置,loader thread要通过UI线程来控制界面,用消息机制来实现通信,实时的将数据通过消息(message)发送到UI thread,想到用监听器
b)down threads下载的数据大小用sharepreferences保存,每次下载的时候,从sharepreferences获取已经下载,和这次下载的数据量,判断是否>len,是则完成标志置位
。并将此次下载的数据保存到loader thread中
代码:
mainactivity
private Handler handler = new Handler()//UI线程的handler
{
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case 1:
int num=msg.getData().getInt("size");
String str="下载了:"+num;
text2.setText(str);
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button) findViewById(R.id.button1);
text2=(TextView) findViewById(R.id.textView2);
text2.setText("监听:");
button.setOnClickListener(new MyButton());
download(99);//下载的数据量
}
private void download(final int sum)//管理线程loader thread
{
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
FileDownloader loader=new FileDownloader(sum,3,MainActivity.this);//3个下载线程,
try {
loader.download(new DownloadProgressListener() {//监听器的方法,实现更新UI界面
@Override
public void onDownloadSize(int size) {
// TODO Auto-generated method stub
Message msg=new Message();
msg.what=1;
msg.getData().putInt("size", size);
handler.sendMessage(msg);//发送消息
}});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} }).start();
}
监听接口DownloadProgressListener.java:
public interface DownloadProgressListener {
public void onDownloadSize(int size);
}
loader threadd代码 FileDownloader.java
FileDownloader(int size,int threadnum,Context context)
{
this.size=size;
this.threadnum=threadnum;
threads=new DownThread[threadnum];
this.context=context;
SharedPreferences userInfo = context.getSharedPreferences("user_info", 0);
Editor editor=userInfo.edit();
for(int i=0;i<threadnum;i++)
{
editor.putInt("thread"+i,0);
}
editor.commit();
}
/*取线程i 已经下载的数据*/
private int getprocess(int i)
{
SharedPreferences userInfo = context.getSharedPreferences("user_info", 0);
int value=userInfo.getInt("thread"+i,0);
return value;
}
protected synchronized void append(int cur) {//保证同步的写
downlen += cur;
}
private boolean getnotfinished()
{
return downlen<size;
}
public int download(DownloadProgressListener listener) throws InterruptedException
{
while(downlen<size)
{
int block=(int)size/threadnum;
for(int i=0;i<threadnum;i++)
{
if(downlen<size&&getprocess(i)<=block)
{
this.threads[i]=new DownThread(this,block,context,i);
this.threads[i].setPriority(7);
this.threads[i].start();
}else
threads[i]=null;
}
if(listener!=null) listener.onDownloadSize(downlen);
Thread.sleep(50);
}
return 0;
}
down thread代码 DownThread.java
public DownThread(FileDownloader loader,int len,Context context,int num)
{
this.loader=loader;
this.len=len;
this.context=context;
this.num=num;
}
/*取线程i 已经下载的数据*/
private int getprocess(int i)
{
SharedPreferences userInfo = context.getSharedPreferences("user_info", 0);
int value=userInfo.getInt("thread"+i,0);
return value;
}
private void saveprocess(int i,int size)
{
SharedPreferences userInfo = context.getSharedPreferences("user_info", 0);
Editor editor=userInfo.edit();
editor.putInt("thread"+i,size);
editor.commit();
}
@Override
public void run() {
// TODO Auto-generated method stub
while(!finished)
{
//int size=(int) (Math.random()*10);
int size=1;
int cnt=getprocess(num);
cnt+=size;
saveprocess(num,cnt);
loader.append(size);
if(cnt>=len)
{
finished=true;
break;
}
}
}
本文觉得监听器比较好,和回调函数类似,在回调函数中使用函数指针作为参数,根据传送的函数调用相应的方法。在这里用接口,接口作为参数,调用相应的接口方法。
android简便简体器的方法:
findViewById(R.id.myButton).setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// Do stuff
}
});
第二种:内部类作为监听器
第三种:Activity本身作为事件监听器
具体代码:http://download.csdn.net/detail/surpassgood123/7685375