Android AsyncTask平替方案

一、AsyncTask被弃用的原因

1、内存泄漏问题:AsyncTask在早期的Android版本中使用了隐式的静态引用,导致在配置更改(如屏幕旋转)时容易发生内存泄漏。这是因为AsyncTask在执行期间会持有对启动它的Activity或Fragment的引用,而这些引用无法被及时释放,从而导致内存泄漏。
2、生命周期不可控问题:AsyncTask的执行是与UI组件(如Activity)绑定的,这意味着在Activity销毁或配置更改时,AsyncTask的执行可能会被取消或中断。这种生命周期依赖性使得在处理旋转屏幕等配置更改时,需要额外的处理才能确保任务能够正确执行。
3、并发执行限制:AsyncTask默认情况下会按顺序执行后台任务,并且在早期的Android版本中,同时只能执行一个AsyncTask实例。这导致了并发执行任务的限制,无法充分利用多核处理器的优势。
4、异常处理问题:AsyncTask中的异常处理机制相对较弱,对于后台任务中的异常,无法提供一种统一和可靠的方式来捕获和处理。

二、抽象类BackgroundTask

import android.content.Context;
import android.os.Handler;
import android.os.Looper;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public abstract class BackgroundTask {
    private final Context context;
    private final Handler handler;

    private final ExecutorService THREAD_POOL_EXECUTOR;

    public BackgroundTask(Context context) {
        this.context = context;
        handler = new Handler(Looper.getMainLooper());
        THREAD_POOL_EXECUTOR = Executors.newFixedThreadPool(5);
    }

    private interface Callback<R> {
        void onComplete(R result);
    }

    private <R> void executeAsync(final Callable<R> callable, final Callback<R> callback) {
        THREAD_POOL_EXECUTOR.submit(new Runnable() {
            @Override
            public void run() {
                final R result;
                try {
                    result = callable.call();
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
                runUI(new Runnable() {
                    @Override
                    public void run() {
                        callback.onComplete(result);
                    }
                });
            }
        });
    }

    private void runUI(Runnable runnable) {
        if (Thread.currentThread() != context.getMainLooper().getThread()) {
            handler.post(runnable);
        } else {
            runnable.run();
        }
    }

    public void shutdown(){
        THREAD_POOL_EXECUTOR.shutdown();
    }

    public void executeOnExecutor() {
        runUI(new Runnable() {
            @Override
            public void run() {
                onPreExecute();
            }
        });
        executeAsync(new Callable<String>() {
            @Override
            public String call() {
                return doInBackground();
            }
        }, new Callback<String>() {
            @Override
            public void onComplete(String result) {
                onPostExecute(result);
            }
        });
    }

    protected abstract void onPreExecute();

    protected abstract String doInBackground(Integer... params);

    protected abstract void onPostExecute(String rslt);
}

特点:
1、使用方法和AsyncTask一致,可以完美平替AsyncTask。
2、在Activity等生命周期结束时,可以调用shutdown()方法关闭线程池,避免内存泄漏问题。

三、使用示例

import android.content.Context;

public class MyAsyncTask extends BackgroundTask {

    public MyAsyncTask(Context context) {
        super(context);
    }

    @Override
    protected void onPreExecute() {
        // 在主线程中执行,任务执行前的准备工作
        // 例如显示进度条或初始化UI
    }

    @Override
    protected String doInBackground(Integer... params){
        // 在后台线程中执行,耗时任务的代码
        // 模拟耗时操作,每隔一秒更新进度,并返回结果

        return "Task completed";
    }

    @Override
    protected void onPostExecute(String result) {
        // 在主线程中执行,任务完成后的操作
        // 参数result为doInBackground方法的返回结果
        // 更新UI,显示任务完成的消息
        // textView.setText(result);
    }
}
public class BaseActivity extends Activity {
	public BackgroundTask task;
	
	@Override
    public void onDestroy() {
        if (task != null) task.shutdown();
        super.onDestroy();
    }
}
public class LoginActivity extends BaseActivity {
	...
	public void onCreate(Bundle savedInstanceState) {
		...
		task = new MyAsyncTask(context);
		task.executeOnExecutor();
		...
	}
}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值