To implement the process of converting a Java object to JSON and saving it in a file, or converting the saved JSON to a Java object, use the standard Android SDK org.json, not to mention Jackson. I was a little bit hard, and when I searched for a good library, I found Moshi in Square, Inc.. I found out that there is a library called /), so I tried it easily.
Moshi Moshi is a JSON library developed by Square Inc. It seems that it was introduced as one of the Ok series at Droidcon Montreal 2015.
A Few 'Ok' Libraries (Droidcon MTL 2015)
I won't touch on this time, but in the Ok series, there are other HTTP client OkHttp and I / O library Okio. / square / ooki /) etc. have been released.
As of August 12, 2017, when this article was written, the latest release is 1.5.0 (2017/05) / 15).
The file size is as small as 64KB. This can be an advantage in Android app development. Considering that Jackson is close to 1MB and Gson is 144KB, the latest 2.8.1 is quite small.
According to the 1.4.0 API documentation, the classes included in the body are:
If you take a quick look at the source code of GitHub Library, test will find android.util.Pair. (reference / android / util / Pair.html) is used, and it seems that the Android SDK dependency is not included in the library implementation. Therefore, it can be used with other than Android apps like other Ok series.
Note that Okio is included as a dependency. This is also an I / O library that does not depend on the Android SDK.
In 1.5.0 it was Apache 2.0 like the other Ok series.
You can use it just by adding one line.
app/build.gradle
dependencies {
compile 'com.squareup.moshi:moshi:1.5.0'
According to the README of GitHub repository, the following settings are required when using Proguard. This setting is not required for use in Java applications.
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
-keepclasseswithmembers class * {
@com.squareup.moshi.* <methods>;
}
-keep @com.squareup.moshi.JsonQualifier interface *
item | value |
---|---|
IDE | Android Studio 2.3 & IntelliJ IDEA |
Java | 1.8.0_131 |
OS | Windows 10 |
Below, the explanation of the sample class required for this operation verification will be continued, so [Click here if you do not need it](# java-% E3% 82% AA% E3% 83% 96% E3 % 82% B8% E3% 82% A7% E3% 82% AF% E3% 83% 88% E3% 81% A8-json-% E3% 82% 92% E7% 9B% B8% E4% BA% 92% E5% A4% 89% E6% 8F% 9B% E3% 81% 99% E3% 82% 8B).
Let's work with a class that defines tabs in a web browser.
Tab.java
import java.util.ArrayList;
import java.util.List;
class Tab {
private List<History> histories;
private int index;
private String thumbnailPath;
private String lastTitle;
Tab() {
histories = new ArrayList<>();
index = -1;
}
// Simple accessor methods...
void addHistory(final History history) {
histories.add(history);
index++;
}
History getLatest() {
return histories.get(index);
}
}
The History class used in the Tab class is a simple class that has only two String type fields as shown below.
History.java
class History {
private final String title;
private final String url;
private History(final String title, final String url) {
this.title = title;
this.url = url;
}
public static History make(final String title, final String url) {
return new History(title, url);
}
public String title() {
return title;
}
public String url() {
return url;
}
}
Initialize the Tab object prior to the following steps.
final Tab tab = new Tab();
tab.setThumbnailPath("file://~~");
tab.setLastTitle("Google");
tab.addHistory(History.make("Title", "URL"));
Moshi uses a class called JsonAdapter to perform the conversion.
Create a Moshi object and use the adapter method to specify the type to be converted and get the JsonAdapter object.
final Moshi moshi = new Moshi.Builder().build();
final JsonAdapter<Tab> tabJsonAdapter = moshi.adapter(Tab.class);
Run with JsonAdapter.toJson.
final String json = tabJsonAdapter.toJson(tab);
The following JSON is output.
{"histories":[{"title":"Title","url":"URL"}],"index":0,"lastTitle":"Google","thumbnailPath":"file://~~"}
Pretty Printing If you want to output the JSON in a formatted state, it will take some time.
pretty_print
final Buffer buffer = new Buffer(); // 1.
final JsonWriter prettyPrintWriter = JsonWriter.of(buffer); // 2.
prettyPrintWriter.setIndent(" "); // 3.
try {
tabJsonAdapter.toJson(prettyPrintWriter, tab); // 4.
} catch (final IOException e) {
e.printStackTrace();
}
final String json = buffer.readUtf8(); // 5
It may be a little confusing as more classes are used, toJson no longer returns values directly, and toJson now raises exceptions.
As shown below, JSON was output with the specified indentation.
{
"histories": [
{
"title": "Title",
"url": "URL"
}
],
"index": 0,
"lastTitle": "Google",
"thumbnailPath": "file://~~"
}
Although it is not practical at all, it seems that the character string passed as indent in step 3 above does not matter. For example, if * 2 is specified as indent, the following JSON will be output.
{
**"histories": [
****{
******"title": "Title",
******"url": "URL"
****}
**],
**"index": 0,
**"lastTitle": "Google",
**"thumbnailPath": "file://~~"
}
Of course, if you pass this JSON to JsonAdapter.fromJson, which will be described later, you will get an exception because it cannot be parsed as JSON.
Run with JsonAdapter.fromJson. This method can throw an IOException and needs to be taken care of.
try {
final Tab fromJson = tabJsonAdapter.fromJson(json);
} catch (IOException e) {
e.printStackTrace();
}
Let's display the contents of the obtained Tab object with standard output.
System.out.println(fromJson.getLastTitle());
System.out.println(fromJson.getThumbnailPath());
System.out.println(fromJson.getLatest().title());
System.out.println(fromJson.getLatest().url());
Google
file://~~
Title
URL
It seems that the History class defined by myself is also converted properly. I feel that it is good to be able to convert even a class that does not have a public constructor.
The code for this operation verification is put in gist. https://gist.github.com/toastkidjp/252bc2ac86de2c0a3625b9fed0b9fc62
Moshi is a lightweight and easy-to-use JSON library. Since the library itself does not include the Android SDK dependency, it can be used not only for Android but also for normal Java application development. I described a simple mutual conversion method using this Moshi.
Recommended Posts