9781449390501
Android_User_Interface.html

Chapter 6. Android User Interface

If you're new to the Android mobile operating system, Learning Android is the perfect way to master the fundamentals. This gentle introduction shows you how to use Android's basic building blocks to develop user interfaces, store data, and more. Buy the print book or ebook.

In this chapter, you will learn how to build user interface in Android. You will create your first Activity. You will learn how to create an XML layout for it, and how to connect it to Java. You will learn about Views (a.k.a. widgets) and Layouts. You will learn how to handle events in Java, such as a button click. Additionally, you’ll add the support for twitter-like API into your project as an external jar so your app can make web service calls to the cloud.



By the end of this chapter, you will have written your own Twitter-like Android app. The app will feature a single screen that will prompt user for current status update, and post that update online.

Two Ways to Create User Interface

There are two ways to create user interface (UI) in Android. One is declarative and the other one is programmatic. They are quite different but often used together to get the job done.

Declarative User Interface

Declarative approach involves using XML to declare what the UI will look like. It is similar to creating a web page using HTML. You write tags and specify elements to appear on your screen. If you ever hand-coded an HTML page, you did pretty much the same work as creating an Android screen.

The advantages of declarative user interface are that you can use what-you-see-is-what-you-get (WYSIWYG) tools. Some of these tools ship with Eclipse Android Development Tools (ADT) extension, others come from third parties. Additionally, XML is fairly human readable and event people unfamiliar with the Android platform and framework can readily determine what the intent of the user interface is.

The disadvantages of declarative UI approach are that you can only get so far with XML. XML is great for declaring the look and feel of your user interface, but that doesn’t provide a good way of handling user input. That’s where programmatic approach comes in.

Programmatic User Interface

Programmatic user interface involves writing Java code to develop UI. For anyone who ever did any Java AWT or Java Swing development, Android is pretty much the same in that respect. It is also similar to many other UI toolkits in other languages as well.

Basically, if you want to create a button programmatically, you have to declare the button variable, create an instance of it, add it to a container that is to contain this button, and set any button properties that may make sense, such as color, text, text size, background, and so on. You would probably also want to declare what the button does once the button is clicked, so that’s another piece of code. All in all, you end up writing quite a few lines of Java.

Everything you can do declaratively, you can also do programmatically. But additionally, Java also allows you to specify what happens when that button is actually clicked. This is the main advantage of programmatic approach to user interface.

The Best of Both Worlds

So which approach to use? The best practice is to use both. You would use declarative (XML) approach to declare everything about the user interface that is static, such as the layout of the screen, all the widgets, etc. You would then switch to programmatic (Java) approach to define what goes on when user interacts with various widgets of the user interface. In other words, you’d use XML to declare what the "button" looks like, and Java to specify what it does.

Note

Note that there are two approaches to developing the actual user interface, but at the end of the day, all the XML is actually "inflated" into Java memory space as if you actually wrote Java code. So, it’s only Java code that runs.

Views and Layouts

Android organizes its UI elements into layouts and views. Everything you see, such as a button, label, or text box, is a view. Layouts organize views, such as grouping together a button and label or a group of them.

If you have prior experience with Java AWT or Swing, layouts are similar to Java containers and views are similar to Java components. Views in Android are sometimes referred to as widgets as well.

Figure 6.1. Layouts and Views relationship

Layouts and Views relationship

Note

Don’t confuse widgets in Android UI with App Widgets - miniature application views that can be embedded in other applications (such as the Home screen application). Here, we are referring to widgets as views in our activities.

So, a layout can contain other children. Those children can furthermore be layouts themselves allowing for complex user interface structure.

A layout is responsible for allocating space for each child. Different layouts use different approach to laying out their child widgets.

There are couple of main layouts that we use more frequently than others, such as Linear Layout, Table Layout, Frame Layout, Relative Layout, and Absolute Layout.

LinearLayout

LinearLayout is one of the simplest and most common layouts. It simply lays out its children next to each other, either horizontally or vertically. The order of children matters. As LinearLayout asks its children for how much space they need, it allocates desired space to each child in the order they are added. So, if an "older" child comes along and asks for all the space on the screen, there won’t be much left for the subsequent widgets in this layout.

An important property for LinearLayout are layout_orientation and valid options are vertical or horizontal.

Tip

While Linear Layout is probably the simplest and most commonly used layout, it is not always the best choice. A good rule of thumb is that if you start to nest multiple Linear Layouts, you should probably be using another layout, such as Relative Layout. Too many nested layouts can have big consequences on the time to inflate the UI and overall CPU and battery consumption.

TableLayout

TableLayout lays out its children in a table. TableLayout consists of only other TableRow widgets. TableRow represents a row in a table and can contain other UI widgets. TableRow widgets are laid out next to each other horizontally, sort of like LinearLayout with horizontal orientation.

For those familiar with HTML, Table Layout is similar to <table> element, while Table Row is similar to the <tr> element. Where as in HTML we also have <td> to represent each cell in the table, in Android the columns are determined dynamically based on the number of views we add to a table row.

An important property for TableLayout is stretch_columns indicating index of column to stretch to fill out available space. You can also use * to stretch all columns.

FrameLayout

FrameLayout places its children on top of each other so that latest child is covering the previous, like a deck of cards. This layout policy is useful for tabs, for example. FrameLayout is also used as placeholder for other widgets to be added to it programmatically at some later point in time.

RelativeLayout

RelativeLayout lays out its children relative to each other. As such, it is very powerful as it doesn’t require you to nest unnecessary layouts in order to achieve certain look. At the same time, using RelativeLayout can minimize total number of widgets that need to be drawn thus improving the overall performance of you application. Having said that, RelativeLayout requires each of its child views to have an ID set so that we can position it relatively to other children.

AbsoluteLayout

AbsoluteLayout positions its children at absolute coordinates on the screen. It is the favorite layout for WYSIWYG tools that automatically generate your UI. While very simple, it is not very flexible. Your user interface would look good on one particular screen but as soon as the screen size, orientation, or density changes, AbsoluteLayout would not be able to adjust.

Starting Yamba Project

We are about to start our Yamba project. So, fire up your Eclipse and click on File→New→Android Project.

You will get a dialog window asking you about your new Android project. Let’s explain again all the different fields that are significant.

Project Name
The name under which Eclipse organizes our project. Is is a good idea if the project name doesn’t have any spaces in it - makes it easier to access from the command line later. Enter Yamba here.
Contents
Leave this as is, set to creating a new project since that’s what we’re intending to do.
Build Target
The type of Android system we are intending to run this application on. This could be any Android platform, either standard or proprietary. I’m assuming we’re working with Android 2.3 (API level 9) and thus will choose Android 2.3.
Application name
Simply a plain text name of your application. It can be any text. For our app, feel free to enter Yamba.
Package name
A Java package, and as such it needs to adhere to Java package naming convention. In a nutshell, you want to use the reverse of your domain name for your package. I’m going to use com.marakana.yamba here.
Create Activity
An option to create an activity as part of this project. You can leave it checked. For the activity name, we must adhere to Java class naming convention. That simply means use upper CamelCase convention. I’m going to enter StatusActivity here
Min SDK Version
Represents the minimum version of Android SDK that is installed on the device in order to be able to run this particular application. Typically, this number will correspond to the API level that you picked for your target, in our case Android 9. However, if the app doesn’t depend on latest-greatest API or is capable of scaling gracefully to lower API, you should rethink this number. In our case, the app will be able to work on API level 4 (Android 1.6). So, enter 4 here. This is good because we can distribute our app to way more people than if minimum was Android 2.3.

Click on Finish. You should have Yamba project now appear in your Package Explorer in Eclipse.

Figure 6.2. New Project Dialog

New Project Dialog

StatusActivity Layout

Let’s start by designing the user interface for our screen where we’ll enter the new status and click a button to update it.

By default, Eclipse created a file called main.xml under res/layout folder. For consistency purposes, we should rename this file to status.xml to match our StatusActivity. To rename a file in Eclipse, right-click on it, choose Refactor→Rename… and enter new name. Eclipse is somewhat smart about renaming files and does more than just change the name. It also offers to lookup all the places where this file is referred from and update those references as well. While this feature works well when renaming a Java file, it is not fully automatic with XML files. So, renaming this file requires us to change the line in Java where we refer to it via the R class. To do that, in your StatusActivity’s onCreate(), change setContentView(R.layout.main); to setContentView(R.layout.status);.

This screen will have four components:

  • Title at the top of the screen. This will be a TextView widget.
  • Big text area to type our 140-character status update. We’ll use EditText widget for this purpose.
  • Button to click to update the status. This will be a Button widget.
  • A layout to contain all these widgets and lay them out one after another in vertical fashion. For this screen, we’ll use LinearLayout, one of the more common ones.

The source code for our StatusActivity layout looks like this:

Example 6.1. res/layout/status.xml

<?xml version="1.0" encoding="utf-8"?>

<!-- Main Layout of Status Activity -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <!-- Title TextView-->
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:gravity="center"
    android:textSize="30sp"
    android:layout_margin="10dp" android:text="@string/titleStatus"/>

  <!-- Status EditText  -->
  <EditText android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:layout_weight="1"
    android:hint="@string/hintText" android:id="@+id/editText"
    android:gravity="top|center_horizontal"></EditText>

  <!-- Update Button -->
  <Button android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:text="@string/buttonUpdate"
    android:textSize="20sp" android:id="@+id/buttonUpdate"></Button>

</LinearLayout>

This code was generated by Eclipse Graphical Layout. This is the part of Android Development Tools (ADT) for Eclipse plugin that helps you work with Android-specific XML files. Since ADT knows that you are working on a UI layout, it opens status.xml in Graphical Layout mode. You can also view the raw XML by choosing status.xml tab at the bottom of this window. That will give you the XML source code for this screen, as displayed above.

Figure 6.3. Graphical Layout mode for status.xml

Graphical Layout mode for status.xml

Although we discussed the basic meaning of these XML resources in a previous chapter, there are some details in the code that you should know more about, which we’ll examine in the following section.

Important Widget Properties

The properties you are most likely to use regularly are:

Important Widget Properties

