# PreLoader
**Repository Path**: luckybilly/PreLoader
## Basic Information
- **Project Name**: PreLoader
- **Description**: 预加载:android页面启动速度优化利器。Activity打开之前就预加载数据,在Activity的UI布局初始化完成后显示预加载的数据,大大缩短启动时间。如果对您有帮助请在github上给个star支持一下,谢谢!
- **Primary Language**: Android
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: https://github.com/luckybilly/PreLoader
- **GVP Project**: No
## Statistics
- **Stars**: 77
- **Forks**: 10
- **Created**: 2018-01-02
- **Last Updated**: 2024-10-30
## Categories & Tags
**Categories**: android-modules
**Tags**: None
## README
## PreLoader: Make your activity launch faster
[](https://bintray.com/hellobilly/android/pre-loader/_latestVersion)
[](https://github.com/luckybilly/PreLoader)
[](https://github.com/luckybilly/PreLoader)
[changelog](changelog.md)
[中文文档](README-zh-CN.md)
Pre-load data before Activity opens, and display data on UI after UI initialization. Speedup Activity launch
You can start a PreLoader everywhere and start to listen data which loaded by the PreLoader with preLoaderId
- if DataLoader.loadData() is not completed, then DataListener.onDataArrived() will be called after the data load is completed
- if DataLoader.loadData() is completed, then DataListener.onDataArrived() called immediately
Continuous optimization, welcome watch, star!
## demo
[demo download](demo.apk)
## Typically used for
1. Pre-load data in Application.onCreate for HomePageActivity to reduce the user waiting time in HomePageActivity initialization
2. Pre-load data before context.startActivity(), and display data after activity UI are initialized
3. Pre-load data for complex UI Activity (UI initialization cost too much time)
4. Pre-load data for next page of ListView/RecyclerView before pull to load more
## Features
- 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
- support one loader (DataLoader) for multiple listeners (DataListener)
- support multiple preload tasks for an Activity
- support for add/remove listener dynamically

## Usage
1. add dependencies in build.gradle
```groovy
dependencies {
compile 'com.billy.android:pre-loader:x.x.x'
}
```
2. start a pre-load
```java
int preLoaderId = PreLoader.preLoad(new Loader());
Intent intent = new Intent(this, PreLoadBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
//DataLoader, mock as load data from network
class Loader implements DataLoader {
@Override
public String loadData() {
//this method runs in thread pool
// load data in this method synchronously
try {
Thread.sleep(600);
} catch (InterruptedException ignored) {
}
return "data from network server";
}
}
```
3. Listen data after UI initialization in Activity/Fragment/View
```java
PreLoader.listenData(preLoaderId, new Listener());
//after data load completed,DataListener.onDataArrived(...) will be called to process data
class Listener implements DataListener {
@Override
public void onDataArrived(String data) {
// this method runs on main thread, Handler is not required
Toast.makeText(activity, data, Toast.LENGTH_SHORT).show();
}
}
```
4. Refresh data: DataLoader.loadData() will be called, and DataListener.onDataArrived() will be called for all listeners
```java
PreLoader.refresh(preLoaderId);
```
5. Destroy the PreLoader object if you do not need it(eg. Activity is destroyed)
```java
PreLoader.destroy(preLoaderId);
```
6. start a group of pre-load task with GroupedDataLoader and GroupedDataListener
```java
//start pre-load task with a group of GroupedDataLoader(s)
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 {
@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 {
@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";
}
}
//listen data in Activity after UI initialization with GroupedDataListener(s) for each GroupedDataLoader(s)
//GroupedDataListener matched with GroupedDataLoader by key
PreLoader.listenData(preLoaderId
, new DataHolder1()
, new DataHolder2()
);
class DataHolder1 implements GroupedDataListener {
@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 {
@Override
public void onDataArrived(String data) {
String s = allTime.stopAndPrint();
logTextView.append(data + "\n" + s + "\n");
}
@Override
public String keyInGroup() {
return "loader2";
}
}
```
## Better to use with the componentized architecture framework (CC)
[CC](https://github.com/luckybilly/CC) framework comes with AOP at the component level: when component is calling for start an activity, you can start a pre-load for it. So, it is not need to do pre-load work in every place where you want to start the Activity.
1. define a component for open the activity
```java
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;
}
}
```
call that component by CC to open activity
```java
// pre-load is needless here, the logistic of component are all inside that component itself
CC.obtainBuilder("demo.ComponentA").build().call();
```