Tuesday, June 30, 2015

JavaOne Publications

For those that follow my blog, JavaOne has published one of my talks from JavaOne 2013, on YouTube: https://www.youtube.com/watch?v=5GONWVKjaOg

Android ListView Example

Here's a very simple example to get you started with an Android ListView. This example just displays a hard-coded list of colors in a ListView control. The key components are the ArrayAdapter and the additional layout file.

ListViews work via an adapter pattern. So, we have to create an adapter that lists the items that we're going to display in the ListView. We also have to create a layout with the type of entity that we're displaying for each item in the ListView. In this example, each item in the ListView will be a simple TextView. However, it could be something more involved (like an image).


res/layout/activity_main.xml :

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    tools:context="${relativePackage}.${activityClass}" >



    <ListView

       android:id="@+id/list_of_colors"

       android:layout_width="fill_parent"

       android:layout_height="fill_parent"

       android:padding="10dp"

       android:textSize="20sp" />


</RelativeLayout>


res/layout/listview_item.xml :

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
    
 <TextView android:id="@+id/color_item"   
   android:layout_width="fill_parent"   
   android:layout_height="wrap_content"  
   android:padding="10dp"  
   android:textSize="16sp" />
 
</LinearLayout>


src/{package-name}/MainActivity.java :

public class MainActivity extends Activity {
 
    private  final String[] COLORS = new String[] { "Red", "Orange", 
             "Yellow", "Green", "Blue", "Indigo", "Violet" };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
  
       ArrayAdapter adapter = new ArrayAdapter(this, R.layout.listview_item,
                        R.id.color_item, COLORS);
  
       ListView lv = (ListView) findViewById(R.id.list_of_colors);
       lv.setAdapter(adapter);
    }
}

I put this code on GitHub for you to reference: https://github.com/travisdazell/android-listview-example

Monday, June 29, 2015

Android and Eclipse No More!

Google has been warning us for awhile that support for Eclipse would eventually go away for Android development. That warning became imminent yesterday, as they announced that we have until the end of this year to stop using Eclipse and start using Android Studio.

Granted, you can still develop apps for Android using Eclipse and the Android plugin, but support will be absent by year's end.

I must admit that I'm still more comfortable with Eclipse than I am with Android Studio. However, this is exciting to see energy and progress on the Android development front. This change is good. Now myself, like many others, need to put away the comfort and familiarity of Eclipse and embrace Android Studio!

Sunday, June 28, 2015

Android Examples

Here is a list of Android examples that I've put together. I will continue adding to it over time.

  • Android Basics
  • Android Concurrency

Android - Starting a New Activity - Explicit Intent

In Android, each screen or presentation is done via its own activity. So, we will have a main activity that runs when the application is first started. Launching a new activity is simple, using an explicit intent.

Let's say that we have a button that launches a new activity when it's clicked. Here's the code for doing this, using an explicit intent.

   public void openOtherActivityClick(View view) {
     // create an explicit intent and specify
     // the exact class name of the activity that we want
     Intent otherActivityIntent = new Intent(this, OtherActivity.class);
  
     // start the other activity
     startActivity(otherActivityIntent);
 }

With an explicit intent, we specify the exact class name of the activity that we want to start. Another way to start an activity, is with an implicit intent. Here's an example of how to use an implicit intent: http://travisdazell.blogspot.com/2015/01/android-implicit-intents.html

REST - PUT Versus POST for RESTful Services

The use of GET and DELETE is pretty obvious for RESTful services, but there's usually some confusion around when to use a PUT versus a POST. The reality is, they can both do the job. But, here's the breakdown on when to use PUT and when to use POST for your REST services.

Use a PUT only when you know the exact URI of the resource that you are creating or updating.

Let's start with creating a new resource. Should you use a PUT or a POST when designing this service? Well, generally speaking, when you are creating a new resource, you probably don't know the exact URI. Why? Because, to retrieve an individual record, we usually provide a REST service that allows clients to specify records by their ID. Example:

