在平时的android开发工作中,我们常常须要运行耗时操作,有时为了用户体验还须要显示个等待框,我之前的做法都是开一个线程,然后用handler发消息进行显示和关闭等待框以及相关的ui操作。假设任务比較多的话,频繁的new Thread会让代码看上去比較混乱,并且还不好管理,针对这样的情况我写了tractor。

tractor基本的作用有:

1. 代码变得整洁。不用在到处new Thread和new Handler。

2. 能够监控任务的运行情况,能够随时取消一个或多个任务;

3. 封装了okhttp。支持大文件上传,多线程断点下载。get,post以及其它的网络请求

效果图

使用说明

类图

结构事实上非常easy。没有多少东西。

普通任务

//当LoadListenerImpl构造函数传入context,则显示progressdialog
doNormalTask(new LoadListenerImpl(this) {
@Override
public void onStart(Object result) {
super.onStart(result);
setMessage("任务開始运行");
} @Override
public void onSuccess(Object result) {
super.onSuccess(result);
String response = (String) result;
setMessage("任务结束");
} @Override
public void onFail(Object result) {
super.onFail(result);
String response = (String) result;
setMessage(response);
} @Override
public void onLoading(Object result) {
super.onLoading(result);
//以后不用写handler了,这样就能够处理了
int response = (int) result;
switch (response) {
case 1:
setMessage("正在运行 response=" + response);
break;
case 2:
setMessage("正在运行 response=" + response);
break;
case 3:
setMessage("正在运行 response=" + response);
break;
default:
break;
}
} @Override
public void onCancel(Object result) {
super.onCancel(result);
setMessage("任务被取消了");
} @Override
public void onCancelClick() {
super.onCancelClick();
TaskPool.getInstance().cancelTask(MainActivity.this);
}
}, this);

在上面的代码块中,LoadListenerImpl是LoadListener的实现类,用于监听任务载入的整个过程,使用LoadListenerImpl而不是LoadListener的优点有两点:

1.能够不实现全部的方法,仅仅要依据自己的须要来实现对应的方法即可了;‘

2.LoadListenerImpl中能够管理ProgressDialog。ProgressDialog能够用tractor中自带的,也能够自定义。

LoadListenerImpl 部分源代码:

public class LoadListenerImpl implements LoadListener {
private WeakReference<Context> context;
private ProgressDialog mProgressDialog;
private String mMessage = "载入中...";
private long mDismissTime = 500; /**
* 不显示progressdialog
*/
public LoadListenerImpl() {
} /**
* 显示progressdialog。其上显示的文字是默认的
* @param context
*/
public LoadListenerImpl(Context context) {
init(context, null);
} /**
* 显示progressdialog,其上显示的文字是message
* @param context
* @param message
*/
public LoadListenerImpl(Context context, String message) {
init(context, message);
}
/**
* 设置自定义的progressdialog,假设不设置则使用tractor自带的
* @param progressDialog
*/
public void setProgressDialog(ProgressDialog progressDialog) {
mProgressDialog = progressDialog;
}
......
}

当然了,你也能够自己实现LoadListener。毕竟是面向接口编程。

doNarmalTask方法的详细实现

 /**
* 发起个普通的任务
*
* @param listener
* @param tag
*/
public void doNormalTask(LoadListener listener, Object tag) {
TaskPool.getInstance().execute(new Task(tag, listener) {
@Override
public void onRun() {
SystemClock.sleep(500);
notifyLoading(1);
SystemClock.sleep(500);
notifyLoading(2);
SystemClock.sleep(500);
notifyLoading(3);
SystemClock.sleep(500);
Random random = new Random();
//任务是模拟的,所以随机下
if (random.nextBoolean()) {
//notifySuccess(null);
} else {
notifyFail("糟糕,任务失败了");
}
} @Override
public void cancelTask() { }
});
}

TaskPool.getInstance().execute()方法终于是把task交由线程池来运行。TaskPool仅仅负责加入和取消任务。接下来说Task,在上面的类图中有说明,Task是实现了Runnable接口,并重写run(),所以线程池能够运行Task,我们看下run()方法是怎么实现的:

