Toolbelt
Toolbelt is an Android library for common tools and utilities for optional values, easier logging and operations on String
s. I need these mostly boilerplate stuff for almost all of my Android projects so I decided to serve them as a library.
How to Include In Your Project?
Toolbelt is served on Bintray
and jCenter
. So, simply add following
compile 'com.github.mehmetakiftutuncu:toolbelt:latestVersion'
inside dependencies
in build.gradle
file in your application module. If somehow dependency resolution fails, you should also add the following repository
maven {
url 'https://dl.bintray.com/mehmetakiftutuncu/maven'
}
inside repositories
. Don't forget to replace latestVersion
with the latest version number found in the title.
What's In It?
1. Optional
It represents an optional value that may or may not exist. This is an attempt to avoid using null
s as they are not safe.
// Creates an existing optional Optional<String> optional1 = Optional.with("Hello");
// Short for Optional.<String>with();
// Creates an empty optional Optional<Integer> optional2 = Optional.empty();
// Short for Optional.<Integer>empty();
// Also creates an empty optional if the passed value is null Optional<List<String>> optional3 = Optional.with(null);
optional1.get();
// Yields "Hello" optional2.get();
// Throws a NoSuchElementException because value does not exist optional1.getOrElse("World");
// Yields "Hello" optional3.getOrElse("World");
// Yields "World" optional1.isDefined();
// Yields true optional2.isDefined();
// Yields false optional1.isEmpty();
// Yields false optional2.isEmpty();
// Yields true Optional<String> alternative = Optional.with("World");
optional1.or(alternative);
// Yields optional1 itself because value exists in optional1 optional2.or(alternative);
// Yields passed alternative because value does not exist in optional2 // Here is an example use case below that extracts the extension of from a file name. // Instead of using getExtensionUnsafe dealing with null values, use getExtensionSafe // so whoever calls it will know if extension exists or not without dealing with nulls. // Of course this is just a demonstration, these methods could have been improved greatly. public String getExtensionUnsafe(String fileName) {
if (fileName == null) return null;
String[] parts = fileName.split("\\.");
return (parts.length == 0) ? null : parts[parts.length - 1];
}
public Optional<String> getExtensionSafe(String fileName) {
String[] parts = Optional.with(fileName).getOrElse("").split("\\.");
return (parts.length == 0) ? Option.<String>empty() : Optional.with(parts[parts.length - 1]);
}
2. Log
It wraps android.util.Log
methods to get dynamic tags using the caller reference and supports message formatting as done in String.format()
. It also simplifies log levels to just DEBUG
, WARN
and ERROR
.
// Debug level log methods public static void debug(String tag, String message, Object... args) public static void debug(Class<?> caller, String message, Object... args) // Warn level log methods public static void warn(String tag, String message, Object... args) public static void warn(Class<?> caller, String message, Object... args) // Error level log methods with and without a Throwable public static void error(String tag, String message, Object... args) public static void error(String tag, Throwable throwable, String message, Object... args) public static void error(Class<?> caller, String message, Object... args) public static void error(Class<?> caller, Throwable throwable, String message, Object... args) /* Example call with dynamic tag from a non-static scope where 'this' is accessible, for example in an instance method of class Foo * * This would log following with debug level: * * Tag | Message * ----|-------- * Foo | Doing some work with 'test' and '123'... */ Log.debug(this, "Doing some work with '%s' and '%d'...", "test", 123);
/* Example call with dynamic tag from a static scope where 'this' is inaccessible, for example in a static method of class Bar * * This would log following with warn level: * * Tag | Message * ----|-------- * Bar | Doing some work with 'test' and '123'... */ Log.warn(Bar.class, "Doing some work with '%s' and '%d'...", "test", 123);
3. StringUtilities
Name says it all.
StringUtilities.isEmpty(null);
// Yields true StringUtilities.isEmpty("");
// Yields true StringUtilities.isEmpty("foo");
// Yields false List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
list.add("baz");
// These methods work on any collection extending java.util.Collection StringUtilities.makeString(list, "['", "', '", "']");
// Yields: "['foo', 'bar', 'baz']" StringUtilities.makeString(list, ", ");
// Yields: "foo, bar, baz"
4. Timer
You can use it to time stuff and see how long they take to run.
// Manage start and stop yourself Timer.start("foo");
// Do some work long duration = Timer.stop("foo");
printf("Finished in %d milliseconds!", duration);
// Or wrap a block of work and time it automatically Timer.ActionResult<Double> piResult = Timer.time(new Timer.Action<Double>() {
@Override public Double perform() {
// Perform some advanced math here to calculate the value of PI
return 3.14;
}
}
);
printf("Calculated PI as %f and it took %d milliseconds!", piResult.result, piResult.duration);
Contribution
Please feel free to and contribute. I'd love to hear your feedback, issue reports and pull requests.
License
Toolbelt is licensed under Apache License Version 2.0.
Copyright (C) 2016 Mehmet Akif Tütüncü Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.