模拟多线程下载

问题:对于单线程现在慢的问题,和在网上看到别人多线程下载的例子,自己写了多线程下载的小例子

由于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



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值