# Get customer with ID = 52

GET /customer/52 HTTP/1.1

Host: www.mysite.org


So, if you're creating a new resource, you typically don't know the next ID in the sequence. So, you wouldn't use a PUT in this scenario. Instead, use a POST. Example:

# Request to create a new customer record

POST /customer HTTP/1.1

Host: www.mysite.org

Content-Type: application/xml;charset=UTF-8



<customer>

   <firstname>John</firstname>

   <lastname>Doe</lastname>

</customer>



# Response

HTTP/1.1 201 Created

Location: http://www.mysite.org/customer/52

Content-Location: http://www.mysite.org/customer/52

Content-Type: application/xml;charset=UTF-8


I didn't include the response body, but you get the point. Now that we have the URI for the customer record, we can use a PUT for any future updates.

So, the general rule of thumb:

  • Creating a new resource? Use a POST, unless you already know the URI for the new resource. 
    • The only time you would want to use a PUT for creating a new resource, is when the client applications can specify the exact URI of the new resource that's being created.
  • Updating an existing resource? Use a PUT.
    • However, a POST is a viable option as well. Really, anywhere you can use a PUT, you can use a POST. But, if already know the URI of the resource that you're modifying, a PUT is preferred.

Wednesday, June 24, 2015

Android AsyncTask Example

Often times, you will need to run an operation in the background of your Android app, so that you're not blocking the UI thread. For short running operations, AsyncTask is the perfect tool for the job. The best part is that it's very easy to use.

Let's consider an app that takes an image and adjusts the contrast of the image to make it brighter. By clicking a button in the app, a predefined image is made brighter and then displayed on the screen. To implement the image contrast functionality, let's pretend that we've already written a Java class called ImageUtils that contains a method called setContrast. The signature for this method looks like this:

public Bitmap setContrast(Bitmap image, double contrastValue);

Naively, we could call this method within our button's onClickListener. However, if we do that, then while the image is being manipulated, we will block the UI thread and cause the application to "freeze". So, we can use AsyncTask to perform this image manipulation in the background!

Here's a naive approach to processing the image, within the button's onClickListener:

public void onClickListener(View target) {
 // get the Android icon bitmap that's included in this project 
 Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

 ImageUtils imageConverter = new ImageUtils();

 Bitmap result = imageConverter.setContrast(originalBitmap, CONTRAST_VALUE);

 ivAndroidIcon.setImageBitmap(result);
}

Thankfully, to use AsyncTask, all that's needed is for us to create a new Java class that extends AsyncTask. Within this class, we'll call our setContrast method. In a sense, we're simply wrapping our current image logic with a class that extends AsyncTask. Pretty simple indeed! Here's how this new class looks:

class BrightenImageTask extends AsyncTask<Bitmap, Void, Bitmap> {
 @Override
 protected Bitmap doInBackground(Bitmap... params) {
  // create a new image that's much brighter than the original image
  ImageUtils imageConverter = new ImageUtils();

  return imageConverter.setContrast(params[0], CONTRAST_VALUE);
 }
  
 @Override
 protected void onPostExecute(Bitmap result) {
  // display the updated image
  ivAndroidIcon.setImageBitmap(result);
 }
}

Now that we have our image processing logic inside an AsyncTask, we can modify our button's onClickListener to call our AsyncTask:

public void onClickListener(View target) {
 // get the Android icon bitmap that's included in this project 
 Bitmap originalBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);

 new BrightenImageTask().execute(originalBitmap);
}

There are a couple things to note about AsyncTask:
  1. The generic types that are defined on our AsyncTask class are specifying that a Bitmap is passed into the doInBackground method and a Bitmap is returned by our onPostExecute method.
  2. The VOID type specifies the type that's used to as the unit of progress for the background operation. I didn't use a "progress indicator" in this example, but this is where you would do this type of indication. You could specify this as an Integer and then override the method onProgressUpdate(Integer... progress) to set a progress indicator.
