项目
在 GitHub 查看
luckybilly/PreLoader
luckybilly/PreLoader has 1,510 GitHub stars and 173 forks. GitHot measured 0 stars in 24 hours. Last checked 2026-11-08 04:28 UTC. Last push 2018-08-22.
Pre-load data for android Activity/Fragment/View (android页面启动速度优化利器:在页面打开之前就预加载数据)
可以做什么
- support network data, network images, local images, database queries, and file I/O
- support for cross-activity pre-loading
- support pull-down refresh (DataLoader reloads once, after loading completes, callback for all DataListener)
- supports custom thread-pool
实测星标增长
- 24小时
- 0
- 7天
- 正在收集历史
- 15天
- 正在收集历史
- 1个月
- 正在收集历史
各周期内的星标净变化,周期相互重叠,并非每日新增。缺失的测量保持空白。星标代表关注度,不代表软件质量。
README-zh-CN.md
原文预加载:页面启动速度优化利器
Activity打开之前就预加载数据,在Activity的UI布局初始化完成后显示预加载的数据,大大缩短启动时间。
在任意处开启预加载任务,并生成任务id,根据任务id可在任意处(一般是UI初始化完成后)开始对预加载的数据进行监听。
- 开始进行监听时,若预加载任务未完成,则等待任务加载完成后执行监听对象的回调方法
- 开始进行监听时,若预加载任务已完成,则直接执行监听对象的回调方法
持续优化中,欢迎watch、star关注!
demo

典型应用
- 在Application.onCreate中加载地址数据,在需要用到地址的页面中获取预加载的数据
- 在启动页中预加载app主页所需的数据,减少用户等待时间
- startActivity之前就开始预加载,UI初始化完成后显示预加载的数据
- 复杂页面(UI初始化耗时较多的页面)内部在UI初始化开始之前预加载数据,UI初始化完成后显示预加载的数据
- ListView/RecyclerView在上拉加载更多之前预加载下一页的数据
功能列表
- 支持网络数据、网络图片、本地图片、数据库查询及文件I/O等各种耗时操作的预加载
- 支持跨Activity预加载
- 支持下拉刷新(DataLoader重新加载一遍,加载完成后,回调所有DataListener)
- 支持自定义线程池
- 支持一个加载任务(DataLoader)对应多个监听器(DataListener)
- 支持为一个Activity配置多个预加载任务
- 支持后续添加/移除监听器(DataListener)

使用方法
- 在build.gradle中添加依赖
dependencies {
compile 'com.billy.android:pre-loader:x.x.x'
}
- 开启预加载任务(如:在startActivity之前开启)
int preLoaderId = PreLoader.preLoad(new Loader());
Intent intent = new Intent(this, PreLoadBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
//预加载任务:模拟网络接口请求获取数据
class Loader implements DataLoader<String> {
@Override
public String loadData() {
//此方法在线程池中运行,无需再开子线程去加载数据
try {
Thread.sleep(600);
} catch (InterruptedException ignored) {
}
return "data from network server";
}
}
- 在Activity(或Fragment)中UI初始化完成后开始监听预加载数据
PreLoader.listenData(preLoaderId, new Listener());
//数据加载完成后,会调用DataListener.onDataArrived(...)来处理加载后的数据
class Listener implements DataListener<String> {
@Override
public void onDataArrived(String data) {
//此方法在主线程中运行,无需使用Handler切换线程运行
Toast.makeText(activity, data, Toast.LENGTH_SHORT).show();
}
}
- 刷新数据,DataLoader会重新加载一遍数据,加载完成后,所有的DataListener的回调方法会被执行
PreLoader.refresh(preLoaderId);
- 在使用完成后可以对预加载任务进行销毁(如:在onDestroy中)
PreLoader.destroy(preLoaderId);
- 用GroupedDataLoader和GroupedDataListener来开启多个预加载任务(解决页面中有多个预加载任务时id管理不方便的问题)
//用GroupedDataLoader开启一组预加载任务,共用同一个id
int preLoaderId = PreLoader.preLoad(new Loader1(), new Loader2());
Intent intent = new Intent(this, PreLoadGroupBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
class Loader1 implements GroupedDataLoader<String> {
@Override
public String loadData() {
TimeWatcher timeWatcher = TimeWatcher.obtainAndStart("GroupedDataLoader1 load data");
try {
Thread.sleep(600);
} catch (InterruptedException ignored) {
}
return timeWatcher.stopAndPrint();
}
@Override
public String keyInGroup() {
return "loader1";
}
}
class Loader2 implements GroupedDataLoader<String> {
@Override
public String loadData() {
TimeWatcher timeWatcher = TimeWatcher.obtainAndStart("GroupedDataLoader2 load data");
try {
Thread.sleep(400);
} catch (InterruptedException ignored) {
}
return timeWatcher.stopAndPrint();
}
@Override
public String keyInGroup() {
return "loader2";
}
}
//在UI初始化完成后开始用GroupedDataListener对数据进行监听
//GroupedDataListener 与 GroupedDataLoader 之间用key进行关联
// 可以一次开启多个监听
PreLoader.listenData(preLoaderId
, new DataHolder1()
, new DataHolder2()
);
//也可以分别监听
PreLoader.listenData(preLoaderId, new DataHolder1());
PreLoader.listenData(preLoaderId, new DataHolder2());
class DataHolder1 implements GroupedDataListener<String> {
@Override
public void onDataArrived(String data) {
String s = allTime.stopAndPrint();
logTextView.append(data + "\n" + s + "\n");
}
@Override
public String keyInGroup() {
return "loader1";
}
}
class DataHolder2 implements GroupedDataListener<String> {
@Override
public void onDataArrived(String data) {
String s = allTime.stopAndPrint();
logTextView.append(data + "\n" + s + "\n");
}
@Override
public String keyInGroup() {
return "loader2";
}
}
配合组件化开发框架( CC )使用效果更佳
CC框架自带组件层级的AOP,在组件被调用打开Activity之前进行预加载,不需要在每个打开这个Activity的地方调用预加载。
组件定义打开Activity的功能:
public class ComponentA implements IComponent {
@Override
public String getName() {
return "demo.ComponentA";
}
@Override
public boolean onCall(CC cc) {
int preLoaderId = PreLoader.preLoad(new Loader());
Intent intent = new Intent(this, PreLoadBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
CC.sendCCResult(cc.getCallId(), CCResult.success());
return false;
}
}
调用打开PreLoadBeforeLaunchActivity的组件:
//不需要执行预加载,加载数据的逻辑在页面所属的组件内部完成
CC.obtainBuilder("demo.ComponentA").build().call();
探索相关项目
affaan-m/ECC
智能体执行与控制框架的性能优化系统。面向 Claude Code、Codex、Opencode、Cursor 等,涵盖技能、本能、记忆、安全与研究优先的开发。
299,333 星标NousResearch/hermes-agent
与你一同成长的智能体
261,581 星标multica-ai/andrej-karpathy-skills
一个用于改进 Claude Code 行为的 CLAUDE.md 文件,源自 Andrej Karpathy 对 LLM 编程陷阱的观察。
230,698 星标firecrawl/firecrawl
借助来自网络及其他来源的数据,强化你的 AI 智能体。正在构建面向超级智能的资料库。🔥
199,551 星标