Research
Security News
Malicious npm Packages Inject SSH Backdoors via Typosquatted Libraries
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
com.koushikdutta.ion:ion
Advanced tools
Android Asynchronous Networking and Image Loading
The included documented ion-sample project includes some samples that demo common Android network operations:
Looking for more? Check out the examples below that demonstrate some other common scenarios. You can also take a look at 30+ ion unit tests in the ion-test.
Ion.with(context)
.load("http://example.com/thing.json")
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
JsonObject json = new JsonObject();
json.addProperty("foo", "bar");
Ion.with(context)
.load("http://example.com/post")
.setJsonObjectBody(json)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
@Override
public void onCompleted(Exception e, JsonObject result) {
// do stuff with the result or error
}
});
Ion.with(getContext())
.load("https://koush.clockworkmod.com/test/echo")
.setBodyParameter("goop", "noop")
.setBodyParameter("foo", "bar")
.asString()
.setCallback(...)
Ion.with(getContext())
.load("https://koush.clockworkmod.com/test/echo")
.uploadProgressBar(uploadProgressBar)
.setMultipartParameter("goop", "noop")
.setMultipartFile("archive", "application/zip", new File("/sdcard/filename.zip"))
.asJsonObject()
.setCallback(...)
Ion.with(context)
.load("http://example.com/really-big-file.zip")
// have a ProgressBar get updated automatically with the percent
.progressBar(progressBar)
// and a ProgressDialog
.progressDialog(progressDialog)
// can also use a custom callback
.progress(new ProgressCallback() {@Override
public void onProgress(long downloaded, long total) {
System.out.println("" + downloaded + " / " + total);
}
})
.write(new File("/sdcard/really-big-file.zip"))
.setCallback(new FutureCallback<File>() {
@Override
public void onCompleted(Exception e, File file) {
// download done...
// do stuff with the File or error
}
});
Ion.with(context)
.load("http://example.com/test.txt")
// set the header
.setHeader("foo", "bar")
.asString()
.setCallback(...)
// This is the "long" way to do build an ImageView request... it allows you to set headers, etc.
Ion.with(context)
.load("http://example.com/image.png")
.withBitmap()
.placeholder(R.drawable.placeholder_image)
.error(R.drawable.error_image)
.animateLoad(spinAnimation)
.animateIn(fadeInAnimation)
.intoImageView(imageView);
// but for brevity, use the ImageView specific builder...
Ion.with(imageView)
.placeholder(R.drawable.placeholder_image)
.error(R.drawable.error_image)
.animateLoad(spinAnimation)
.animateIn(fadeInAnimation)
.load("http://example.com/image.png");
The Ion Image load API has the following features:
All operations return a custom Future that allows you to specify a callback that runs on completion.
public interface Future<T> extends Cancellable, java.util.concurrent.Future<T> {
/**
* Set a callback to be invoked when this Future completes.
* @param callback
* @return
*/
public Future<T> setCallback(FutureCallback<T> callback);
}
Future<String> string = Ion.with(context)
.load("http://example.com/string.txt")
.asString();
Future<JsonObject> json = Ion.with(context)
.load("http://example.com/json.json")
.asJsonObject();
Future<File> file = Ion.with(context)
.load("http://example.com/file.zip")
.write(new File("/sdcard/file.zip"));
Future<Bitmap> bitmap = Ion.with(context)
.load("http://example.com/image.png")
.intoImageView(imageView);
Futures can be cancelled by calling .cancel():
bitmap.cancel();
json.cancel();
Though you should try to use callbacks for handling requests whenever possible, blocking on requests is possible too. All Futures have a Future.get() method that waits for the result of the request, by blocking if necessary.
JsonObject json = Ion.with(context)
.load("http://example.com/thing.json").asJsonObject().get();
public static class Tweet {
public String id;
public String text;
public String photo;
}
public void getTweets() throws Exception {
Ion.with(context)
.load("http://example.com/api/tweets")
.as(new TypeToken<List<Tweet>>(){})
.setCallback(new FutureCallback<List<Tweet>>() {
@Override
public void onCompleted(Exception e, List<Tweet> tweets) {
// chirp chirp
}
});
}
Wondering why your app is slow? Ion lets you do both global and request level logging.
To enable it globally:
Ion.getDefault(getContext()).configure().setLogging("MyLogs", Log.DEBUG);
Or to enable it on just a single request:
Ion.with(context)
.load("http://example.com/thing.json")
.setLogging("MyLogs", Log.DEBUG)
.asJsonObject();
Log entries will look like this:
D/MyLogs(23153): (0 ms) http://example.com/thing.json: Executing request.
D/MyLogs(23153): (106 ms) http://example.com/thing.json: Connecting socket
D/MyLogs(23153): (2985 ms) http://example.com/thing.json: Response is not cacheable
D/MyLogs(23153): (3003 ms) http://example.com/thing.json: Connection successful
By default, Ion automatically places all requests into a group with all the other requests created by that Activity or Service. Using the cancelAll(Activity) call, all requests still pending can be easily cancelled:
Future<JsonObject> json1 = Ion.with(activity, "http://example.com/test.json").asJsonObject();
Future<JsonObject> json2 = Ion.with(activity, "http://example.com/test2.json").asJsonObject();
// later... in activity.onStop
@Override
protected void onStop() {
Ion.getDefault(activity).cancelAll(activity);
super.onStop();
}
Ion also lets you tag your requests into groups to allow for easy cancellation of requests in that group later:
Object jsonGroup = new Object();
Object imageGroup = new Object();
Future<JsonObject> json1 = Ion.with(activity)
.load("http://example.com/test.json")
// tag in a custom group
.group(jsonGroup)
.asJsonObject();
Future<JsonObject> json2 = Ion.with(activity)
.load("http://example.com/test2.json")
// use the same custom group as the other json request
.group(jsonGroup)
.asJsonObject();
Future<Bitmap> image1 = Ion.with(activity)
.load("http://example.com/test.png")
// for this image request, use a different group for images
.group(imageGroup)
.intoImageView(imageView1);
Future<Bitmap> image2 = Ion.with(activity)
.load("http://example.com/test2.png")
// same imageGroup as before
.group(imageGroup)
.intoImageView(imageView2);
// later... to cancel only image downloads:
Ion.getDefault(activity).cancelAll(imageGroup);
Proxy server settings can be enabled all Ion requests, or on a per request basis:
// proxy all requests
Ion.getDefault(context).configure().proxy("mycomputer", 8888);
// or... to proxy specific requests
Ion.with(context)
.load("http://example.com/proxied.html")
.proxy("mycomputer", 8888)
.getString();
Using Charles Proxy on your desktop computer in conjunction with request proxying will prove invaluable for debugging!
Ion operations return a ResponseFuture, which grant access to response properties via the Response object. The Response object contains the headers, as well as the result:
Ion.with(getContext())
.load("http://example.com/test.txt")
.asString()
.withResponse()
.setCallback(new FutureCallback<Response<String>>() {
@Override
public void onCompleted(Exception e, Response<String> result) {
// print the response code, ie, 200
System.out.println(result.getHeaders().code());
// print the String that was downloaded
System.out.println(result.getResult());
}
});
<dependency>
<groupId>com.koushikdutta.ion</groupId>
<artifactId>ion</artifactId>
<version>(insert latest version)</version>
</dependency>
dependencies {
compile 'com.koushikdutta.ion:ion:(insert latest version)'
}
git clone git://github.com/koush/AndroidAsync.git
git clone git://github.com/koush/ion.git
cd ion/ion
ant -Dsdk.dir=$ANDROID_HOME release install
Jars are at
git clone git://github.com/koush/AndroidAsync.git
git clone git://github.com/koush/ion.git
There's hundreds of apps using ion. Feel free to contact me or submit a pull request to add yours to this list.
FAQs
Android Asynchronous Networking and Image Loading
We found that com.koushikdutta.ion:ion demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Security News
Socket’s threat research team has detected six malicious npm packages typosquatting popular libraries to insert SSH backdoors.
Security News
MITRE's 2024 CWE Top 25 highlights critical software vulnerabilities like XSS, SQL Injection, and CSRF, reflecting shifts due to a refined ranking methodology.
Security News
In this segment of the Risky Business podcast, Feross Aboukhadijeh and Patrick Gray discuss the challenges of tracking malware discovered in open source softare.