layout_height and layout_width
Defines how much space this widget is asking from its parent layout to display itself. While you could enter a value in pixels, inches, or similar, that is not a good practice. Since your application could run on many different devices with various screen sizes, you want to use relative size for your components, not absolute. So, best practice would be to use either fill_parent or wrap_content for the value. fill_parent means that your widget wants all the available space from its parent. wrap_content means that it only requires as much space as it needs to display its own content. Note that in API Level 8 and higher, fill_parent has been renamed to match_parent.
layout_weight
Layout weight is a number between 0 and 1. It implies the weight of our layout requirements. For example, if our Status EditText had default layout weight of 0, and required layout height of fill_parent, then the Update button would have been pushed out of the screen since Status, and its request for space came before the button. However, when we set Status widget’s layout weight to 1, we are saying we want all available space height-wise, but are yielding to any other widget that also may need space, such as the Update button.
layout_gravity
Specifies how this particular widget is positioned within its layout, both horizontally and vertically. Values could be top, center, left, and so on. Notice the difference between this property and gravity below. For example, if you have a widget that has width set to fill_parent, trying to center it wouldn’t do much since it’s already taking all available space. However, if our title TextView had width set to wrap_content, centering it with layout_gravity would generate desired results.
gravity
Specifies how the content of this widget is positioned within the widget itself. It is commonly confused with layout_gravity. Which one to use will depend on size of your widget and desired look. For example, if our title TextView had width fill_parent, then centering it with gravity would work but centering it with layout_gravity wouldn’t do anything.
text
Not all widgets have this property, but many do, such as Button, EditText, and TextView. It simply specifies the text for the widget. Now, it is not a good practice to just enter the text because than your layout will only work in one locale/language. Best practice is to define all text in strings.xml resource and refer to particular string via this notation: @string/titleStatusUpdate.
id
id is simply the unique identifier for this particular widget in particular layout resource file. Not every widget needs an id and I recommend removing id’s if not needed to minimize clutter. But widgets that we’ll later need to manipulate from Java do need id’s. Id has the following format: @+id/someName where someName is whatever you want to call your widget. My naming convention is to use type followed by name, so @+id/buttonUpdateStatus for example.

Strings Resource

Android tries hard to keep data in separate files. So, layouts are defined in their own resources, and all text values (such as button text, title text, etc.) should be defined in their own file called strings.xml. This later allows you to provide multiple versions of strings resources to be used for various languages, such as English, Japanese, or Russian.

Here’s what our strings.xml file looks like at this point:

Example 6.2. res/values/strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <string name="app_name">Yamba 1</string>

  <string name="titleYamba">Yamba</string>
  <string name="titleStatus">Status Update</string>

  <string name="hintText">Please enter your 140-character status</string>
  <string name="buttonUpdate">Update</string>
</resources>

That this is simply a set of name/value pairs.

Tip

I use a certain naming convention for my resource names. Let’s look at titleYamba, for example. First, I prefix the resource with the name of what it is, in this case a title of the activity. Secondly, I give it a name, Yamba. This naming convention helps later on keep many different resources sorted in a easy to find way. Finally, I use CamelCase for my names while some may prefer to use underscores to separate words.

StatusActivity Java Class

Now that we have our UI designed in XML, we are ready to switch over to Java. Remember from earlier in this chapter that Android provides two ways to building user interface. One is by declaring it in XML, which is what we just did. And we got as far as we could (for now). The other one is to programmatically build it in Java. We also said earlier that the best practice is to get as far as possible in XML, and then switch over to Java.

Our Java class for this is StatusActivity.java and the Eclipse New Project Dialog has already created the stub for this class for us. The class is part of com.marakana.yamba1 Java package, and as such is part of that directory.

Creating your application-specific object and initialization code

As with all Main Building Blocks in Android, such as Activities, Services, BroadcastReceivers and ContentProviders, you usually start by subclassing a base class provided by the Android framework, and overriding certain inherited methods. In this case, we subclass Android’s Activity class and override its onCreate() method. As you recall, activities have a certain lifecycle the section called “Activity Lifecycle”, or state machine through which they go. We as developers do not control what state the activity is in, but we do get to say what happens at a transition to a particular state. In this case, the transition we want to override is onCreate() method that is invoked by the system’s ActivityManager when the activity is first created (i.e. it goes from Starting the section called “Starting State” to Running the section called “Running State” state). This sort of programming when we subclass a system class and fill out the blanks is also known as Template pattern.

Our onCreate(), in addition to doing some standard housekeeping, will carry out two major tasks that the application needs done just once, and done at the beginning. We’ll set up our button so it responds to clicks, and connect to the cloud.

Notice that onCreate() take a Bundle as a parameter. This is a small amount of data that can be passed into the activity via the Intent that started it. The data provided in a Bundle is typically limited to basic data types and more complex ones need to be specially encoded. For the most part, we’re not going to be using Bundle in Yamba example as there’s no real need for us.

Keep in mind that whenever you override a method, you first want to make a call to the original method provided by the parent. That’s why we have super.onCreate() call here.

So, once you subclass the framework’s class, override the appropriate method, and call super’s method in it, you are still back at status quo - your code does the same thing the original class did. But now we have a placeholder where we can add our own code.

The very first thing we typically do in activity’s onCreate() is to load the UI from the XML file and inflate it into the Java memory space. In other words, we write some Java code that opens up our XML layout file, parses it, and for each element in XML it creates a corresponding Java object in our memory space. For each attribute of a particular XML element, this code will set that attribute on our Java object. This process is called inflating from XML and the line of code that does all this is setContentView(R.layout.status);.

Remember that R class is the automatically generated set of pointers that helps connect the world of Java to our world of XML and other resources in /res folder. Similarly, R.layout.status points to our /res/layout/status.xml file.

This method setContentView() does a lot of work, in other words. It reads the XML file, parses it, creates all the appropriate Java objects to correspond to XML elements, sets object properties to correspond to XML attributes, sets up parent/child relationships between objects and overall inflates the entire view. At the end of this one line, our screen is ready for drawing.

Your objects are not the only ones that define methods and respond to external stimuli. Android’s user interface objects do that too. Thus, you can tell your Button to execute certain code when its clicked. To do that, you need to define a method named onClick() and put the code there that you want executed. You also have to run the setOnClickListener method on the Button. You pass this as an argument to setOnClickListener because your object is where you define onClick().

Example 6.3. StatusActivity.java, version 1

package com.marakana.yamba1;

import winterwell.jtwitter.Twitter;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class StatusActivity1 extends Activity implements OnClickListener { // 1
  private static final String TAG = "StatusActivity";
  EditText editText;
  Button updateButton;
  Twitter twitter;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.status);

    // Find views
    editText = (EditText) findViewById(R.id.editText); // 2
    updateButton = (Button) findViewById(R.id.buttonUpdate);

    updateButton.setOnClickListener(this); // 3

    twitter = new Twitter("student", "password"); // 4
    twitter.setAPIRootUrl("http://yamba.marakana.com/api");
  }

  // Called when button is clicked // 5
  public void onClick(View v) {
    twitter.setStatus(editText.getText().toString()); // 6
    Log.d(TAG, "onClicked");
  }
}

1

To make StatusActivity capable of being a button listener, it needs to implement OnClickListener interface.

2

Find views inflated from the XML layout and assign them to Java variables.

3

Register the button to notify this i.e. StatusActivity when it gets clicked on.

4

Connect to the online service that supports Twitter API. At this point, we hard code the username and password.

5

The method that is called when button is clicked, as part of OnClickListener interface.

6

Make the web service API call to the cloud to update our status.

Compiling Code and Building Your Projects: Saving Files

Once you make changes to your files, Java or XML, make sure you save them before moving on. Eclipse builds your project automagically every time you choose File→Save or press Ctrl-S. So, it is important to save files and make sure you do not move to another file until the current file is fine. You will know your file is fine if there are no little red x symbols in your code and the project builds successfully. Since Java depends on XML and vice versa, moving to another file while the current one is broken just makes it even more difficult to find errors.

Java errors are typically easy to find since the little red x in the code navigates you straight down to the line number where the error occurred. By putting your mouse right on that error, Eclipse will tell you what the error is and it will also offer you some possible fixes. This feature of Eclipse is very useful and is analogous to spell checker in a word processor.

Figure 6.4. Tracing Java Errors

Tracing Java Errors

Adding jtwitter.jar Library

We are connecting to the the online service that implements Twitter-compatible API in our application. This connection is done via a series of web service calls. Since Android uses standard Java networking capabilities, there’s not much new in Android with respect to web services than we already have in Java. So, as such, there’s little value in reinventing the wheel.

To make our life with web services and Twitter API easier, we’re going to use a third-party library, jtwitter.jar, provided by Winterwell Associates. This library provides a simple Java class to interact with the online service and abstracts all the intricacies of making network calls and passing the data back and forth. If no one has been kind enough to provide a high-level library like jtwitter for what we want to do, we could always use standard Java networking libraries to get the job done. It would just have been more work.

Note

The jtwitter.jar library provided with this code has been slightly modified from the official Winterwell version to make it work in Yamba project.

Once you download this library, you can put it inside your project in Eclipse. You can simply drag the jtwitter.jar file and drop it in the root of your Eclipse project in Package Manager window. This makes the file part of the project, but our Java code is still unable to locate it.

Java searches for all the classes in its classpath. To add it to the classpath, right-click on your project, select Properties and you will get a Properties for Yamba dialog window. Select Java Build Path and choose Libraries tab. In there, click on Add JARs… and locate your jtwitter.jar file. This will add this JAR file to your projects classpath.

Figure 6.5. Properties for Yamba project in Eclipse where we add the jtwitter.jar file.

Properties for Yamba project in Eclipse where we add the jtwitter.jar file.

Updating Manifest File for Internet Permission

Before this application can work, we must ask user to grant us right to use the internet. The way Android manages security is by specifying permissions needed for certain dangerous operations. User then must explicitly grant those permissions to each application when he/she installs the application first time around. User must grant all or no permissions that the application asks for - there’s no middle ground. Also, user is not prompted about permissions upon upgrading an existing app.

Note

Since we are running this application in debug mode and installing it via USB cable, Android doesn’t prompt us for permissions like it would the end user. However, we still must specify that the application requires certain permissions.

