Android Programming

Bill Phillips, Brian Hardy

Mentioned 6

An easy-to-follow tour of the Android mobile development platform helps readers create their own apps, giving them a working knowledge of the key concepts and APIs needed and helpful techniques for using the Android development tools to their fullest. Original.

More on Amazon.com

Mentioned in questions and answers.

I am currently looking at using a loader manager to populate my expandablelistview in a drawerlayout. I cannot find anywhere in the documentation if the callback function onLoadFinished() is running on the UI thread or on a background thread. Is it on a background thread?

http://www.amazon.com/Android-Programming-Ranch-Guide-Guides/dp/0321804333, pg. 566.

"The onFinishedLoad() method will be called on the main thread once the data has been loaded in the background."

I was referring to following article to further understand the life cycle of the activity and found phrase "activity record object"

Quoting article :

When your activity is stashed, an Activity object does not exist, but the activity record object lives on in the OS.The OS can reanimate the activity using the activity record when it needs to.


When onSaveInstanceState(...) is called, the data is saved to the Bundle object.That Bundle object is then stuffed into your activity's activity record by the OS

Could any one define exactly what is meant by "activity record object", and does OS save considerable amount of memory by just killing an activity ?

I wrote the passage you quote here (it's from the book Brian Hardy and I wrote, Android Programming: The Big Nerd Ranch Guide). Let me see if I can answer your questions.

The "activity record object" (I usually say "activity record") is not visible to you as an application developer. Instead, it lives in the Android OS, where it is used to keep track of your activity. That object is where your saved instance state is stored; it's where the intent that initially started your activity lives, where the activity results you receive are stored before they are delivered. More importantly, if the activity record is alive, it may be used to reconstitute an Activity instance in your application.

The activity record object is much cheaper to keep alive than an instance of the Activity class. An Activity instance has a whole view hierarchy, which can easily take up a few megabytes of memory by itself. On top of that, Activity instances require your app's process to exist. So if there are no Activity instances left, Android can get rid of your entire process, too.

I have defined a button on Android where upon being clicked, I need to read some data back. The steps in doing so are shown below:

1- OnStart(), I make a call to a thread as follows:

mConnectedThread = new ConnectedThread(mmSocket);
mConnectedThread.start();

2- The "run" public function of the above thread makes some calculation and then sends the result back to the message handler as shown here:

msg_handler.obtainMessage(READ_BUF_HAS_UP_STATUS, num_of_read_bytes, -1).sendToTarget();

3- The message handler has been defined as follows in onCreate:

       msg_handler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                // if received buffer has any data, then process it here:

                case READ_BUF_HAS_UP_STATUS:

                    up_idle_status_byte = readBuf[0];
                    n_bytes = msg.arg1;
                    Log.d(TAG, "....We have received the up status! And it is: "+up_idle_status_byte);

                    break;
            }
        }

        ;
    };

4- The "readStatus" button which reads the status from the above thread is defined as follows in "onCreate". As shown below, a call to mConnectedThread.readStatusReg() would cause the status to be read back from the thread's "run" procedure which subsequently is handed over to the above message handler:

       readStatus.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v){
            mConnectedThread.readStatusReg();
            while (!msg_handler.hasMessages(READ_BUF_HAS_UP_STATUS)) {
                    try {
                        Log.d(TAG, "There is NO message from msg_handler yet");
                        TimeUnit.MILLISECONDS.sleep(80);
                    } catch (InterruptedException e) {
                        String msg = "clicked readStatus and an exception occurred when sleeping for some time" + e.getMessage();
                        errorExit("Fatal Error", msg);
                    }
                }
             }
             if (up_idle_status_byte == (byte) 0x01){
                    //do something
             }
             else{
                    //do something else
             }
    });

The problem is that "up_idle_status_byte" value which is captured by the message handler, is not seen by this button event [it always ends up in the "else" statement above]. If the message handler is acting in parallel with button activity -- which I suspected so -- I would have imagined that the button handler should be able to eventually see the correct status value. But that is not the case and message handler seems to be operating sequentially. Meaning that regardless of how much I pause in the button handler loop, I never see the path through "if (up_idle_status_byte == (byte) 0x01)" being executed. And as soon as the button activity exits, the sequential manner of message handler shows the value of up_idle_status_byte to be correctly set to one!! [note that up_idle_status_byte is defined as a global variable]

