Skip to content

Repository files navigation

PreLoader: Make your activity launch faster

Download

GitHub starsGitHub forks

changelog

中文文档

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

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

image

Usage

  1. add dependencies in build.gradle
dependencies {
compile 'com.billy.android:pre-loader:x.x.x'
}
  1. start a pre-load
intpreLoaderId = PreLoader.preLoad(newLoader());
Intentintent = newIntent(this, PreLoadBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
//DataLoader, mock as load data from networkclassLoaderimplementsDataLoader<String> {
@OverridepublicStringloadData() {
//this method runs in thread pool// load data in this method synchronouslytry {
Thread.sleep(600);
} catch (InterruptedExceptionignored) {
}
return"data from network server";
}
}
  1. Listen data after UI initialization in Activity/Fragment/View
PreLoader.listenData(preLoaderId, newListener());
//after data load completed,DataListener.onDataArrived(...) will be called to process dataclassListenerimplementsDataListener<String> {
@OverridepublicvoidonDataArrived(Stringdata) {
// this method runs on main thread, Handler is not requiredToast.makeText(activity, data, Toast.LENGTH_SHORT).show();
}
}
  1. Refresh data: DataLoader.loadData() will be called, and DataListener.onDataArrived() will be called for all listeners
PreLoader.refresh(preLoaderId);
  1. Destroy the PreLoader object if you do not need it(eg. Activity is destroyed)
PreLoader.destroy(preLoaderId);
  1. start a group of pre-load task with GroupedDataLoader and GroupedDataListener
//start pre-load task with a group of GroupedDataLoader(s)intpreLoaderId = PreLoader.preLoad(newLoader1(), newLoader2());
Intentintent = newIntent(this, PreLoadGroupBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
classLoader1implementsGroupedDataLoader<String> {
@OverridepublicStringloadData() {
TimeWatchertimeWatcher = TimeWatcher.obtainAndStart("GroupedDataLoader1 load data");
try {
Thread.sleep(600);
} catch (InterruptedExceptionignored) {
}
returntimeWatcher.stopAndPrint();
}
@OverridepublicStringkeyInGroup() {
return"loader1";
}
}
classLoader2implementsGroupedDataLoader<String> {
@OverridepublicStringloadData() {
TimeWatchertimeWatcher = TimeWatcher.obtainAndStart("GroupedDataLoader2 load data");
try {
Thread.sleep(400);
} catch (InterruptedExceptionignored) {
}
returntimeWatcher.stopAndPrint();
}
@OverridepublicStringkeyInGroup() {
return"loader2";
}
}
//listen data in Activity after UI initialization with GroupedDataListener(s) for each GroupedDataLoader(s)//GroupedDataListener matched with GroupedDataLoader by keyPreLoader.listenData(preLoaderId
, newDataHolder1()
, newDataHolder2()
);
classDataHolder1implementsGroupedDataListener<String> {
@OverridepublicvoidonDataArrived(Stringdata) {
Strings = allTime.stopAndPrint();
logTextView.append(data + "\n" + s + "\n");
}
@OverridepublicStringkeyInGroup() {
return"loader1";
}
}
classDataHolder2implementsGroupedDataListener<String> {
@OverridepublicvoidonDataArrived(Stringdata) {
Strings = allTime.stopAndPrint();
logTextView.append(data + "\n" + s + "\n");
}
@OverridepublicStringkeyInGroup() {
return"loader2";
}
}

Better to use with the componentized architecture framework (CC)

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
publicclassComponentAimplementsIComponent {
@OverridepublicStringgetName() {
return"demo.ComponentA";
}
@OverridepublicbooleanonCall(CCcc) {
intpreLoaderId = PreLoader.preLoad(newLoader());
Intentintent = newIntent(this, PreLoadBeforeLaunchActivity.class);
intent.putExtra("preLoaderId", preLoaderId);
startActivity(intent);
CC.sendCCResult(cc.getCallId(), CCResult.success());
returnfalse;
}
}

call that component by CC to open activity

// pre-load is needless here, the logistic of component are all inside that component itselfCC.obtainBuilder("demo.ComponentA").build().call();

About

Pre-load data for android Activity/Fragment/View (android页面启动速度优化利器:在页面打开之前就预加载数据)

Resources

Stars

1.5k stars

Watchers

45 watching

Forks

Releases

Packages

Contributors

Languages