In this case, we want to ask user to grant this application the use of INTERNET permission. We need internet in order to connect to the online service. So, open up AndroidManifest.xml file by double-clicking on it. Note that Eclipse typically opens this file in a WYSIWYG editor with many tabs on the bottom. As always, you can make most of the changes to this file via this interface, but since Eclipse tools are limited and sometimes buggy, we prefer to go straight into the XML view of this file. So, choose the right-most tab in the bottom that says AnddroidManifest.xml and add <uses-permission android:name="android.permission.INTERNET" /> element within the <manifest> block.

Example 6.4. AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:versionCode="1" android:versionName="1.0" package="com.marakana.yamba1">
  <application android:icon="@drawable/icon" android:label="@string/app_name">

    <activity android:name=".StatusActivity" android:label="@string/titleStatus">
      <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
      </intent-filter>
    </activity>

  </application>
  <uses-sdk android:minSdkVersion="4" />

  <uses-permission android:name="android.permission.INTERNET" /> <!-- 1 -->
</manifest>

1

Defines the <uses-permission> element for INTERNET permission.

Logging in Android

Android offers a system-wide logging capability. You can log from anywhere in your code by calling Log.d(TAG, message), where TAG and message are some strings. TAG should be a tag that is meaningful to you given your code. Typically, tag would be the name of your app, your class or some module. Good practice is to define TAG as a Java constant for your entire class, such as:

private static final String TAG = "StatusActivity";

Tip

Before your code will compile, you need to import Log class. Eclipse has a useful feature under Source→Organize Imports, or Ctrl+O for short. Usually, this feature will automatically organize your import statements. However, in case of Log, there is usually a conflict because there are multiple classes with name Log. This is where you have to use your common sense and figure it out. In this case, the ambiguity is between Android Log and Apache Log classes, so choice should be easy.

Warning

Eclipse’s Organize Imports tool can sometimes lead to hard-to-find problems. For example, if your project doesn’t have R.java generated (which could easily happen because there’s an earlier problem with one of XML resources) then Organize Imports will import android.R class. This other R class is part of Android framework and has the same name as your local R class, making it hard to notice. So, if you have many compilation errors around your references to R resources, check that android.R is not imported.

Note that Log takes different severity levels. .d() is for debug level. You can also specify .e() for Error, .w() for warning, .i() for info. There’s also .wtf() severity level for errors that should never happen. It stands for What a Terrible Failure, in case your wondered. Eclipse color-codes log messages based on their severity level.

LogCat

The Android system log is outputted to LogCat. LogCat is a standardized system-wide logging mechanism. LogCat is readily available to all Java and C/C++ code. The developer can easily view the logs and filter their output based on severity, such as debug, info, warning, or error, or based on custom-defined tags. As with most things in Android development, there are two ways to view the LogCat: via Eclipse or via the command line.

LogCat from Eclipse DDMS Perspective

To view logcat in Eclipse, you need to open the LogCat View. It is typically available in DDMS perspective to which you can switch by clicking on DDMS in top-right corner of Eclipse or by going to Window→Open Perspective→DDMS in the Eclipse menu.

DDMS stands for Dalvik Debug Monitor Server. DDMS is the connection between your application running on the device and your development environment, such as Eclipse.

Figure 6.6. LogCat in Eclipse

LogCat in Eclipse

You can define filters for LogCat as well. Click on the little green plus button and LogCat Filter dialog will come up. You can define a filter based on TAG, severity, or process id. This will create another window within LogCat showing you only the log entries that match your filter.

Figure 6.7. LogCat Filter

LogCat Filter

Note

DDMS may not show up for in the top right corner right away if you haven’t used it before. If that’s the case, go to Window→Open Perspective and choose DDMS there. From there on, it should show in your window tab as well.

LogCat from command line

Just like all the tools, anything you can do in Eclipse, you can do from command line as well. To view logcat, open up your terminal window and type:

[user:~]> adb logcat

This will give you the tail of current logcat and will be updated as your device keeps generating log entries. You can also filter log entries on command line, but the syntax is not the most intuitive. To only see StatusActivity-tagged entries, you specify StatusActivity:*, meaning you want all severity levels for this tag. However, you also have to specify what you don’t want to see. To do that, you add *:S, meaning silence all other tags. The following command line illustrates that:

[user:~]> adb logcat StatusActivity:* *:S

Tip

I find it useful to keep a command line window open with adb logcat running in it at all times. This makes it easy for me to quickly see what’s going on with my app and is certainly much faster than switching to DDMS perspective in Eclipse.

Threading in Android

A thread is a sequence of instructions executed in order. Although each CPU can only process one instruction at a time, most operating systems are capable of handling multiple threads on multiple CPUs, or interleaving them on a single CPU. Different threads need different priorities, so the operating system determines how much time to give each one if they have to share a CPU.

Android operating system is based on Linux and as such is fully capable of running multiple threads at the same time. However, you as application developer need to be aware how applications use threads in order to design your application properly.

Single Thread

By default, an Android application runs on a single thread. Single threaded application run all commands in serially, meaning the next command is not completed until the previous one is done. Another way of saying the same thing is that each call is blocking.

Figure 6.8. Single Threaded Execution

Single Threaded Execution

This single thread is also known as the UI (as in User Interface) thread since that’s the thread that processes all the user interface commands as well. The UI thread is responsible for drawing all the elements on the screen as well as processing all the user events, such as touches of the screen, clicks on the button, and so on.

The problem with running StatusActivity on the single thread is our network call to update the our status. As with all network calls, the time it takes to execute is outside of our control. Our call to twitter.updateStatus() is subject to all the network availability and latency issues. We don’t know if the user is on the super fast WiFi connection, or is using a much slower protocol to connect to the cloud. In other words, our application cannot respond until the network call is completed.

Note

Android system will offer to kill any application that is not responding within a certain time period, typically around five seconds for activities. This is known as Application Not Responding dialog, or ANR for short.

Figure 6.9. Application Not Responding

Application Not Responding

Multithreaded Execution

A much better solution is to have the potentially long operations run on a separate thread. When multiple tasks run on multiple threads at the same time, the operating system slices the available CPU so that no one task dominates the execution. The result is that appears that multiple tasks are running in parallel at the same time.

Figure 6.10. Multithreaded Execution

Multithreaded Execution

In our example, we could put the actual network call of updating our status in the cloud in a separate thread. That way our main UI thread will not block while we’re waiting for the network and the application will appear much more responsive. We tend to talk of the main thread as running in the foreground and the additional threads as running in the background. They’re really all equal in status, alternating execution on the device’s CPU, but from the point of view of the user, the main thread is in the foreground because it deals with the UI.

There are multiple ways of accomplishing multithreading. Java has a class Thread that allows for many of these operations. We could certainly use any of the regular Java features to handle putting the network call in the background.

However, one of the problems that we’d run into by using standard Java Thread class is that another thread is not allowed to update the elements in the main UI thread. This make sense since to update the UI thread we would need to synchronize with the current state of its objects and that would be a job on its own.

In addition to standard Java threading support, Android provides a utility class AsyncTask specifically designed for this purpose.

AsyncTask

AsyncTask is an Android mechanism created to aid in handling long operations that need to report to UI thread. To take advantage of this class, we need to crate a new subclass of AsyncTask and implement doInBackground(), onProgressUpdate(), and onPostExecute() methods. In other words, we are to fill out the blanks for what to do in the background, what to do when there’s some progress and what to do when done with this task.

We’ll extend our earlier example with an asynchronous posting to the cloud. The first part of the example is very similar to the code in Example 6.3, “StatusActivity.java, version 1” but it hands off the posting to the asynchronous thread. A new AsyncTask does the posting in the background.

Example 6.5. StatusActivity.java, version 2

package com.marakana.yamba1;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

public class StatusActivity2 extends Activity implements OnClickListener {
  private static final String TAG = "StatusActivity";
  EditText editText;
  Button updateButton;
  Twitter twitter;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.status);

    // Find views
    editText = (EditText) findViewById(R.id.editText);
    updateButton = (Button) findViewById(R.id.buttonUpdate);
    updateButton.setOnClickListener(this);

    twitter = new Twitter("student", "password");
    twitter.setAPIRootUrl("http://yamba.marakana.com/api");
  }

  // Asynchronously posts to twitter
  class PostToTwitter extends AsyncTask<String, Integer, String> { // 1
    // Called to initiate the background activity
    @Override
    protected String doInBackground(String... statuses) { // 2
      try {
        Twitter.Status status = twitter.updateStatus(statuses[0]);
        return status.text;
      } catch (TwitterException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
        return "Failed to post";
      }
    }

    // Called when there's a status to be updated
    @Override
    protected void onProgressUpdate(Integer... values) { // 3
      super.onProgressUpdate(values);
      // Not used in this case
    }

    // Called once the background activity has completed
    @Override
    protected void onPostExecute(String result) { // 4
      Toast.makeText(StatusActivity2.this, result, Toast.LENGTH_LONG).show();
    }
  }

  // Called when button is clicked
  public void onClick(View v) {
    String status = editText.getText().toString();
    new PostToTwitter().execute(status); // 5
    Log.d(TAG, "onClicked");
  }

}

1

The PostToTwitter class in this case is an inner class of StatusActivity. It also subclasses AsyncTask. Notice the use of Java generics to describe the data types that this AsyncTask will use in its methods. We’ll refer to these three types below. The first data type is used by doInBackground, the second by onProgressUpdate, and the third by onPostExecute

2

doInBackground() is the callback that specifies the actual work to be done on the separate thread, as if it’s executing in the background. The argument String... is the first of the three data types that we defined in the list of generics for this inner class above. The fact that it’s followed by three dots indicates that this is an array of Strings and you have to declare it that way even though you want to pass only a single status.

3

onProgressUpdate() is called whenever there’s progress in the task execution. The progress should be reported from the doInBackground() call. In this case, we do not have a meaningful progress to report. In another example, such as file download for instance, this could report the percentage of completion or amount of data downloaded thus far. The actual data type, in this case Integer refers to the second argument in the generics definition of this class.

4

onPostExecute() is called when our task is completed. This is our callback method to update the user interface and tell the user that task is done. In this particular case, we are using Toast feature of Android UI to show a quick message on the screen. Notice that Toast uses makeText() static method to make the actual toast message. Also, do not forget the call show() on the toast, otherwise your message will never be displayed and there won’t even be any errors - a hard bug to find. The argument that this method gets is the value that doInBackground() returns, in this case a String. This also corresponds to the third generics datatype in the class definition.

