tape 是在Android和Java中使用的与队列类相关的集合类。
一.tape是轻快的、事务性的、基于文件的FIFO的.
1.1 FIFO(先进先出)很好理解,就像我们吃饭排队,有人要加入排队队列,要排在队列的最后面,越早排队的人越靠前。队列中最早的人可以打饭,打到饭后离开队列。让排在它后面的人可以打饭。而在别人打饭的过程中,剩下的人都在等待。
1.2 轻快的指用tape执行的操作复杂度低,速度快。比如从它的接口实例中进行的增加和移除操作都是时间复杂度为O(1)的操作。即这些操作的执行时间是一个与问题规模n无关的常数。算法的执行时间不会随着问题规模n的增加而增长,即使算法中有上千条语句,其执行时间也不过是一个较大的常数。另外tape能够代替你手动编写队列处理的大量工作 ,降低了你编写程序的复杂度。
1.3 事务性指这些操作是原子性的,即这些操作在执行过程中不会被线程调度所打断。一旦开始执行就会运行到结束为止。如果处理过程中失败了,它会自动再次执行命令或操作。它的写入操作同步,不会造成两边数据不等的情况。所以tape处理不稳定环境中的数据流和数据下载非常棒。
使用方法如下:
首先,先创建一个QueueFile实例。
File file = // ...
QueueFile queueFile = new QueueFile.Builder(file).build();
如果要在队列中增加一些数据,可以向下面这样添加。QueueFile接受任意长度的byte[].
queueFile.add("data".getBytes());
如果要从队列中读数据可以使用下面方法。
byte[] data = queueFile.peek();
如果要删除处理过的元素可以用以下方法。
// Remove the eldest element.
queueFile.remove();
// Remove multiple elements.
queueFile.remove(n);
// Remove all elements.
queueFile.clear();
如果要同时读取并处理多个数据元素,可以使用迭代器API,如下:
Iterator iterator = queueFile.iterator();
while (iterator.hasNext()) {
byte[] element = iterator.next();
process(element);
iterator.remove();
}
类似于QueueFile处理byte[],ObjectQueue用相同的API处理不定长度的JAVA对象实例。ObjectQueue的创建方法有两种,如下:第一种方式需要一个转换器来处理对象元素到byte[]之间的转换。
// A persistent ObjectQueue.
ObjectQueue queue = ObjectQueue.create(queueFile, converter);
// An in-memory ObjectQueue.
ObjectQueue queue = ObjectQueue.createInMemory();
一个变换器将对象实例转变为byte[]或者byte[]转变为对象实例如下:
/** Converter which uses Moshi to serialize instances of class T to disk. */
class MoshiConverter implements Converter {
private final JsonAdapter jsonAdapter;
public MoshiConverter(Moshi moshi, Class type) {
this.jsonAdapter = moshi.adapter(type);
}
@Override public T from(byte[] bytes) throws IOException {
return jsonAdapter.fromJson(new Buffer().write(bytes));
}
@Override public void toStream(T val, OutputStream os) throws IOException {
try (BufferedSink sink = Okio.buffer(Okio.sink(os))) {
jsonAdapter.toJson(sink, val);
}
}
}
往队列中增加一些对象元素的方法如下:
queue.add("data");
从队列中读对象元素如下:
// Peek the eldest elements.
String data = queue.peek();
// Peek the eldest `n` elements.
List data = queue.peek(n);
// Peek all elements.
List data = queue.asList();
移除处理过的对象元素如下:
// Remove the eldest element.
queue.remove();
// Remove multiple elements.
queue.remove(n);
// Remove all elements.
queue.clear();
用迭代器API读和处理多个对象元素如下:
Iterator iterator = queue.iterator();
while (iterator.hasNext()) {
String element = iterator.next();
process(element);
iterator.remove();
}
我们处理任务时可以把每个任务对象实例通过add方法加入ObjectQueue中,处理端通过peek方法取出ObjectQueue中最先加入的任务对象实例进行执行。当该任务实例执行成功完成时,再在成功回调的方法中用remove将该对象实例从ObjectQueue中移除。以此完成后台任务队列的管理。