public abstract class Task implements Runnable {
......
@Override
public final void run() {
start();
onRun();
finish();
}
......
private void start() {
notifyStart(null);
......
}
/**
* 实现这种方法来运行详细的任务
*/
public abstract void onRun();
private void finish() {
if (isRunning()) {
// 默认载入成功
mStatus = Status.SUCCESS;
notifySuccess(null);
}
clear();
}

run()中分别运行了start(),onRun()和finish(),start()方法中调用了notifyStart(null),finish()中调用了notifySuccess(null),也就是说在開始的时候会通知ui线程任务開始,结束的时候默认通知ui线程任务结束。

onRun()是抽象方法,是给任务调用者来实现运行详细的任务的。在运行的过程中能够通过notifyLoading(result)来通知ui任务的进度。notifySuccess(result)和notifyFail(result)通知ui任务成功和失败,并把须要的数据result作为參数传给ui线程。

至于Task中的cancelTask()放到后面取消任务的时候再说。

超时任务

 doTimeoutTask(500, new LoadListenerImpl() {
@Override
public void onStart(Object result) {
super.onStart(result);
toast("超时任务開始运行");
} @Override
public void onSuccess(Object result) {
super.onSuccess(result);
toast("超时任务运行成功");
} @Override
public void onTimeout(Object result) {
super.onTimeout(result);
toast("任务超时");
}
}, this);
.......
public void doTimeoutTask(long timeout, LoadListener listener, Object tag) {
TaskPool.getInstance().execute(new Task(timeout, tag, listener) {
@Override
public void onRun() {
SystemClock.sleep(1000);
} @Override
public void cancelTask() { }
});
}

能够看到。超时任务相较于普通任务来说仅仅是Task构造函数多了个timeout參数。这个timeout參数的含义就是任务运行的时间限制。假设超过这个限制就回调onTimeout()方法。

取消任务

在平时的开发过程中,有时开了一个超耗时的操作,在耗时操作未返回的时候页面就被关闭了。当页面关闭以后耗时操作才有了返回,这时候须要操作控件的话就有可能会报null或者其它的一些异常,为了避免异常,我们通常须要进行一些页面是否处于激活状态的推断,但是这样总是非常麻烦的。tractor攻克了这个问题,能够调用取消任务的方法,就像这样:

//取消任务的方法,參数能够是任务的tag,也能够是task。假设是tag,则取消tag相关的全部任务。是task则取消指定的task。
//能够在onDestroy()中调用
TaskPool.getInstance().cancelTask(tag|task);

这样调用以后会调用notifyCancel(null),在ui上显示给用户任务已取消的效果,tractor有个特性:当任务有结果时(已经取消,超时,成功和失败),兴许的notifyXXX()就都不会通知到ui线程了,所以假设任务在运行取消任务代码以后,当任务有结果返回的时候。ui回调也不会被运行。那么上面说的那个问题也就不存在了,就省的自己去加推断了。

前面也有提到,取消任务的代码仅仅能在保证ui上有取消的效果,但是任务实际上还是在运行的。尽管用户看不到但是资源还是在损耗,所以还不行。

从类图中能看到Task有onRun()和cancelTask()两个抽象方法,onRun()是运行详细任务的,cancelTask()则是运行详细的取消任务的操作。他是在非ui线程中运行的。详细怎么停止任务是由你来决定的。

网络请求部分

为了让任务管理器看起来更实用些。我封装了网络框架,实现是okhttp,能够支持head,get,post,多线程下载,大文件上传以及其它一些http请求。因为是面向接口编程,所以假设以后有更合适的库,能够非常方便的就换掉okhttp。这部分的样例我就不贴出来了,感兴趣能够自己看代码,非常easy,代码全在demo module的MainActivity里。

下载:



上传打文件:

最后

假设你有什么问题和建议能够留言或者给我发邮件。tractor是托管在github上,点击此处获取源代码。欢迎star or follow!

Android有用的任务管理器—tractor的更多相关文章

  1. android有用代码片段