5

Once we have out AsyncTask setup, we can use it. To use it, we simply instantiate it and call execute() on it. The argument that we pass in is what goes into doInBackground() call. Note that in this case we are passing a single String that is being converted into a String array in the actual method later on. This is the use of Java’s variable number of arguments feature.

At this point, when user clicks on Update Status button, our activity will create a separate thread using AsyncTask and place the actual network operation on that thread. When done, the AsyncTask will update the main UI thread by popping up a Toast message to tell the user that operation either succeeded or failed. This approach makes our application much more responsive and user should never get "Application Not Responding: Force Close or Wait" message again, as shown in Figure 6.9, “Application Not Responding”.

Figure 6.11. StatusActivity, Part 1

StatusActivity, Part 1

Other UI Events

So far, you have seen how to handle the click events by implementing OnClickListener and providing the onClick() method so that when the button is clicked this method is invoked. Imagine that we want to provide a little counter telling user how many characters are still available on the input from the maximum of 140. To do that, we need another type of listener.

Android provids many different listeners for various events, such as touch, click, and so on. In this case, we’re going to use TextWatcher to watch for text changes on the edit text field. Steps for this listener are similar to the steps for OnClickListener and are similar to many other listeners.

From users stand point, we’ll add another TextView to our layout to indicate the number of characters still available to type. This text will change color, from green to yellow and red as user approaches the limit.

From Java point of view, we’ll implement TextWatcher and attach it to our text field where the user is typing the actual text. The TextWatcher methods will be invoked as user changes the text and based on the amount of text entered we’ll update the counter.

Example 6.6. res/layout/status2.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Main Layout of Status Activity -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent">

  <!-- Title TextView-->
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:gravity="center"
    android:text="@string/titleStatus" android:textSize="30sp"
    android:layout_margin="10dp" />

  <!-- Text Counter TextView 1 -->
  <TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:layout_gravity="right"
    android:id="@+id/textCount" android:text="000"
    android:layout_marginRight="10dp" />

  <!-- Status EditText  -->
  <EditText android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:layout_weight="1"
    android:hint="@string/hintText" android:id="@+id/editText"
    android:gravity="top|center_horizontal"></EditText>

  <!-- Update Button -->
  <Button android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:text="@string/buttonUpdate"
    android:textSize="20sp" android:id="@+id/buttonUpdate"></Button>

</LinearLayout>

1

New TextView that represents the count of how many characters are still available for user to type. We start at 140 and then go down as user enters text.

The following version of Status Activity implements the TextWatcher interface, and the new methods in this example appear at the end of the class. Initially the text of the counter is in green color to indicate we can keep on typing. As we approach the maximum, the text turns yellow and eventually becomes red to indicate we are beyond the maximum message size.

Example 6.7. StatusActivity.java, final version

package com.marakana.yamba1;

import winterwell.jtwitter.Twitter;
import winterwell.jtwitter.TwitterException;
import android.app.Activity;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class StatusActivity extends Activity implements OnClickListener,
    TextWatcher { // 1
  private static final String TAG = "StatusActivity";
  EditText editText;
  Button updateButton;
  Twitter twitter;
  TextView textCount; // 2

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.status);

    // Find views
    editText = (EditText) findViewById(R.id.editText);
    updateButton = (Button) findViewById(R.id.buttonUpdate);
    updateButton.setOnClickListener(this);

    textCount = (TextView) findViewById(R.id.textCount); // 3
    textCount.setText(Integer.toString(140)); // 4
    textCount.setTextColor(Color.GREEN); // 5
    editText.addTextChangedListener(this); // 6

    twitter = new Twitter("student", "password");
    twitter.setAPIRootUrl("http://yamba.marakana.com/api");
  }

  // Called when button is clicked
  public void onClick(View v) {
    String status = editText.getText().toString();
    new PostToTwitter().execute(status);
    Log.d(TAG, "onClicked");
  }

  // Asynchronously posts to twitter
  class PostToTwitter extends AsyncTask<String, Integer, String> {
    // Called to initiate the background activity
    @Override
    protected String doInBackground(String... statuses) {
      try {
        Twitter.Status status = twitter.updateStatus(statuses[0]);
        return status.text;
      } catch (TwitterException e) {
        Log.e(TAG, e.toString());
        e.printStackTrace();
        return "Failed to post";
      }
    }

    // Called when there's a status to be updated
    @Override
    protected void onProgressUpdate(Integer... values) {
      super.onProgressUpdate(values);
      // Not used in this case
    }

    // Called once the background activity has completed
    @Override
    protected void onPostExecute(String result) {
      Toast.makeText(StatusActivity.this, result, Toast.LENGTH_LONG).show();
    }
  }

  // TextWatcher methods
  public void afterTextChanged(Editable statusText) { // 7
    int count = 140 - statusText.length(); // 8
    textCount.setText(Integer.toString(count));
    textCount.setTextColor(Color.GREEN); // 9
    if (count < 10)
      textCount.setTextColor(Color.YELLOW);
    if (count < 0)
      textCount.setTextColor(Color.RED);
  }

  public void beforeTextChanged(CharSequence s, int start, int count, int after) { // 10
  }

  public void onTextChanged(CharSequence s, int start, int before, int count) { // 11
  }

}

1

We declare that StatusActivity now implements TextWatcher. This means we need to actually provide the implementation for this interface, which we do later on in this class.

2

textCount is our text view that we defined in the layout above.

3

First, we need to find the textCount in the inflated layout.

4

We set the initial text to 140 since that’s the maximum length of a status message in our app. Note that TextView takes text as value, so we convert a number to text here.

5

The textCount field will dynamically change color based on how much text is left to type. In this case, we start with green. Notice that Color class is part of Android framework and not Java. In other words, we’re using android.graphics.Color and not java.awt.Color. Color.GREEN is one of the few colors defined as a constant in this class. More on colors in the next section.

6

Here we attach the TextWatcher to our editText field. In other words, editText will call TextWatcher instance, in this case this which refers to this object itself.

7

afterTextChanged() is one of the methods provided by the TextWatcher interface. This method is called whenever the text changes in the view that this TextWatcher is watching. In our case, whenever user changes the underlying text in editText, this method is invoked with the current text.

8

Here we do some math to figure out how many characters are left given the 140 character limit.

9

Next, based on the availability of the text, we update the color of the counter. So, if more than 10 characters are available, we are still in the green. Fewer than 10 means we are approaching the limit, thus yellow color. If we are pass the limit of 140 characters, the counter turns red.

10

This method is called just before the actual text replacement is completed. In this case, we don’t need this method, but as part of implementing the TextWatcher interface, we must provide its implementation, event though its empty.

11

Similarly, we are not using onTextChanged() in this case, but must provide its blank implementation.

Figure 6.12. StatusActivity, Part 1

StatusActivity, Part 1

Adding Color & Graphics

Our application works well, but it’s a bit dull looking. A little bit of color and graphics could go along way. Android offers a lot of support to make your application snazzy. We’re going to see some basics here.

Adding Images

For starters, we want to add a background to our screen. This background is going to be some kind of graphics file. In Android, most images go to a resource folder called drawable. You may notice that you already have three folders with such name:

  • /res/drawable-hdpi for devices with high density screens
  • /res/drawable-mdpi for devices with medium density screens
  • /res/drawable-ldpi for devices with low density screens

We are going to create another drawable folder called just /res/drawable. To do that, right-click on the res folder and choose New→Folder. For name, enter drawable. You can now put your graphics that are independent of screen density in this folder. We’re going to assume you found some cool background graphics and that you saved it in there under the name background.png. While Android supports many different file formats, PNG is preferred since to the once-controversial GIF standard because PNG is lossless and doesn’t require any patent licenses.

Tip

While PNG officially stands for Portable Network Graphics, it is also commonly known as PNG’s Not Gif to reflect its departure from controversial GIF standard.

Remember that all resources are being "watched" by Eclipse, and the moment we put something in there, Eclipse will use Android SDK tools to update the R class automatically. That means that at this point, we’ll have a reference R.drawable.background available to us if we wanted to use this resource from Java. But we’re not.

We are going to update our status activity layout file res/layout/status.xml next. Our goal is to have this background be the background of the entire screen. To do that, we’ll update the top layout in our file and set it’s background to point to this new background PNG file. To do that, we have to open the status.xml layout. Now we have two ways of adding the background to the top layout.

Using WYSIWYG Editor In Eclipse

One way is to do it using the WYSIWYG tool that Eclipse provides. In this tool, we need to first select the main layout. We may have hard time selecting it since many other components are in front of it. The red border tells you what view or layout is selected at a time.

Another way of selecting it is to open up your Outline view in Eclipse and selecting the top element there. This view may or may not be currently visible in your Eclipse, depending on how you arranged many windows that are available. One sure way to get Outline view is to go to Window→Show View→Outline and open it up that way. Once you get this view opened, you can select the top layout, in this case our LinearLayout. You will know it’s selected if a red border is around your entire activity.

Next, you want to open up the Properties view in Eclipse. Again, this view may already be opened or may not be. If it’s not visible as a window in Eclipse, go to Window→Show View→Other and under General section pick Properties. This will open up a view in which you can change various properties for this particular view.

The property we want to modify is background. You can now click on the little button which will bring up Reference Chooser dialog. In this dialog, choose Drawable→background.

Figure 6.13. Reference Chooser

Reference Chooser

This will set the background of your top layout to @drawable/background. As you recall, this is the way that one XML resource refers to another resource. In this case, our status.xml layout is referring to the background.png drawable. Notice that we do not use extensions when referring to other file resources. Android figures out best file format automatically, in case there are files with same name but of different extension.

Figure 6.14. Eclipse Graphical Layout Editor

Eclipse Graphical Layout Editor

Updating Directly in XML Code

Another approach is always to go straight into the XML code and make changes there. Remember that everything you can do with Eclipse tools, you can also do in plain text editor. To switch to XML code view, select the tab status.xml in the bottom of the window, next to Layout tab. This will open up your file with standard XML editor.

