Android best practices 2015
Transcript of Android best practices 2015
![Page 1: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/1.jpg)
© Sean Katz
Best ANDROID DevelopmentPractices
1
![Page 2: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/2.jpg)
© Sean Katz
Hello!I AM SEAN KATZ
I love (Android) developmentHope you’ll love it too.
- Software Dev Manager @ Autodesk- Previously Co-Founder @ for-each- 10 Years work in software dev- Passionate about Mobile & Web- Father of Mini
2
![Page 3: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/3.jpg)
© Sean Katz
SUBJECTS TODAY
1. Architecture2. Gradle3. Android Studio4. Git5. Manifest6. APIs & Support Lib7. App Code Skeletons
1. Boilerplate code2. Performance3. Debug & Measure4. CI5. Security6. Graphical Design
3
![Page 4: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/4.jpg)
© Sean Katz
What is Tipz.io ?
○ 2 in 1:● Bite-Size Tips platform for acquiring skills● Open Source Initiative for educational purposes
○ Contribute! Web, Android & iOS dev, DevOps, UX/UI work,
marketing, branding, SEO… show your skills on tipz!
○ Earn endless love & real-life reputation
4
![Page 5: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/5.jpg)
© Sean Katz
Give a Star on GitHub!
5
1. 2. 3.
![Page 6: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/6.jpg)
© Sean Katz
Tips on learning Tipz - browse tipz.io
6
![Page 7: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/7.jpg)
© Sean Katz
Tips on learning Tipz - browse commits
7
![Page 8: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/8.jpg)
© Sean Katz
Tips on learning Tipz - blame a file
8
![Page 9: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/9.jpg)
© Sean Katz
Tips on learning Tipz - browse pull reqs
9
![Page 10: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/10.jpg)
© Sean Katz
Tips on learning Tipz - continuously learn
10
![Page 11: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/11.jpg)
© Sean Katz
Contributors gets backstage access
11
![Page 12: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/12.jpg)
© Sean Katz
“
FULL BLOWN ARCHITECTURE
Weeks of programming can save you hours of planning
12
![Page 13: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/13.jpg)
© Sean Katz
What is an Android app?
Choose one or more:✓ Activity - display❏ Service - do❏ Content Provider - data❏ Broadcast - communicate
13
![Page 14: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/14.jpg)
© Sean Katz
PLAN ARCHITECTURE
ACTIVITY (or FRAGMENT)
ViewableInteractionsForeground
SERVICE
EngineBlackBoxBackgroundNetwork
Go Fetch content
Broadcast status
CONTENTPROVIDER
DataURIsEncapsulation
Results? Data CRUD
Sync
14
![Page 15: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/15.jpg)
© Sean Katz
“
GRADLE
Computers are good at following instructions, but not at reading your mind
- Donald Knuth
15
![Page 16: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/16.jpg)
© Sean Katz
Hello: GRADLE
● Build system○ Like Grunt○ Forget ‘Ant’
● Groovy● Terminal run
16
![Page 17: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/17.jpg)
© Sean Katz
GRADLE Tipz
1. Always use a gradle wrapper ☞2. Leverage a top-level build.gradle ☞3. Set names to your modules ☞4. Prefer a remote maven dependency ☞5. Always choose dependencies explicitly ☞6. Read the changelog of the Android Build
Tools ☞17
![Page 18: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/18.jpg)
© Sean Katz
“
ANDROID STUDIO
My favorite things in life don't cost any money. It's really clear that the most precious resource we all have is time
- Steve Jobs
18
![Page 19: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/19.jpg)
© Sean Katz
Hello: ANDROID STUDIO
19
![Page 20: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/20.jpg)
© Sean Katz
ANDROID STUDIO Tipz
1. Install plugins ☞2. Color your logcat ☞3. Use Android tools4. Enforce code styles ☞5. Inspect code + Lint6. Know (and use) code templates ☞
20
![Page 21: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/21.jpg)
© Sean Katz
“
GIT
Coming together is a beginning. Keeping together is progress. Working together is success
- Henry Ford
21
![Page 22: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/22.jpg)
© Sean Katz
Hello: GIT
● Popular SCM● Branch away● Collaborate● Code Review● Open Source
22
![Page 23: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/23.jpg)
© Sean Katz
Hello: GIT & SourceTree
23
![Page 24: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/24.jpg)
© Sean Katz
Hello: GIT flow
● Master● Develop● Feature/*● Release/*● Hotfix/*
24
![Page 25: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/25.jpg)
© Sean Katz
GIT Tipz
1. Your git should hold all the files needed to compile the project from scratch ☞
2. Always start with a gitignore file first ☞3. Don't invent 'gitignore', Look for an
already published gitignore for various use cases ☞
25
![Page 26: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/26.jpg)
© Sean Katz
“The Internet is the first thing that humanity has built that humanity doesn't understand, the largest experiment in anarchy that we have ever had
MANIFEST
- Eric Schmidt
26
![Page 27: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/27.jpg)
© Sean Katz
Hello: MANIFEST
27
![Page 28: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/28.jpg)
© Sean Katz
MANIFEST Tipz
1. Meet Android Dashboard ☞2. Manifest's Package name vs build.
gradle's Application ID ☞3. Carefully add new permissions ☞4. Think About android:allowBackup ☞5. Guard your components with android:
exported='false' ☞28
![Page 29: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/29.jpg)
© Sean Katz
“By failing to prepare, you are preparing to fail
ANDROID APIs & SUPPORT LIBRARY
- Benjamin Franklin
29
![Page 30: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/30.jpg)
© Sean Katz
ANDROID APIsCode name Version API level
Lollipop 5.0 21
KitKat 4.4.x 19
Jelly Bean 4.1.x, 4.2.x, 4.3.x 16 - 18
Ice Cream Sandwich 4.0.3, 4.0.4 15
Ice Cream Sandwich 4.0.1, 4.0.2 14
Honeycomb 3.x 11-13
Froyo, Gingerbread 2.2.x - 2.3.x 8-10
Cupcake, Donut, Eclair 1.x - 2.1.x 1-7
Minimum API
< ~8% users
Target APICompiled SDK
30
![Page 31: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/31.jpg)
© Sean Katz
❤ SUPPORT LIBRARYCorresponding Features from support API level
● getExternalStorageState● Notification (additions - wear, car, ...)
21
● ConnectivityManager● Notification (additions)● Nested Fragments (v4) (issue)
16 - 18
● Fragment● ActionBar, ActionBarDrawerToggle● Material design, Toolbar● ViewPager, FragmentPagerAdapter● LocalBroadcastManager● Loader● Share, ShareActionProvider● SearchView● GridLayout
14
11-13
8-10
1-7
Minimum API
< ~8% users
Target APICompiled SDK
31
![Page 32: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/32.jpg)
© Sean Katz
❤ SUPPORT LIBRARY - standalonesCorresponding Features from support API level
● DrawerLayout● SlidingPaneLayout● PrintHelper● SwipeRefreshLayout ● CardView● RecyclerView● Palette● Multidex
Standalone
![Page 33: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/33.jpg)
© Sean Katz
APIs & SUPPORT LIB Tipz
1. Always compile to the latest SDK ver ☞2. Selecting the Android version you
support (minSdkVersion) ☞3. Prefer Support Library over built in APIs
(even if your minimum API allows it) ☞
33
![Page 34: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/34.jpg)
© Sean Katz
“Simplicity is the ultimate form of sophistication
APP CODE SKELETONS
- Leonardo da Vinci
34
![Page 35: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/35.jpg)
© Sean Katz
APPLICATION CLASS Tipz
1. Use Application class, don't abuse ☞2. Don't use class as a single tone ☞3. Don't do lengthy operations ☞4. Assume the Application class values
never gets deleted ☞
35
![Page 36: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/36.jpg)
© Sean Katz
LIFECYCLE Tipz
1. Create a Launcher Activity ☞2. A runtime check for version upgrade ☞3. If you need to know when your Activity is
in resume mode ☞4. Fragments are automatically recreated
upon Activity re-create ☞5. Pick your Fragment: Static or Dynamic ☞
36
![Page 37: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/37.jpg)
© Sean Katz
SERVICES, PROVIDERS & DB Tipz
1. Provide an easy instantiation to your component ☞
2. DB operations are heavy ☞3. You probably should use IntentService ☞
37
![Page 38: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/38.jpg)
© Sean Katz
SHARED PREFS Tipz
https://github.com/tipz/tipz-android/pull/1/1. Shared Preference commit() is not the
only option2. Smartly organized SharedPreferences3. Do not store secrets in the Shared
Preferences (+ encryption example)
38
![Page 39: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/39.jpg)
© Sean Katz
GENERAL CODE Tipz
1. Adapter view data is always there ☞2. Keep your logs tidy ☞3. Goodbye old List/Grid and Adapters,
Hello RecyclerView ☞4. Request Resources and not Context ☞5. When in need of debug sections, use
BuildConfig.DEBUG ☞39
![Page 40: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/40.jpg)
© Sean Katz
“Measuring programming progress by lines of code is like measuring aircraft building progress by weight
BOILERPLATE CODE
- Bill Gates
40
![Page 41: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/41.jpg)
© Sean Katz
Hello: BOILERPLATE CODE○ BaseFragment - tag, debug, inflate
○ BaseLoadingFragment - progress views○ BaseDataFragment - connects to data
○ BaseDataAdapterFragment - w/ adapter○ BaseDataAdapterPagingFragment
○ Service○ IntentService - off-the-ui-thread, queue
○ WakefulIntentService - stays awake○ BaseService - broadcasts, access ease
○ ContentService - provider, REST api’s
41
![Page 42: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/42.jpg)
© Sean Katz
BOILERPLATE Samplez
1. “Copy and paste is a design error”2. BaseDataFragment ☞3. RecyclerViewAdapter ☞4. BaseContentProvider (+DB) ☞5. BaseActivity ☞
42
![Page 43: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/43.jpg)
© Sean Katz
“It's hardware that makes a machine fast. It's software that makes a fast machine slow
PERFORMANCE
- Craig Bruce
43
![Page 44: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/44.jpg)
© Sean Katz
1. Context and memory leaks ☞2. Avoid Internal Getters/Setters ☞3. Minimize view hierarchies4. Don’t overdraw5. Let the pros handle images ☞6. Bulk/Transactional inserts are faster ☞
PERFORMANCE Tipz
44
![Page 45: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/45.jpg)
© Sean Katz
“Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
DEBUG & MEASURE TOOLS
- Brian Kernighan
45
![Page 46: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/46.jpg)
© Sean Katz
StrictMode
46
Or, Report to logcat ☞
Activate in developer tools
![Page 47: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/47.jpg)
© Sean Katz
GPU Overdraw
47
No color 0X
Blue 1X
Green 2X
Light Red 3X
Dark Red 4X +
![Page 48: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/48.jpg)
© Sean Katz
Profile GPU Rendering
48
Blue Draw (Java)
Red Process (Render)
Orange Execute (Pipeline)
Green 60 FPS target
![Page 49: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/49.jpg)
© Sean Katz
Don’t keep activities
49
![Page 50: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/50.jpg)
© Sean Katz
Show Layout Bounds (Developer tools)
50
![Page 51: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/51.jpg)
© Sean Katz
Show Layout Bounds (Android Device Monitor)
51
![Page 52: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/52.jpg)
© Sean Katz
Network Statistics
52
Tag network using:android.net.TrafficStats
![Page 53: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/53.jpg)
© Sean Katz
Method Tracing
53
![Page 54: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/54.jpg)
© Sean Katz
Java Heap + MAT
54
![Page 55: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/55.jpg)
© Sean Katz
System Information
1. Activity Manager State2. Package Information3. Memory Usage4. Memory use over time5. Graphics State
55
![Page 56: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/56.jpg)
© Sean Katz
“An iPod, a phone, an internet mobilecommunicator... these are NOT three separatedevices! And we are calling it iPhone! Today Apple is going to reinvent the phone
Continuous Integration
- Steve Jobs56
![Page 57: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/57.jpg)
© Sean Katz
Hello: CI
● Automation○ Trigger○ Build○ Test○ Deploy
● Tools○ Jenkins○ ship.io (SaaS)
57
![Page 58: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/58.jpg)
© Sean Katz
CI Tipz
1. Use a version numbering scheme ☞2. Automated versioning ☞3. Store your debug key in git ☞
58
![Page 59: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/59.jpg)
© Sean Katz
“The only truly secure system is one that is powered off, cast in a block of concrete and sealed in a lead-lined room with armed guards
SECURITY
– Gene Spafford
59
![Page 60: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/60.jpg)
© Sean Katz
SECURITY Tipz
1. Use proguard (see next slide)
2. Silent the logs ☞3. Do not store secrets in storage ☞4. Run Android Lint for security checks5. android:exported='false' ☞6. Safe keep Production signing key ☞
60
![Page 61: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/61.jpg)
© Sean Katz
PROGUARD Tipz
1. Proguard your release, not debug ☞2. What's in the stock Android proguard ☞3. Run Proguard on a frequent basis ☞4. Create separate proguard files ☞5. Planning on using json parsers? ☞6. Proguard for 3rd party libraries ☞
61
![Page 62: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/62.jpg)
© Sean Katz
REVERSE ENGINEERING Tipz
1. Reverse own app for security checkup2. Steps:
a. Rename app.APK to app.ZIPb. extract app.ZIPc. classes.dex -> jar (tool)
3. Output:a. Java files: jar -> clear text java (tool)b. Resources: Folder “res” with the resources
62
![Page 63: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/63.jpg)
© Sean Katz
“There is no reason anyone would want acomputer in their home
GRAPHICAL DESIGN
- Ken Olson, 1977
63
![Page 64: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/64.jpg)
© Sean Katz
Android Design Cheat-Sheet
64
http://possiblemobile.com/wp-content/uploads/2014/01/Android-Design-Cheat-Sheet-highres.png
![Page 65: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/65.jpg)
© Sean Katz
PRODUCTIVE TEAMWORK
1. Productive Teamwork Blog Post ☞a. Understanding the different configurationsb. Planning a dynamic layoutc. Real estate of the screend. Stretching techniques (9 patch)e. Full screen imagesf. Folder and Files naming conventionsg. Marketing (Google Play) assets
65
![Page 66: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/66.jpg)
© Sean Katz
RESOURCES Tipz
1. Naming conventions for your ID's ☞2. You can use '@null' in attributes values ☞3. Carefully use platform drawables:
'@android:drawable/...' ☞4. Custom attributes should use res-auto
xmlns ☞5. Re-use XML layouts with <include.../> ☞
66
![Page 67: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/67.jpg)
© Sean Katz
GENERAL GRAPHICAL Tipz
1. Prefer Toolbar over ActionBar ☞2. Hello CardView ☞3. Use AppCompat themes ☞4. Styles, Themes and dimens = CSS ? ☞
67
![Page 68: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/68.jpg)
© Sean Katz
THANKS!Any questions?
68blog.android-develop.com
@_SeanKatz
www.linkedin.com/in/seankatz
![Page 69: Android best practices 2015](https://reader030.fdocuments.net/reader030/viewer/2022032616/55a64dda1a28abf6028b4869/html5/thumbnails/69.jpg)
© Sean Katz
Line Icons by Webalys, Virgil Pana and Mirko Monti are published under a Creative Commons Attribution license and Free for both personal and commercial use. You can copy, adapt, remix, distribute or transmit them. If you use these sets on your presentation remember to keep the “Credits” slide or provide a mention and link to these resources:
● Mirko Monti - Simple line icons● Virgil Pana - E-commerce icons● Webalys - Streamline iconset 69
ASSETS CREDITS