If you really want to get an appreciation for AsyncTask, you can add a Thread.sleep(5000) inside your doInBackground method. You'll notice that you can still click around on the screen while the operation is happening in the background. If instead, you put the image processing logic directly inside the button's onClickListener, you will find that the screen becomes non-responsive while the image is being processed (namely that the button remains depressed and it's obvious that the UI is blocked).

So, next time you need to quickly make an operation run in the background, consider using AsyncTask. Note that this works great for operations that only take a few seconds to complete. However, if you have long running operations, you should consider using an Android service. This is because AsyncTask processes are still connected to the activity stack that executed the AsyncTask. As all of us Android developers know, the Android OS could decide to kill your activity at any time, if the OS needs to recover system resources. This could leave your background task in an unknown state. If you have a long running process, you'll want to use a service that continues to run, just in case your activity is shut down for some unplanned reason.

For reference, I've placed all of the source code for this application on GitHub: https://github.com/travisdazell/asynctask-example

Sunday, February 8, 2015

Order of Growth - Doubling Hypothesis

When designing an algorithm that must process large data sets, performance is usually a big concern. One way to determine the running time (i.e. performance) is to simply run the program against various test cases measure the running time. For example:

long startTime = System.currentTimeMillis();

// run your algorithm

long endTime = System.currentTimeMillis();
double timeToExecute = (now - start) / 1000.0;

This works most of the time, but you don't always want to test your code against extremely large data sets. Instead, you'd rather run the code against a handful of smaller data sets and estimate how much the performance degrades as the size of the data set grows. This can save considerable time when you don't want to wait for your program to finish processing millions of records. Let's say we're trying to estimate the running time of our application when the number of records exceeds one million.

To estimate the running time for this large data set, we start with asking the question, "What is the effect on the running time of doubling the size of the data set?".

We can start by creating a list that contains four columns, like such, where N is the number of records to process.

Nsecondsratiolog_2 ratio
256???
512???
1024???
2048???
4096???
8192???
16384???
32768???


We have question marks for all of the other values for now. The next step is to run our algorithm against each sized data set in our table and add the number of seconds it takes to execute each data set to our table. As an example, let's say that our results look like this:

Nsecondsratiolog_2 ratio
2560.000??
5120.004??
10240.019??
20480.088??
40960.406??
81921.825??
163848.213??
3276836.959??

At this point, we've recorded the number of second that it takes to process each data set, where the size of the data set ranges from 256 items to 32768 items, doubling the size with each test (hence the name "doubling hypothesis").

The next step is to fill in the values in the ratio column. We'll start with the very last row. The value for the last row is the result of 36.959 / 8.213. The value for the row above it is the result of 8.213 / 1.825. We then continue until we've calculated all ratios. Note that there will not be a ratio for the top row (since there's no row above it to divide by). There will also not be a ratio for the second row, since we can't divide by zero.

After calculating the ratios, our table looks like this:

Nsecondsratiolog_2 ratio
2560.000-?
5120.004-?
10240.0194.75?
20480.0884.63?
40960.4064.61?
81921.8254.50?
163848.2134.50?
3276836.9594.50?

The last column is the log_2 ratio, which is shorthand for "log base 2 ratio". This is simply the log base 2 of the ratio value. For example, the value in the last row is the log base 2 of 4.50. If you're using the Windows calculator, you can use the natural logarithm, like this:

ln(4.50) / ln(2)

After calculating the log base 2 for each ratio value, we have the following table:

Nsecondsratiolog_2 ratio
2560.000--
5120.004--
10240.0194.752.25
20480.0884.632.21
40960.4064.612.20
81921.8254.502.17
163848.2134.502.17
3276836.9594.502.17

Notice that log_2 ratio seems to converge at 2.17. We can now plug this value into the following equation (read as "A times N to the power of b"), where "A" is a constant, "b" is the log_2 ratio, and N is the number of items we need to process. Note that T(N) is the time it takes to process N number of records.

T(N) = A * (N ^ b)

We already know that b is approximately 2.17. We can find the value of the constant A by solving the equation for one of our timings. You'll want to use one of the larger values of N. You can even try it for a few values of N. For example, if we try to solve for A using N = 32,768, we get:

A * (32,768 ^ 2.17) = 36.959
A = 0.000000005877516

So, if we wanted to know how long it would take to process 1,048,576 records, we would just calculate it as:

T(N) = 0.000000005877516 * (1,048,576 ^ 2.17)
T(N) = 68,217.474 seconds

This doubling hypothesis allows us to estimate the amount of time that our algorithm will take to process very large sets of data, without having to run the program and wait for it to complete. This can be very useful when trying to determine if we're on the right track or need to refine our algorithm to handle large inputs.

Saturday, January 24, 2015

Android Implicit Intents

There are times that you want to utilize another application on the Android device for some action in your application. For example, let's say you have an application that opens a browser and navigate to a web site. You wouldn't want to build your own browser (most likely anyway), so you'd just let the Android device choose an application to use for navigating to the web site. When you do this, you're using an implicit intent. Here's how you do it.

private void navigateToWebSite() {
   // Create an intent for viewing a specific web site
   Uri google = Uri.parse("http://developer.android.com");
  
   Intent intent = new Intent(Intent.ACTION_VIEW, google);
  
   // Create a chooser intent
   Intent chooserIntent = Intent.createChooser(intent, "Browse with...");
        
   // Start the chooser activity
   if (intent.resolveActivity(getPackageManager()) != null) {
      startActivity(chooserIntent);
   }
}

The chooserIntent is optional. I'm using it to add a custom title to the chooser dialog. You can simply create the intent and call "startActivity(intent)" and let Android display the standard chooser dialog.

In this example, we just told Android to include any application that can handle the ACTION_VIEW intent. What if you have written your own application that you want to include as an option for handling  this type of intent? In your application's AndroidManifest.xml file, you simply add an intent-filter within the definition of the activity.

For example, here I've added a second intent-filter to handle any applications that initiates an intent on the Intent.ACTION_VIEW with "http" requests, just like in the example above.

<activity android:label="@string/app_name" android:name=".MyOtherActivity">

       <intent-filter>
           <action android:name="android.intent.action.MAIN" />

           <category android:name="android.intent.category.LAUNCHER">
       </intent-filter>

         <intent-filter>
             <action android:name="android.intent.action.VIEW">

             <category android:name="android.intent.category.DEFAULT">

             <data android:scheme="http">
         </intent-filter>

</activity>



Monday, January 19, 2015

Android - Handling Configuration Changes Yourself

There are many things that can happen outside of your Android application. One of the most common occurrences is a change in the device settings. For example, the user might leave your app running, while they go into the display settings and change the font size.

Android Font Size Setting

When the user goes back to your application, the activity in your application is recreated, which means onCreate() is called all over again. Most times, this is o.k. In fact, for the most part, you want to trust Android to handle these global settings and manage the effects of those changes to the lifecycle of your application's activities. However, there are times when you may want to manually handle these configuration changes. One obvious advantage to manually handling the config changes, is that you can avoid the activity being killed and recreated. Note that onStart(), onResume(), and onRestart() will still be called.

To manually handle config changes, simply add the "android:configChanges" attribute to the activity in your Manifest file. For example:

        <activity
            android:configChanges="fontScale"
            android:name="net.company.app.MainActivity"
            android:label="@string/app_name" >

There's a listing of the configChanges defined here: http://developer.android.com/guide/topics/manifest/activity-element.html.

The next step, is to override the onConfigurationChanged() method in the activity, like this:

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Log.i(TAG, "newConfig.fontScale = " + newConfig.fontScale);

        super.onConfigurationChanged(newConfig);
    }


When the font size changes in the device settings, your onConfigurationChanged() method is called and an object containing the new device configuration is passed to the method, for you to handle as you please.

Saturday, January 17, 2015

Android Development - Hello World Application

If you know Java, you can learn Android development. In this blog post, we'll create a very simple Android application in Android Studio and run it with an Android emulator. To get started, download the Android Studio installer here: http://developer.android.com/sdk/index.html.

Take note of the system requirements, most importantly being the Java Development Kit (JDK).

Now that you've installed Android Studio, let's create a simple application for Android. Start up Android Studio and click the option for "Start a new Android Studio project".

Welcome to Android Studio Dialog

The next dialog prompts you to name your application and provide the Company Domain. For all intents and purposes, this is simply the package name for your Java classes. Choose a name for your application and package directory and click the "Next" button.

Android Studio New Project Dialog

The next dialog prompts you for the platform where you want to develop and deploy your application. Android is a very cool platform, in that you can develop apps for TV and wearables (e.g. watches), but for this example, I'm going to select "Phone and Tablet" and choose "API 8: Android 2.2 (Froyo)" for my minimum SDK version. When you develop applications for Android, you specify the minimum and maximum SDK version. For this application, API 8 Froyo will be the minimum SDK version needed to run the application. After you select the platform, click "Next".

Android Studio Select API Version Dialog

Next, you select an activity for you application and click "Next". I'm going to choose a Blank Activity. As you get more experienced with Android development, you'll become familiar with activities and the Activity class. For now, you can think of an activity as a screen or view in your application. By choosing Blank Activity, the application will have a blank screen to start building an application.

Android Studio Activity Dialog

The next dialog prompts you for a name for the activity. I'm going to leave it as MainActivity and click "Finish".

Android Studio - Name Activity Dialog



After clicking the "Finish" button, you'll see a progress dialog, as your application is being created.

Android Studio - Create Project Progress Dialog

When Android Studio is finished building your project, you'll see your new Android application open in the IDE.

Android Studio - IDE Screenshot



Next, let's run the application in an Android emulator. You can start up an emulator from the menu option under Tools-> Android -> AVD Manager. Note that AVD Manager is short for Android Virtual Device Manager.

Android Studio - AVD Manager Menu Option

The AVD Manager dialog prompts you to start a virtual device / emulator. If you don't have a virtual device created, you need to click the button for "Create Virtual Device...". This will allow you to device configuration and Android API version that you want to emulate. For this example, I'm going to use the virtual device that emulates a Nexus 5 using API 21. Because I already have it created, I'll click the green start button on the right side of the device listing, to start the device emulator.

Android Studio - Choose Virtual Device

Next, you'll see a progress dialog, as your device emulator is starting.

Android Studio - Starting Android Virtual Device Progress Dialog

Note that it can take a few minutes to start the emulator, so be patient. After your emulator has started, you'll see the Android welcome screen (just as you'd see if you were powering on an actual Android device). After powering on, you'll see the Android home screen.

Android Studio - Galaxy Nexus Startup Screen

To unlock the welcome screen, just click on the unlock icon and swipe upwards, as you would on an actual Nexus device.



Android Studio - Galaxy Nexus Home Screen

Now that the emulator is running, go back to your Android Studio IDE to run your application on the emulator. From the Android Studio menu, select Run -> Run...


Android Studio - Run Application Menu

You'll be prompted for the device where you want to run the application. Choose the emulator that's already running and click "OK".

Android Studio - Choose Running Device Dialog

After a few seconds, you'll see the application running on the device emulator.


Android Studio - Hello World Application

Congratulations, you've just created your first Android application! In the next Android blog post, I'll talk about the project structure and the files in the project, as well as provide a more involved application example.