    一.  获取系统版本号: [java] view plaincopy PackageInfo info = this.getPackageManager().getPackageInfo(this.g ...

  2. Android 有用的快捷键

    The powerful Android Studio 08 Jun 2016 Android Studio is the official tool for Android development ...

  3. Android开发网上的一些重要知识点[经验分享]

    1. android单实例运行方法 我们都知道Android平台没有任务管理器,而内部App维护者一个Activity history stack来实现窗口显示和销毁,对于常规从快捷方式运行来看都是s ...

  4. Android 程序员必须知道的 53 个知识点

    1. android 单实例运行方法 我们都知道 Android 平台没有任务管理器,而内部 App 维护者一个 Activity history stack 来实现窗口显示和销毁,对于常规从快捷方式 ...

  5. 我是怎样自学 Android 的?

    1. Java知识储备 本知识点不做重点解说: 对于有基础的同学推荐看<Java编程思想>,巩固基础,查漏补全,了解并熟悉很多其它细节知识点. 对于没有基础的同学推荐看一本Java基础的书 ...

  6. Android-ConvenientBanner轻松实现广告头效果

    Android-ConvenientBanner通用的广告栏控件,让你轻松实现广告头效果.支持无限循环, 可以设置自动翻页和时间(而且非常智能,手指触碰则暂停翻页,离开自动开始翻页. 你也可以设置在界 ...

  7. MTK 关闭安全模式

    1.当 Android 设备在安全模式(Safe Mode)下工作时,任何的第三方应用程序或相关文件(主要为apk应用程序文件)都不可以使用,但可以使用 Android 设备的任务管理器选项进行卸载或 ...

  8. flutter问题集锦

    现在的多平台开发很多啦,目前主流的救赎react native 和weex了,其他的旧的就不说了,新出来的gomobile目前基本无人使用,底层的很多原生对接还没有完善,flutter发布了第一版正式 ...

  9. 12套有用的免费 PSD 格式 Android UI 素材

    在这里,我们向大家呈现一些有用的和免费的 Android 用户界面 PSD 素材.由于 Android 市场迅速增长,设计人员和开发人员正在寻找一些快速和容易的方法来创建 Android 友好的应用和 ...

随机推荐

  1. ImportError: No module named tornado.ioloop 记录过程

    ImportError: No module named tornado.ioloop 记录过程 安装 pycurl    pip install pycurl 报错 'curl-config' no ...

  2. DriverModule_01

    最小驱动模块: 最简单的Makefile 无配置文件 最小驱动的四部分 头文件 声明模块信息 模块驱动的入口.出口 功能区 关于这个头文件的分析: linux头文件的位置,例如#include< ...

  3. amazeui-datatables(登录注册界面用到)

    amazeui-datatables(登录注册界面用到) 一.总结 amazeui-datatables:DataTables 插件 Amaze UI 集成,只修改了样式和默认显示语言,其他参数同官方 ...

  4. iOS_03_关键字、标识符、注释

    一.学习语法之前的提醒 1. C语言属于一门高级语言,其实,所有高级语言的基本语法组成部分都一样,只是表现形式不太一样. 2. 就好像亚洲人和非洲人,大家都有人类的结构:两只手.两只脚.一个头,只是他 ...

  5. UVA 11584 - Partitioning by Palindromes DP

    http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&p ...

  6. postman--基本使用1

    本文转自:http://blog.csdn.net/five3/article/details/53021084 HTTP的接口测试工具有很多,可以进行http请求的方式也有很多,但是可以直接拿来就用 ...

  7. 【Codeforces Round #433 (Div. 1) C】Boredom(树状数组)

    [链接]h在这里写链接 [题意] 给你一个n*n的矩阵. 其中每一列都有一个点. 任意两个点构成了矩形的两个对角点 ->即任意两个点确定了一个矩形. ->总共能确定n*(n-1)/2个矩形 ...

  8. 使用Samba在Linux服务器上搭建共享文件服务

    最近我们的小团队需要在服务器上共分出一个共享文件夹用于大家存放公共的资源文档, 大家想啊,这肯定很简单呀,在Windows下面只要创建相关的windows account,共享某个文件夹,把读/写权限 ...

  9. orabbix 报错No suitable driver found for

     orabbix报错如下:   2018-07-11 14:35:20,119 [main] ERROR Orabbix - Error on Configurator for database qa ...

  10. 【边做项目边学Android】手机安全卫士05_2:程序主界面,为每一个条目加入事件

    为每一个条目加入点击事件监听器 gv_main.setOnItemClickListener(this); 须要当前Activity实现OnItemClickListener接口.同一时候实现publ ...