In this case, to add background resource to our entire activity we simply add android:background="@drawable/background" to our to `<LinearLayout> element.

From now on, we’re going to be making changes in XML code directly since it’s much simpler to explain. Also, the WYSIWYG Editor can only do so much and often you run into its limitations.

Adding Color

We now have the background for the entire screen, but what about the actual text box that user types the text to? The current design is stock. We could improve on it by adding some color and transparency to it.

Android uses the standard RGB color set but it also optionally expands it with an Alpha channel. So, you can express color as RGB or ARGB where A is the amount of transparency, R is the amount of red, G is for green and B stands for blue color. The combination of these three colors and optional transparency gives you every conceivable color from white to black, and from opaque to fully transparent! That’s the whole point of ARGB. Of course, the granularity isn’t exactly what Monet would be happy with; each value has only 256 possibilities.

Amounts of each can be represented either as values between 0 and 255, or using Hexadecimal system as values between 0 and FF. So, the actual values values can be AARRGGBB where each letter can be replaced with a value between 0 and F. There’s also a shorter version ARGB where for each value, it is repeated so that each two digits are the same. For example, #3A9F is the same as #33AA99FF and corresponds to #33 for alpha, #AA for red, #99 for green and #FF for blue. Notice that we use # symbol in front of hexadecimal values to distinguish them from decimal values.

So, we could update the background of our EditText element to be #cfff, which is somewhat transparent white color.

Next, we can also update the color of the title text by changing the textColor property for that TextView. A good color would be white, for example. One way to specify white would be #fff but another way would be to enter @android:color/white. The android: part of that statement refers to Android operating system set of resources, in this case a predefined color white.

Example 6.8. res/layout/status.xml

<?xml version="1.0" encoding="utf-8"?>

<!-- Main Layout of Status Activity -->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  android:orientation="vertical" android:layout_width="fill_parent"
  android:layout_height="fill_parent" android:background="@drawable/background"><!--1-->

  <!-- Title TextView-->
  <TextView android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:gravity="center"
    android:text="@string/titleStatus" android:textSize="30sp"
    android:layout_margin="10dp" android:textColor="@android:color/white" /><!--2-->

  <!-- Text Counter TextView -->
  <TextView android:layout_width="wrap_content"
    android:layout_height="wrap_content" android:layout_gravity="right"
    android:id="@+id/textCount" android:text="000"
    android:layout_marginRight="10dp" />

  <!-- Status EditText  -->
  <EditText android:layout_width="fill_parent"
    android:layout_height="fill_parent" android:layout_weight="1"
    android:hint="@string/hintText" android:id="@+id/editText"
    android:gravity="top|center_horizontal" android:background="#cfff" /><!--3-->

  <!-- Update Button -->
  <Button android:layout_width="fill_parent"
    android:layout_height="wrap_content" android:text="@string/buttonUpdate"
    android:textSize="20sp" android:id="@+id/buttonUpdate" />

</LinearLayout>

1

We set the background of the main layout to point to background.png file in /res/drawable/ directory.

2

We set the color of the title text to point to color defined in system color resource white.

3

We set the background of the edit text area to be a transparent white by specifying #cfff for color using hexadecimal ARGB value.

At this point you’ve seen multiple ways to specify color of couple of different properties of various views in your activity. There are many properties and many different widgets that Android offers. You should be able to extrapolate from this how to set other properties and make your application UI look exactly the way you want.

Alternative Resources

Android supports multiple competing sets of resources. For example, you could have multiple versions of strings.xml file or status.xml layout, or background.png image. The reason why you would want multiple versions of same resource is to have best version be used in given circumstances. We have discussed this in the section called “Adding Images”.

Imagine that your application is used in another country with different language. In that case, you could provide strings.xml version specifically for that language. Or imagine that user runs your application on a different device, with different screen that has more pixels. In that case, you’d want versions of your images specific for this screen pixel density. Similarly, user may simply rotate the device from portrait to landscape mode. While our application will redraw properly, there are further enhancements we could do to the layout of the UI given orientation of the screen.

Android provides for all these cases in an elegant way. Basically, you simply need to create alternative folders for specific constraints. For example, our standard layout files go into /res/layout folder. Well, if we wanted to provide an alternative layout to be used specifically in landscape mode, we’d simply create a new file /res/layout-land/status.xml. And if you wanted to provide translated version of your strings.xml file to be used for users that are in French part of Canada, you’d put it in file called res/values-fr-rCA/strings.xml.

As you see from these couple of examples, the way alternative resources work is by specifying the qualifiers in the name of the resource folder. In case of French Canadian strings, Android knows that the first qualifier -fr refers to language and second qualifier -rCA specifies that the region is Canada. In both cases, we use Two-letter ISO codes to specify the country. So in this case, if the user is in Quebec for instance, and her device is configured to favor French language, Android will look for string resources in /res/values-fr-rCA/strings.xml file. If it doesn’t find a specific resource, it will fall back to default /res/values/strings.xml file. Also, if the user in France, Android in this case will use default resource since our French Canadian qualifiers do not match French for France.

Using qualifiers you can create alternative resources for languages and regions, screen sizes and orientations, device input modes (touch screen, stylus), keyboard or no keyboard, and so on. But how do you know what this naming convention for resource folder names is? The easiest tool is to use the New Android XML File dialog in Eclipse. To open New Android File dialog, choose File→New…→Android XML File from the Eclipse menu.

Figure 6.15. Alternative Resources with New Android XML File Dialog

Alternative Resources with New Android XML File Dialog

Optimizing User Interface

User interface is one of the most expensive parts of a typical Android application. To create a simple screen, your application has to inflate the XML from resources. For each element, it has to create a new Java object and assign its properties to it. Then it needs to draw each widget on the screen. All this takes many computing cycles.

Given all this, it is worth keeping in mind few optimization points. You may want to try to limit number of widgets you have on the screen. This is specially true when you are using nested layouts to achieve desired look. This can sometimes get out of control and if you are nesting unnecessary objects in a loop (say, displaying rows of data on the screen), then the number of widgets quickly explodes and your user interface becomes sluggish.

Generally, you want your structure to be flat instead of deep. You can accomplish this by replacing nested layouts with relative layouts.

Hierarchy Viewer

There’s a very useful tool that ships with Android SDK called Hierarchy Viewer. Go ahead and start it - it is in your SDK/tools directory.

Hierarchy Viewer allows you to attach to any Android device, emulator or physical phone. You can then introspect the structure of the current view. It shows you all the widgets currently loaded in memory, their relationship to each other, and all their properties. You can introspect not just your screens but screens of any application on your device. This is also a good way to see how some other applications are structured.

Figure 6.16. Hierarchy Viewer

Hierarchy Viewer

Summary

By the end of this section, you should have your application run and look like Figure 6.17, “StatusActivity”. It should also successfully post your tweets to your twitter account. You can verify it is working by logging into the online service of your choice that supports Twitter API, such as yamba.marakana.com using the same username/password as hard coded in the application.

Figure 6.17. StatusActivity

StatusActivity

The following illustrates what we have done so far as part of the design outlined in Figure 5.4, “Yamba Design Diagram”:

Figure 6.18. Yamba Completion

Yamba Completion

Site last updated on: April 8, 2011 at 12:51:47 PM PDT
Cover for Learning Android

View 1 comment

  1. Frank Cauley – Posted Aug. 22, 2011

    I am trying to get the Yamba application described at location 1708 in the book purchased on Kindle using the cloud reader.

    I am getting the following error and suggestion form the android sdk:

    ultiple markers at this line - The type StatusActivity1 must implement the inherited abstract method DialogInterface.OnClickListener.onClick(DialogInterface, int) - The public type StatusActivity1 must be defined in its own file

    The line in question is as follows:

    public class StatusActivity1 extends Activity implements OnClickListener {

Add a comment

View 3 comments

  1. fmaker – Posted Sept. 21, 2010

    Let's build some excitement, this is a neat little project: "...you'll have your own customized twitter application using the same interfaces as any other Twitter application." or something like that.

  2. erik runia – Posted Jan. 7, 2011

    You have used "Twitter-like" in previous paragraphs but "post tweets to Twitter" in this one, should change this one or the prior ones to match reality. Are we posting to twitter or a twitter like service?

  3. Clemens Hladek – Posted Jan. 30, 2011

    I do vehemently support Eric - I am irritated...

Add a comment

View 2 comments

  1. herve – Posted Sept. 9, 2010

    Should title be "Two ways to Create User Interface"?

  2. Clemens Hladek – Posted Jan. 30, 2011

    I'd find: declarative (XML) ... programmatic (java) more explicit!

Add a comment

View 2 comments

  1. fmaker – Posted Sept. 21, 2010

    "non-programmers can understand it" hrm, I don't think so. Lots of keywords still. I think what you really mean is that it enforces a strict structure and is very expressive, meaning people unfamiliar with the platform,framework, etc. can readily determine what the intent is.

  2. Nigel Gilbert – Posted Feb. 4, 2011

    I think you mean "even people" rather than "event people".

Add a comment

View 2 comments

  1. schrickl – Posted Sept. 19, 2010

    .."but doesn't provide a good 'way' of handling user input."

  2. andyo – Posted Oct. 10, 2010

    It may be worth warning the reader that any change to the XML has to be followed by recompiling, just as if the Java code were changed. This appears to be the case, but I haven't seen it documented anywhere.

Add a comment

View 1 comment

  1. fmaker – Posted Sept. 21, 2010

    I would make the UI comparison even broader. In my experience, every UI toolkit is pretty much the same fundamentally. Just a question of what views and widgets are available and how easy it is to create your views. However, I would mention one difference is the necessity of getting a reference to your view at runtime via R.java.

Add a comment

View 1 comment

  1. fmaker – Posted Sept. 21, 2010

    Tip: Just because you can't doesn't mean you should have your whole view programmatically. It is generally best to stick to MVC patterns and let XML be your dividing line between the view (XML) and controller (Android Java) code.

Add a comment

View 5 comments

  1. fmaker – Posted Sept. 21, 2010

    Programmatic views are often useful and/or necessary when the quantity, type, etc. of a view is not know beforehand and must be created during runtime.

  2. fmaker – Posted Sept. 21, 2010

    Tip: Try to keep your view hierarchy tree broad instead of deep. This will allow the transformation from XML to java to take less memory and processing resources. The SDK tool, hierarchy viewer, is invaluable for this purpose.

  3. laurent_tonon – Posted Sept. 28, 2010

    "You would 'then' switch to programmatic (Java) approach to user interface"

  4. laurent_tonon – Posted Sept. 28, 2010

    "You would than switch to programmatic (Java) approach to user interface to define what goes on when user interacts with various widgets."

    what about: "You would then switch to programmatic (Java) approach to define what goes on when user interacts with various widgets of the user interface"

  5. John Crowley – Posted March 9, 2011

    You may have covered it elsewhere, but Android has a single UI thread and access to UI widgets from any other thread can lead to aborts or strange problems. This is a huge issue, especially for new Android developers, who can easily fall into this trap (and get really, really confused). It should be mentioned here -- at least a reference to the full discussion elsewhere.

Add a comment

View 3 comments

  1. fmaker – Posted Sept. 21, 2010

    I like the simple layout vs. views explanation.

  2. Clemens Hladek – Posted Jan. 30, 2011

    Please mention what you sas in your note directly below in your opening paragraph for "Views and Layouts".

  3. Saad Subair – Posted Oct. 14, 2011

    I believe, Java Programmers who are new to Android may skip the details of layouts at this point and go straightforward to create the Yamba project.

    Edited on October 14, 2011, 6 a.m. PDT

Add a comment

View 2 comments

  1. herve – Posted Sept. 9, 2010

    Regarding the Note above: application widgets are usually referred to as "App Widgets", not "Home App Widgets". The Android documentation says "App Widgets are miniature application views that can be embedded in other applications (such as the Home screen)" (note the "such as the Home screen). I haven't tried to add widgets to any other application so I don't know if it works but the documentation seems to imply it could be possible and therefore "Home App Widget" would not always be a suitable name.

  2. fmaker – Posted Sept. 21, 2010

    I think it's easier to say that each element can be nested to the extent resources allow.

Add a comment

View 1 comment

  1. Nigel Gilbert – Posted Feb. 4, 2011

    It might help to clarify that here "space" means physical/display/screen space (as I think it can be confused with allocating memory). What about: "A layout is responsible for figuring out the physical dimensions of each of it's children."?

    Also, "different approach" should be "different approaches".

Add a comment

View 1 comment

  1. fmaker – Posted Sept. 21, 2010

    I would like to see bullet points and a short description of each here. Or something like that. Maybe even just make this sentence into a big header or something.

Add a comment

View 3 comments

  1. schrickl – Posted Sept. 19, 2010

    ..."it allocates desired space to each child in the order they are added."

  2. fmaker – Posted Sept. 21, 2010

    You have the great opportunity to teach people that LinearLayout is NOT always the best to layout to be used and in fact is often used too much! A good rule of thumb is that if you start to nest multiple linearlayouts, you should probably be using another layout. This can have big consequences on the time to inflate the layout, cpu, memory, etc. Something like a relative layout is often a much better choice.

  3. BillS – Posted Oct. 26, 2010

    Frank makes a great point. I myself tend to use LinearLayouts a lot just because they're simpler and I haven't really had the chance to use the others. Maybe an explanation here of the pros and cons of each or why you would choose one over another would be good.

Add a comment

View 2 comments

  1. fmaker – Posted Sept. 21, 2010

    I would draw a quick analogy to HTML tables.

  2. John Crowley – Posted March 9, 2011

    Might also clarify along the lines of "... the TableRow instances themselves are positioned vertically. The widgets within each TableRow are ...."

Add a comment

View 1 comment

  1. herve – Posted Sept. 9, 2010

    "use * to stretch", not "put * to stretch".

Add a comment

View 3 comments

  1. fmaker – Posted Sept. 21, 2010

    It is used for Video overlays, for example because the video accelerator writes directly to the graphics memory and consequently the screen itself.

  2. laurent_tonon – Posted Sept. 28, 2010

    I like the analogy "like a deck of cards"

  3. John Crowley – Posted March 9, 2011

    I've always found this confusing. For example, if you set the Gravity of all children to FILL, and then call bringChildToFront(view) does that "card" now appear on top of the deck. I.e. does it work like the old StackLayout in Java? I don't know the answer, but if it does would be worth explaining ....

Add a comment

View 2 comments

  1. fmaker – Posted Sept. 21, 2010

    I disagree, why is relative layout hard to use? Pretty simple. Just specify what is relative to what? The only big deal I can see is you have to deal with the ids for each view.

  2. pablo martinez – Posted Oct. 26, 2011

    typo: it says "of you application", it should be "of your application"

Add a comment

View 1 comment

  1. Marilyn Escue – Posted Nov. 26, 2010

    Isn't the biggest reason not to use this because it might look great on your testing device and one or two similar ones, but the layout might be very poor on most the other devices out there because of their various screen sizes, etc. That's probably the implication here, but it could be made more explicit.

Add a comment

View 1 comment

  1. John Leasia – Posted May 12, 2011

    ...using RelativeLayout can minimize total number of widgets that need to be drawn thus improving the overall performance of you application.

    should be (add the, /you/your/)

    using RelativeLayout can minimize the total number of widgets that need to be drawn thus improving the overall performance of your application.

Add a comment

View 5 comments

  1. herve – Posted Sept. 9, 2010

    "So, enter 4 here" instead of "So, enter 8 here".

  2. herve – Posted Sept. 9, 2010

    Mentioning the fact that Android Market uses the minSDKVersion value to filter applications would be nice.

  3. herve – Posted Sept. 11, 2010

    The manifest file you are showing later shows 8 as the minimum SDK version so if you change the text above you also have to update the manifest file throughout the book to show 4 instead.

  4. Marilyn Escue – Posted Nov. 26, 2010

    Some of the bullet points below are messed up such that one bullet point has been split into several.

  5. Ravishankar rravishankar – Posted Dec. 9, 2010

    It would be good if we can add an example of some difference between API levels.

Add a comment

View 6 comments

  1. fmaker – Posted Sept. 21, 2010

    It would be nice to separate the views in the code snippet, add simple comments and make them bold. Otherwise just looks like a hunk of text.

  2. BillS – Posted Oct. 26, 2010

    With the layout discussion, is it worth mentioning some best practices for making your app look good in both portrait and landscape mode?

  3. erik runia – Posted Jan. 7, 2011

    would be nice to know here how this status1.xml was generated.. did you hand type in all this xml? did you use a wysiwig editor? I'm looking at this from the perspective of a aps.net c# developer and I really don't know if I'd have to type all this in, or is there a design mode where i can just drag this onto the container.. etc etc.

  4. Brian Maschhoff – Posted Feb. 10, 2011

    The heading on the XML file should read:

    res/layout/status.xml

  5. Bartłomiej Piech – Posted April 10, 2011

    You are using strings that you didn't define.

  6. Branden Andersen – Posted Jan. 13, 2012

    I noticed the text in editText is gray. On linux using eclipse Indigo, my default text is black. Did you define the color to be gray? If you did, let beginner users know that you did and how you did it (did you use xml or the graphical tool?). I couldn't find a graphical tool to adjust the text color and used xml. Anyways, great job on the book.

Add a comment

View 6 comments

  1. herve – Posted Sept. 9, 2010

    Add something about layout_weight. It is used in res/layout/main.xml above so that EditText leaves some space for the Button widget but I think it needs some explanation since it won't be obvious to most readers.

  2. andyo – Posted Oct. 7, 2010

    It would be useful to include a figure to show the difference between the gravity and the layout_gravity properties. People who have worked with CSS know the difference between CSS's margin and padding, which seems to be comparable and may be worth mentioning as an analogy.

  3. andyo – Posted Oct. 7, 2010

    Rather than saying a hard-coded string works in only one locale, it would be more precise to say it cannot be adapted to different locales and languages.

  4. Ravishankar rravishankar – Posted Dec. 9, 2010

    There's no "layout_gravity" attribute anywhere in status1.xml above so the Important Widget properties can get confusing. Also would be better to explain what 10dp, 30sp mean in this context.

  5. Bradley Todd – Posted Feb. 25, 2011

    In the text below, suggest replacing "than" with "then":

    ...Now, it is not a good practice to just enter the text because than your layout will only work in one locale/language...

  6. stevemeuse – Posted April 5, 2011

    The distinction between layout_gravity and gravity isn't clear to me. Layout_weight isn't clear, either.

    Also, I've followed the example so far, but we haven't yet worked onvalues/strings.xml, so my screen looks different than Figure 6.3.

Add a comment

View 6 comments

  1. fmaker – Posted Sept. 21, 2010

    Others, such as myself, prefer underscores to camelcase. But regardless, they strings may change overtime, but this is very useful when initially placing the strings.

  2. BillS – Posted Oct. 26, 2010

    Why are the steps below out of order?

  3. Ravishankar rravishankar – Posted Dec. 9, 2010

    It may be worth adding a small note here on the convention for localization - the default directory, the directories looked up for say Japanese or Russian.

  4. Jean-Christophe Moinet – Posted Dec. 18, 2010

    Typo :

    Please enter your 140-characeter tweet

    should be

    Please enter your 140-character tweet

  5. erik runia – Posted Jan. 7, 2011

    characeter typo.. should be character

  6. Adil Muhammad – Posted March 3, 2011

    I think figure 6.3 should come after this?

Add a comment

View 4 comments

  1. schrickl – Posted Sept. 19, 2010

    he/she

  2. fmaker – Posted Sept. 21, 2010

    It might be nice to let them run it, see that is fails and then correct the mistake. This can be nice for students so that they develop confidence in being able to correct mistakes.

  3. laurent_tonon – Posted Sept. 29, 2010

    I tried the code you provide and Eclipse says that the constructor Twitter(String, String) is deprecated.

  4. Robert Widdick – Posted Aug. 8, 2011

    @laurent_tonon - use http://marakana.com/static/courseware/android/jtwitter-yamba.jar

Add a comment

View 4 comments

  1. fmaker – Posted Sept. 21, 2010

    It is even available at the C/C++ level! They all go to the same log.

  2. fmaker – Posted Sept. 21, 2010

    Ok you HAVE to mention here the frequently possibility of getting android.R instead of your .R file. This is a frequent problem I see new Android-ers run into.

  3. Nigel Gilbert – Posted Feb. 7, 2011

    In the tip below, my Eclipse (3.5.2) has Shift+Ctrl+O, not Ctrl+O to Organize Imports.

  4. Adil Muhammad – Posted March 4, 2011

    What is difference between Log and standard output (System.out)? Is there any additional benefit of using log?

Add a comment

View 2 comments

  1. fmaker – Posted Sept. 21, 2010

    These levels correspond to different colors in the Eclipse plugin.

  2. mystixa – Posted Feb. 3, 2012

    in case your wondered. should = "in case you wondered."

Add a comment

View 2 comments

  1. Stuart Jackson – Posted Nov. 22, 2010

    I found this a bit confusing. What little green plus button. Then I read the note below about DDMS and figured it out. Perhaps you could discuss DDMS first?

  2. Chuck Kelly – Posted March 10, 2011

    Completely confusing.No directions or mentions of the purpose of all this, why its placed here in the reading or any directions as to what to do with this.

Add a comment

View 2 comments

  1. schrickl – Posted Sept. 19, 2010

    Regarding the tip below, the logcat within Eclipse does not show the latest entries at the top of the window so it becomes quite annoying to have to always scroll to the bottom of the screen. I opened an issue regarding this so perhaps it will be fixed in the next release. In the meantime, I prefer the command line option.

  2. fmaker – Posted Sept. 21, 2010

    Agreed, it is really nice to have logcat in a terminal running on a second screen as well.

Add a comment

View 1 comment

  1. laurent_tonon – Posted Sept. 28, 2010

    "from resources, for each element is has to create a new Java object and assign its properties to it."

    Maybe it would be better this way:

    "from resources. For each element, it has to create a new Java object and assign its properties to it."

Add a comment

View 1 comment

  1. herve – Posted Sept. 9, 2010

    A section talking about 'advanced' layout tricks would be nice, for example including: ViewStub null window background window background to simulate faster loading time for application

Add a comment

View 2 comments

  1. herve – Posted Sept. 9, 2010

    It would be worth talking about layoutopt as well, another tool shipping with the Android SDK.

  2. fmaker – Posted Sept. 21, 2010

    Yes I agree with Herve layopt is invaluable for telling you what you did wrong ;-)

Add a comment

View 5 comments

  1. schrickl – Posted Sept. 19, 2010

    Cannot run the application at this point because you haven't mentioned downloading the jtwitter package from Winterwell. (Unless that happens to be in Chapter 5)

  2. laurent_tonon – Posted Sept. 29, 2010

    Use OAuth because since August 31th it's mandatory

  3. Marilyn Escue – Posted Nov. 27, 2010

    Why not say it will look like Figure 6.15 rather than going back to 6.9? If it's because the reader might not have the pretty background, then at least say 6.10 because the reader will have made the number of characters left be displayed in green.

  4. Marilyn Escue – Posted Nov. 27, 2010

    Why not say it will look like figure 6.15 rather than go all the way back to 6.9? If it's because the reader may not have the pretty background, at least the user will have made the number of characters left be displayed in green... so, the referenced figure would at least be 6.10.

  5. sigmaPm – Posted Dec. 26, 2010

    For those who can't run this example because of OAuth change, Marko has posted a very useful comment here.

    http://marakana.com/forums/android/examples/67.html#p373

    So using identi.ca with proper credentials does the magic. twitter.setAPIRootUrl("http://identi.ca/api");

Add a comment

View 1 comment

  1. Adil Muhammad – Posted March 4, 2011

    When I run the application, it crash on me instead of showing the showing the toast message, but it is updating the status.

Add a comment

View 1 comment

  1. John Leasia – Posted May 12, 2011

    There are couple of main layouts... should be There are a couple of main layouts...

Add a comment

View 1 comment

  1. pablo martinez – Posted Oct. 26, 2011

    you said: "Android 2.3", but the image shows Android 2.2

Add a comment

View 1 comment

  1. Bartłomiej Piech – Posted April 11, 2011

    In "Starting Yamba Project" we were suposed to use com.marakana.yamba as package name.

Add a comment

View 1 comment

  1. Marilyn Escue – Posted Nov. 27, 2010

    "We as developers do not control what state the activity is 'in'..."

Add a comment

View 1 comment

  1. John Leasia – Posted May 12, 2011

    Notice that onCreate() take a Bundle as should be Notice that onCreate() takes a Bundle as

    last sentence ends oddly I do think there is a need for us.

    maybe...be using the Bundle in our Yamba example as there's no real need for us to do so.

Add a comment

View 1 comment

  1. erik runia – Posted Jan. 7, 2011

    "Java object in out memory space" should read "in our"

Add a comment

View 7 comments

  1. Marilyn Escue – Posted Nov. 27, 2010

    The 6 bullets points below the code should probably be in order because that's how most readers will expect them.

  2. Vivek Krishna – Posted Dec. 4, 2010

    I guess this code no longer works, twitter has changed to OAuth.

  3. Vivek Krishna – Posted Dec. 4, 2010

    also, I second Marilyn's comment.

  4. erik runia – Posted Jan. 7, 2011

    didn't you name this status.java earlier in the book? if not, my apologies, if so you should probably keep things consistent as its named StatusActivity1.java below

  5. Michael Gonzalez – Posted Sept. 22, 2011

    Note there is a type... the public class should be statusActivity NOT statusActivity1

    Use this as the first line after the import statements..

    public class StatusActivity extends Activity implements OnClickListener {

  6. ryszard chojnacki – Posted Nov. 17, 2011

    I believe Example 6.3 below, gets run-time exception in android (platform 4, api 14) related to new policy AndroidBlockGuardPolicy. Related to calling a blocking network api from a UI thread (considered bad).

    Stack overflow has an explanation and ugly dev hack to bypass this for classroom development. See: http://stackoverflow.com/questions/4821845/honycomb-and-defaulthttpclient

    Code that suppresses policy, and worked for me: ThreadPolicy tp = ThreadPolicy.LAX; StrictMode.setThreadPolicy(tp);

  7. Hans-Jacob Enemark – Posted Nov. 30, 2011

    I second Viveks comment about the jtwitter API. The use of the constructor in (4) is deprecated and makes the code no longer work.

Add a comment

View 7 comments

  1. Bill Schrickel – Posted Jan. 16, 2011

    Last sentence needs some modification. Maybe, "moving to another file while the current one is broken just makes it even more difficult to find errors."

  2. Roland Turcan – Posted Jan. 23, 2011

    automagically >>> automatically

  3. Brian Maschhoff – Posted Feb. 10, 2011

    Mention having Project --> Build Automatically checked as well as selecting Project -- Clean to help get rid of phantom build issues

  4. Adil Muhammad – Posted March 4, 2011

    When we started the project, package name was "com.marakana.yamba" and now it has become "com.marakana.yamba1", how?

  5. stevemeuse – Posted April 5, 2011

    Similarly, the public class StatusActivity is now StatusActivity1, which generates a compilation error.

    Also, I get the error: "The import winterwell cannot be resolved."

  6. sonicpp – Posted Sept. 29, 2011

    I like, and use often, the creative word automagically. Leave it in!!! People will know it's a wink and nod.

  7. releaser – Posted Feb. 7, 2012

    Hi guys.

    I'm following this project tutorial from scratch and on first run i came to a problem.

    When deffining twitter = new Twitter it gets deprecated

    I can't implement OnClickListener on StatusActivity like showed in code and my p r i v a t e s t a t i c f i n a l S t r i n g T A G = " S t a t u s A c t i v i t y " ; shows the red cross.

    Also the editText and updateButton does not show when trying to call from R.id. with findViewById.

    Don't know what's the problem.

    Even tried to copy/paste the code for the 3 files but the result is the same.

    Please help understand what's wrong.

    Thanks

Add a comment

View 1 comment

  1. Gideon Bar – Posted Nov. 20, 2011

    It is not clear which link the jar should come from. It is not clear which link on the page is the one wanted. (Thanks his is great learning)

Add a comment

View 4 comments

  1. Jean-Christophe Moinet – Posted Dec. 18, 2010

    jtwitter needs some other jar to work (http://code.google.com/p/oauth-signpost/downloads/detail?name=signpost-core-1.2.1.1.jar)

  2. Bradley Todd – Posted Feb. 25, 2011

    This does not appear to be valid any more. Although you can download the jtwitter.jar file from Winterwell Associates, the constructor in your example is deprecated. This seems to be because of a Twitter requirement whereby you can no longer just supply a username and password.

  3. stevemeuse – Posted April 5, 2011

    For folks like me who are otherwise stuck without the proper jtwitter.jar, this is from the errata at http://oreilly.com/catalog/errataunconfirmed.csp?isbn=0636920010883


    The link to the jtwitter.jar file on this page contains a new version of the file. If you download and use that jar file, you will get an error that the reference to "twitter" (in your statusActivity class) is delimited. The project won't work. You have to use the jtwitter.jar file in the examples download located at this link:

    < http://examples.oreilly.com/0636920010883/ >


  4. Richard Clements – Posted Dec. 12, 2011

    jtwitter lib from the download link the Code still isn't working, still crashes when it calls the twitter.setStatus(editText.getText().toString());

Add a comment

View 1 comment

  1. Adil Muhammad – Posted March 4, 2011

    We have to click on "Add JARs" or "Add External JARs"?

Add a comment

View 1 comment

  1. Marilyn Escue – Posted Nov. 27, 2010

    Move the title of this section "Logcat from command line" to just above this paragraph rather than above the DDMS example.

Add a comment

View 2 comments

  1. Stuart Jackson – Posted Nov. 22, 2010

    Don't you mean threading is a process of executing software instructions in a parallel fashion?

  2. sonicpp – Posted Sept. 29, 2011

    Maybe he meant... A single threaded process will execute its instructions in order.

Add a comment

View 1 comment

  1. Clemens Hladek – Posted Jan. 31, 2011

    Better skip the "(as in" part above - you imply that HERE it means s.th. different!

Add a comment

View 2 comments

  1. Magnus Flansbjer – Posted March 13, 2011

    The reference to updateStatus() is strange since, when reading this, no example code has called that method. In Example 6.3, setStatus() was used.

  2. mystixa – Posted Feb. 3, 2012

    update the our status. should = "update our status."

Add a comment

View 1 comment

  1. Nigel Gilbert – Posted Feb. 7, 2011

    I think that Figure 6.8 looks like it offers no better performance/responsiveness than Figure 6.6 since no code appears to run simultaneously.

    Perhaps it would be better to move the second "UI Tasks" block leftwards a bit to overlap the "Network Tasks" block's time period (It doesn't have to be completely next to the previous "UI Tasks" block to highlight the asynchronous nature of the events).

    I'm assuming that the purpose of this diagram is to show the apparent parallelization of the operations and doesn't need to show that in fact on a single processor the OS could be rapidly swapping between the "UI Thread" and "Another Thread" (as mentioned in the previous paragraph).

Add a comment

View 9 comments

  1. Anna Teittinen – Posted Jan. 3, 2011

    The call to:

    Twitter.Status status = twitter.updateStatus(statuses[0]);

    generated the following error when running:

    Sorry! The application Yamba 1 (process com.marakana.yamba) has stopped unexpectedly. Please try again. [Force close]

    Is there a solution?

  2. Chuck Kelly – Posted March 10, 2011

    No mentions of if were replacing the original status activity code or creating another java file separate from it.

  3. Chuck Kelly – Posted March 10, 2011

    also encountering errors involving

    public class StatusActivity2 extends Activity implements OnClickListener {

    there is some confusion with the Description Resource Path Location Type The public type StatusActivity2 must be defined in its own file StatusActivity.java /Yamba/src/com/yamba/winning line 15 Java Problem reoccurring error

    can easily be solved by removing the "2" but im unsure why the guide would continue to add numbers without explaining why there needed.

  4. Dinesh Bajaj – Posted April 2, 2011

    On running the code, I get the following error:

    04-02 14:37:20.295: ERROR/AndroidRuntime(370): Uncaught handler: thread AsyncTask #1 exiting due to uncaught exception

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): java.lang.RuntimeException: An error occured while executing doInBackground()

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at android.os.AsyncTask$3.done(AsyncTask.java:200)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.FutureTask.setException(FutureTask.java:124)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.FutureTask.run(FutureTask.java:137)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1068)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:561)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.lang.Thread.run(Thread.java:1096)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): Caused by: java.lang.IllegalArgumentException

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.Date.parse(Date.java:447)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.Date.(Date.java:157)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at winterwell.jtwitter.Twitter$Status.(Twitter.java:614)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at winterwell.jtwitter.Twitter.updateStatus(Twitter.java:3073)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at winterwell.jtwitter.Twitter.updateStatus(Twitter.java:3003)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at com.marakana.yamba.StatusActivity$PostToTwitter.doInBackground(StatusActivity.java:44)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at com.marakana.yamba.StatusActivity$PostToTwitter.doInBackground(StatusActivity.java:1)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at android.os.AsyncTask$2.call(AsyncTask.java:185)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305)

    04-02 14:37:20.315: ERROR/AndroidRuntime(370): ... 4 more

    What is the solution to the above problem? Please help!

  5. Dinesh Bajaj – Posted April 3, 2011

    Got the solution to the above reported problem. See the URL: http://answers.oreilly.com/topic/2594-the-code-in-the-book-learning-android-does-not-run/pagepid4952st0&#entry4952

  6. Saurav Malik – Posted April 4, 2011

    When i am using the below code and trying to run it so it is giving the Toast message as "Failed to post". Means it is not updating the status on Twitter. I am new for the android programming so i wanna know that should i go ahead by neglecting this error for now or should i resolve it here. Please suggest me the appropriate suggestions.

    When i checked the Logcat so it was showing this in red color "winterwell.jtwitter.TwitterExeception: java.io.IOException: Received authentication challenge is null".

    Can anyone tell me what is this?

    Many thanks in advance

  7. Saurav Malik – Posted April 4, 2011

    Hello Anna Teittinen,

    I think i have the solution for your query. After using below mentioned code, please use your original credentials of Twitter (Username and Password), dont use the credentials mentined below, like: "student" and "password".

  8. Saurav Malik – Posted April 9, 2011

    Hello Friends..

    Is anybody have the updated source code which is mentioned below because this is not an updated one source code. Or is anybody have the running code of this site?

    Please help!!

    Thanks in advance..

  9. Christopher McGreal – Posted Jan. 24, 2012

    To take advantage of this class, we need to >>>crate<<< a new subclass of AsyncTask and implement doInBackground(), onProgressUpdate(), and onPostExecute() methods.

    Word should be 'create'

Add a comment

View 2 comments

  1. Marilyn Escue – Posted Nov. 27, 2010

    Again, confusing that the bullet points aren't in order.

  2. Clemens Hladek – Posted Jan. 31, 2011

    Supporting Marilyn: not having them in order MIGHT work in a written book - ONLY if on the same page! - but is very annoying onscreen

Add a comment

View 1 comment

  1. Marilyn Escue – Posted Nov. 27, 2010

    Image should be Imagine.

Add a comment

View 1 comment

  1. Laurent BERNABE – Posted Dec. 17, 2010

    I think "Android providers" should be "Android provides" instead.+

Add a comment

View 1 comment

  1. ajendros – Posted Feb. 27, 2012

    In the example 6.6 it's better to use default text values from the resource @string instead of defining it in the layout file.

    Example for res/layout/status2.xml

    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="right" android:id="@+id/textCount" android:text="@string/textCounter" android:layout_marginRight="10dp" />

    Edited on February 27, 2012, 11:39 p.m. PST

Add a comment

View 1 comment

  1. stevemeuse – Posted May 12, 2011

    GIF is also lossless.

Add a comment

View 1 comment

  1. Clemens Hladek – Posted Jan. 31, 2011

    "... use this resource from Java But we’re not."

    Why don't you put the resource's reference name in brackets?

    Some readers might like to play around here (e.g. ME)

Add a comment

View 1 comment

  1. stevemeuse – Posted May 12, 2011

    it's -> its background

Add a comment

View 1 comment

  1. Anna Teittinen – Posted Dec. 30, 2010

    This section may not list all the steps in seeing the 'Drawable→background' property. Having the StatusActivity.java file opened, followed by clicking the 'Window->Show View->Outline', the Outline view only shows lists the import declarations and class members and methods of the StatusActivity class. When I open the status.xml file, nothing shows in the Outline view. Thus, I am unable to bring up the Reference Chooser dialog.

Add a comment

View 2 comments

  1. Clemens Hladek – Posted Jan. 31, 2011

    I'd prefer:

    The other approach is to go straight ...

    I - as a beginner - will otherwise think there may be seceral others!

  2. Clemens Hladek – Posted Jan. 31, 2011

    Sorry, typo: meant to be "several"

Add a comment

View 1 comment

  1. Marilyn Escue – Posted Nov. 27, 2010

    Image at the beginning of the paragraph should be Imagine.

Add a comment

View 2 comments

  1. Anna Teittinen – Posted Dec. 31, 2010

    The link to that LOC website shows a "Page Not Found" message.

  2. Clemens Hladek – Posted Jan. 31, 2011

    Delete "[2" at the end...

Add a comment

View 1 comment

  1. Anna Teittinen – Posted Dec. 31, 2010

    May want to include a reference to how to create the Android XML File dialog in Eclipse.

    As someone new to Android programming following these steps, I have no idea on how to create this dialog.

Add a comment

View 4 comments

  1. Jean-Christophe Moinet – Posted Dec. 18, 2010

    The sentence "So, enter 8 here " should be "So, enter 4 here"

  2. Nigel Gilbert – Posted Feb. 21, 2011

    I believe that later we use features that were only introduced in API level 5, namely:

    • Service.onStartCommand(Intent, int, int)
    • Service.START_STICKY

    So we cannot choose API level 4 here.

  3. Nigel Gilbert – Posted Feb. 21, 2011

    Further to my previous comment about API levels, I think that the following is true (though I would welcome any corrections):

    1. Eclipse will build our software against the version of the Android API specified by the "Project Build Target" field in the Project Properties. Building will fail if the API used by the application is not supported by this build target. Eclipse also uses this field to determine which emulator/device is suitable to run the software and will not even offer to start a new virtual device that is of a lower API version.

    2. Eclipse does not consider the Application Manifest's minSdkVersion field when building the application (apart from showing a warning if that and the build target version differ). The Marketplace (and the device itself) will not allow us to install applications which have a minSdkVersion higher than the device supports. This allows us to write applications which are backwardly compatible with older API versions, but can use newer API features on devices which support them. With this flexibility comes a risk; we can deploy applications onto the marketplace which do not function correctly on some devices, damaging your users' opinion of your application. As ever, the solution appears to be good testing.

    It isn't obvious (or wasn't to me) how to test our application against older API versions which our application manifest claims to support (given the restriction from item 1). However, it appears that manually starting an emulator for a particular API version is the solution. To do this, use the "Android SDK and AVD Manager" and ensure you have the appropriate SDK Platform installed using Available Packages -> Android Repository -> SDK Platform Android 1.6, API 4 (for instance). Then, create a virtual device for that API version and "Start" the device. This should bring up the emulator. When Eclipse is told to run your application, it will show the "Android Device Chooser" dialog from which you can choose the correct emulator. It will be shown with a warning symbol in the Target column.

    This appears to be touched upon in the "Android Versions" section of Chapter 1 already but would seem a bit too heavy to be dealt with at this level of detail so early in the text, maybe there is somewhere else it would be better placed. As such, perhaps it would be better to just pick the same minSdkVersion as the build target for the purposes of the example application and move the discussion about being able to reach a greater audience and the risks this entails elsewhere.

    Note that these assertions are (only) based upon my experiments with Eclipse 3.5.2 and a bit of Googling, it appears to be true, but there might be something more complex going on which I've not noticed.

  4. Adil Muhammad – Posted March 3, 2011

    Please update the Figure 6.2 as you are using Android 2.3 but Figure 6.2 is suggesting that you are using Android 2.2.

Add a comment

View 1 comment

  1. Vijayalaxmi Arakeri – Posted Oct. 21, 2011

    itwould be helpful if it contains some sample code with the explanation.

Add a comment

View 1 comment

  1. Ravi Shastri – Posted June 13, 2011

    I'd think that a comparison of layout in a table (layout name, typical usage scenario. pros, cons, sample screenshot etc.. ) would work best to explain the layouts.

Add a comment