AsynTask 4.0 的时候 dobackground 不能够运行

        之前挺喜欢用AsyncTask 进行异步加载的,但是突然今天遇到一个很无语的问题。在2.3 ,2.6等android手机系统里面,用AysncTask时没有任何问题。但是在4.0以上的,4.2的,结果就悲催了,数据无法加载,认真一查看,发现dobackground函数 压根没有执行。纳闷了半天。。。而且我也是指执行了

        然后开始查看资料,发现AsyncTask 在4.0后,里面的线程池变成了一个SingleThreadExecutor。每次只能够执行一个线程。所以有时候,多个AsyncTask在运行的时候,每次线程池里面只会有一个线程在运行,基本可以说是一个一个地执行。可以利用AsyncTask.executeOnExecutor 函数来自定义线程池,执行。这样就不会出问题了。

但是在2.3 等的时候,AsyncTask内部的线程池,能够同时执行5个线程。我猜想,可能是我程序里面的task太多,导致没法执行,部分加载必须等到前一个task执行完,才能执行,没法执行。这个问题也没有解决。不过我换了个解决的方式。自己写一个类似的加载方式。暂不成熟,仅供参考。我改成了另外一个方式。

public abstract class AbsAsyncTask<Params, Progress, Result>{
	public AbsAsyncTask(){
	}
	private static final int PUBLISH_PROGRESS = 1;
	private static final int POST_EXECUTE = 2;
	private static final int PRE_EXECUTE = 3;
	private Handler handler ;
	public final void execute(final Params ...values){
		handler = new Handler(){

			@Override
			public void handleMessage(Message msg) {
				// TODO Auto-generated method stub
//				if(msg.what == id){
					
//				}
				switch (msg.what) {
				case PUBLISH_PROGRESS:
					onProgressUpdate((Progress)msg.obj);
					break;
				case POST_EXECUTE:
					onPostExecute(result);
					break;
				case PRE_EXECUTE:
					onPreExecute();
				default:
					break;
				}
				super.handleMessage(msg);
			}
			
		};
		
		new Thread(){

			@Override
			public void run() {
				Message msg1 =new Message();
				msg1.what = PRE_EXECUTE;
				handler.sendMessage(msg1);
				
				result = doInBackground(values);
				Message msg =new Message();
				msg.what = POST_EXECUTE;
//				setMsgId(msg);
				handler.sendMessage(msg);
			}
			
		}.start();
		
	}
	private Result result = null;
	/**
	 * 每个类的 msg.what 必须要不一样!
	 * @param msg
	 */
//	protected abstract void setMsgId(Message msg);
	
	public void publishProgress(Progress ...values){
		Message msg =new Message();
		msg.what = PUBLISH_PROGRESS;
		if(values.length>0){
			msg.obj = values[0];
		}
		handler.sendMessage(msg);
	}
	protected void onPreExecute() {
	}
	
	protected void onProgressUpdate(Progress... values) {
		
	}
	
	protected Result doInBackground(Params... params) {
		// TODO Auto-generated method stub
		return null;
	}

	protected void onPostExecute(Result result) {
		// TODO Auto-generated method stub
	}

        用原来的程序继承AsyncTask的,去继承这个类。然后程序就基本能够原封不动地执行了。额,估计上面的代码是有一些问题的。这里只是一个实现的方式,自己也可以在代码中像AsyncTask 一样,放一个线程池。每次执行的时候,执行一个runnable 。

        但是我体会更多的是:

1.尽量将代码结构化,抽象化,有时候当你需要将代码重写使用新的方式去写的时候,你会感觉巨蛋疼。如果能够将相同的代码集中起来,尽量只用一份代码。这样修改起来,只需要修改那份代码就够了。尽量增加代码的重复利用率。尽量在程序中少使用两份一模一样的代码。

2.以前很长一段时间都不知道封装为何物,不知道它的价值在哪。今天算是体会到了。我在原来的代码中,只用到了AsyncTask的几个接口。其他的我都没有去用。然后将AsyncTask替换一下。将其内部实现修改一下。根本不会影响到其他部分的代码。

3.就想今天看《编程珠玑》看到的一句:Good programmers are a little bit lazy: they sit back and wait for an insight rather than rushing forward with their first idea. 不要急于修改bug,急于编码。洞察完代码,然后才去找一个最perfect,最有感觉的方式解决一个问题。

你可能感兴趣的:(android,AsyncTask)