On Steve Martin and a Word to the Wise
There's an old Steve Martin joke where he portrays an over-exuberant shyster who claims to be able to divulge how one can "get a
million dollars and never pay taxes." Of course, everybody and his grandmother's cat would like to know that trick, but the ebullient Martin then lets the
wind out of the audience's sails when the first pointer to accomplish said feat is: "First, get a million dollars!"
There is a bit of a parallel between that shtick and this tip in that, in order to call a RESTful method from Android, you must first
have a RESTful method to call, as this tip does not show you how to do that; that is "an exercise left to the reader" (which hopefully will
not lead you to look up an exorcist).
So, a word to the wise (as a word to the wise is sufficient, and others won't listen, anyway): If you don't have an existing RESTful
method to call, this tip will do you about as much good as an umbrella would keep you dry while sitting on the ocean floor.
Droidio
You can use Eclipse if you want, but I prefer and recommend Droidio (Android Studio) which, although still in "Preview" mode,
works well and is obviously targeted specifically towards Android development (unlike Eclipse, which is sort of a "one IDE fits all"
environment). And, being a product of the Googleplex, it is
bound to be well-funded and continue to be improved. IOW, get in on the ground floor with Drodio - I don't think you'll be "disc-appointed."
You can download Droidio here.
Note: If you are interested in some books on Droidio, there is a list within this reference (scroll down or search for "Android Studio").
Dreaming of Electronic Sheep
The code I will show you simply calls a (Web API) RESTful method that returns an integer value.
Before we get to the actual code, though, we will first need to add a Button
and an EditText
to the design surface. In a typical simple Android app, this would be in activity_main.xml. In Droidio, you can simply drag and drop these widgets to the design surface (a la Borland Delphi, Visual Studio, etc.):
A Patchy Regression
As you will see in the Java code below, the overridden doInBackground()
method uses the Apache IOUtils code; in the screenshot
above, you can see that the corresponding .jar file needed to call that (commons-io-2.4.jar) has been copied to the \app\libs folder. Once you do that (download it from here first), right-click the .jar file and select "Add as Library." This updates the build.gradle file with the necessary entry so that the Dependencies section now looks like this (I also added the gson jar that way):
dependencies {
compile 'com.android.support:appcompat-v7:+'
compile fileTree(include: ['*.jar'], dir: 'libs')
compile files('libs/commons-io-2.4.jar')
compile files('libs/gson-2.2.4.jar')
}
This (updating of the build.gradle file) is something Droidio does for you that other environments don't, forcing you to jump
through hoops like a captive tiger at the circus.
Meanwhile, Back at the Droid Ranch
To play along with the code below, add at least a button named DeptsCountBtn
and an EditText
named dynamicCountEdit
.
Next, in MainActivity.java (the default main code file you will have in the default Android project), add a class that extends
AsyncTask
(so that the instance of the class will run on a thread other than the UI thread) and which overrides the operation to be
performed on that thread in its
doInBackground()
method and which also implements the
onPostExecute()
callback method, which will
handle the results of the
doInBackground()
method like so:
private class GetDepartmentsCount extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String urlString = params[0];
String result = "";
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (null != inputStream)
result = IOUtils.toString(inputStream);
} catch (Exception e) {
System.out.println(e.getMessage());
return e.getMessage();
}
return result;
}
@Override
protected void onPostExecute(String result) {
EditText dynCount = (EditText)findViewById(R.id.dynamicCountEdit);
dynCount.setText(result + " records were found");
Log.i("FromOnPostExecute", result);
}
}
As you can probably tell, the OnPostExecute()
code shows you the results of the call in the EditText
and also writes it to
Logcat.
Now, add the URL you will call and a reference to the method you just added in your Activity:
private static final String getDeptCountsUrl =
"http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242";
private GetDepartmentsCount _getDeptsCount;
Note: Of course, you will have to replace the value assigned to getDeptCountsUrl to one of your own that returns an integer value. The "10.0.2.2" part, though, is necessary to retain when communicating with an emulator (when debugging from within Droidio and attaching to an emulator rather than directly accessing an Android device).
Add to the Activity's onCreate()
event handler code to hook up a button you have added to the corresponding .xml (named
"activity_main
" in the example here) and then hook up an OnClickListener
for that button like this:
Button getDeptsCountBtn = (Button)findViewById(R.id.DeptsCountBtn);
getDeptsCountBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
_getDeptsCount = new GetDepartmentsCount();
_getDeptsCount.execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
}
Now to show the code in context, here is the entire thing:
public class MainActivity extends ActionBarActivity {
private GetDepartmentsCount _getDeptsCount;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button getDeptsCountBtn = (Button)findViewById(R.id.DeptsCountBtn);
getDeptsCountBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
_getDeptsCount = new GetDepartmentsCount();
_getDeptsCount.execute("http://10.0.2.2:28642/api/Departments/GetCount?serialNum=4242");
}
});
}
@Override
public void onStop() {
super.onStop();
_getDeptsCount.cancel(true);
}
private class GetDepartmentsCount extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
String urlString = params[0];
String result = "";
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
InputStream inputStream = urlConnection.getInputStream();
if (null != inputStream)
result = IOUtils.toString(inputStream);
} catch (Exception e) {
System.out.println(e.getMessage());
return e.getMessage();
}
return result;
}
@Override
protected void onPostExecute(String result) {
EditText dynCount = (EditText)findViewById(R.id.dynamicCountEdit);
dynCount.setText(result + " records were found");
Log.i("FromOnPostExecute", result);
}
}
}
When you run the app from Droidio and mash the "Get Dept Count" button, you will soon (the definition of "soon" depends on
how many gerbils are currently rowing the bark, I mean Internet, etc.) see the result:
Not so fast there, Pard!
If you find this of benefit, please make use of Droidio's Help > Submit Feedback menu item so that the Googlers can make Droidio as good as possible as soon as possible. As the Jackson 5 said (paraphrasing), the bug you help squash may be your own.