So why can't I see any parameters created in handleMessage simultaneously available in the button click [sorry if this is such a novice question, but again I am not claiming otherwise!!...]?

Thanks a lot for your input and advice.

Here's the problem: there is no "button activity" that runs parallel to the message handler. The button's onClick() code is run inside of a message on the main handler, just like your code to read the status.

What you are trying to do here—make a network request and receive the result of that request inside the same button listener—is not possible. Each unit of work on the main thread must be small, so you will need to have the button make the request, and then have a separate part do the remaining work when the request finishes (likely inside the message handler).

If you are referring to our book (obligatory plug: Big Nerd Ranch Guide to Android Programming), I strongly recommend building the example exercises for chapters 26 and 27 according to the instructions and understanding how they work. There's a world of difference between doing that and trying to read and cherry pick for a small piece of understanding.

I have read this manual and also i'm reading this book. developer.android.com says i should implement communication through activity. But the book says i can use setTargetFragment() and call onActivityResult() by hand for target fragment from other fragment. Each approach works but which is right? What is setTargetFrament() for, if i can't use it for communication with other fragment?

I have this layout file from Chapter 13 of Android Programming: The Big Nerd Ranch Guide:

<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:layout_width="match_parent"
         android:layout_height="match_parent">

    <ImageView
        android:src="@drawable/armstrong_on_moon"
        android:contentDescription="@string/hellomoon_description"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        android:layout_weight="1"/>

    <TableRow
        android:gravity="center|bottom"
        android:layout_weight="0">

        <Button
            android:id="@+id/hellomoon_playButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hellomoon_play"/>

        <Button
            android:id="@+id/hellomoon_stopButton"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/hellomoon_stop"/>

    </TableRow>

</TableLayout>

And it results in a layout that looks like this. What I do not understand is how the TableRow shows up in the layout at all since its layout_weight is 0 and the ImageView's layout_weight is 1. My understanding is that the way layout_weight works is it will first respect the layout_width and layout_height of each element, and then divide up the remaning space between the elements based on layout_weight. But since the ImageView has match_parent for both its layout_width and layout_height, shouldn't it take up the whole screen and then leave nothing left to divide with the TableRow? I believe that the TableRow also has match_parent for both its layout_width and layout_height attributes since it inherited them from TableLayout, but since it came second I thought the ImageView would dominate the screen. Also, even if the the ImageView shouldn't take up the whole screen, aren't the layout_weights saying that the ImageView should get 100% of the remaining space and the TableRow should get 0%? Additionally, when I increase the layout_weight of the TableRow, the TableRow just gets pushed further and further off the screen as it increases more-- but I thought that this should increase the space the TableRow takes up on the screen. Can anyone explain what I'm misunderstanding here.

In case it helps, my understanding for layout_weight comes from this example in the book:

**How android:layout_weight works**
...

LinearLayout makes two passes to set the width of a view. In the first pass, LinearLayout looks at layout_width (or layout_height, for vertical orientation). The value for layout_width for both the Button and CheckBox is now wrap_content, so each view will get only enough space to draw itself (Figure 8.12).

...

In the next pass, LinearLayout allocates any extra space based on the values for layout_weight.

I can't seem to find anything on Java/Android that's current (uses IntelliJ 13 etc). Everything seems to be either very old (2011-2012), and either the UI has changed, or they don't use the UI Designer etc

I'm not a total noob to programming, I have somewhat decent experience in C# & Windows Forms, and would love something that can throw me into Java for Android that's UP TO DATE.

Thanks.

If you have decent experience in C#/WinForms, you just need a good Android book, not IntelliJ/UI Designer tutorials… I recommend the excellent BigNerdRanch book. They make probably the best iOS books and the Android offers excellent patterns. With your experience, adapting to IntelliJ should be a breeze, in part because the IDE doesn't force you to do anything. In fact, if you're starting, just use Android Studio (is IntelliJ anyway).

The UP-TO-DATE part consists in always using Fragments, understanding the SDK pieces where you have to consider older devices (if that's your scope), making good use of different layouts for different resolutions, etc.

There's no such thing as Visual Studio Designer. (There is, but it doesn't work the same way). I recommend you read the official android documentation about UI with utmost care since it's the core of Android UI. For the most part, you will tweak your UI from the "XML" instead of the UI designer, which you can use to "see how it looks" or if "makes sense" but trust me, as intimidating as it sounds, it's actually not rocket science and you get used to it relatively fast.