android.view.WindowManager$BadTokenException & Android – Displaying Dialogs From Background Threads

Having threads to do some heavy lifting and long processing in the background is pretty standard stuff. Very often you would want to notify or prompt the user after the background task has finished by displaying a Dialog.

The displaying of the Dialog has to happen on the UI thread, so you would do that either in the Handler object for the thread or in the onPostExecute method of an AsyncTask (which is a thread as well, just an easier way of implementing it). That is a textbook way of doing this and you would think that pretty much nothing wrong could go with this.

Surprisingly I found out that something CAN actually go wrong with this. After Google updated the Android Market and started giving crash reports to the developers I received the following exception:

android.view.WindowManager$BadTokenException: Unable to add window — token android.os.BinderProxy@447a6748 is not valid; is your activity running?
at android.view.ViewRoot.setView(ViewRoot.java:468)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:177)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:91)
at android.view.Window$LocalWindowManager.addView(Window.java:424)
at android.app.Dialog.show(Dialog.java:239)
at android.app.Activity.showDialog(Activity.java:2488)

at android.os.Handler.dispatchMessage(Handler.java:99)


I only got a couple of these exceptions from thousands of installs, so I knew that was not anything that happens regularly or that it was easy to replicate.

Looking at the stack trace above it gives us a pretty good idea why it failed. It started in the Handler object, which naturally was called by a background thread after it finished its processing. The Handler instance tried to show a Dialog and before it could show it, it tried to set the View for it and then it failed with:

android.view.WindowManager$BadTokenException: Unable to add window — token android.os.BinderProxy@447a6748 is not valid; is your activity running?

The 447a6748 number is just a memory address of an object that no longer exists.

Note- do not get hung up on the exact number. It would be different with every execution.

Now we know why the application crashed, the only thing left is to figure out what caused it?

We know that background threads execute independently of the main UI thread. That means that the user could be interacting with the application during the time that the thread is doing its work under the covers. Well, what happens if the user hits the “Back” button on the device while the background thread is running and what happens to the Dialog that this thread is supposed to show? Well, if the timing is right the application will most likely crash with the above described error.

In other words what happens is that the Activity will be going through its destruction when the background thread finishes its work and tries to show a Dialog.

In this case it is almost certain that this should have been handled by the Virtual Machine. It should have recognized the fact that the Activity is in the process of finishing and not even attempted to show the Dialog. This is an oversight of the Google developers and it will probably be fixed some time in the future, but in the meantime the burden is on us to take care of this.

The fix to this is pretty simple. Just test if the Activity is going through its finishing phase before displaying the Dialog:

private Handler myHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case DISPLAY_DLG:
if (!isFinishing()) {
showDialog(MY_DIALOG);
}
break;
}
}
};

Spy Around with Android Mobile Spy

I love trying new gizmos and gadgets. The other day I tried out android mobile spy. It’s really incredible, I really felt like a great detective, indeed I instantly became a James Bond!

Though I knew nobody will ever misuse my phone, and I don’t really need to spy on others, but I still planned trying out android mobile spy and to be very frank I simply fell in love with the thing.

Android mobile spy traces every little activity taking place in your android phone. The phone calls made, the phone calls received, the text messages sent, the text messages received, etc. And interestingly, all the information that it traces, it also includes the time when the activities were actually performed. So if somebody calls at say 1:30 pm from your phone, this wonderful spying device will tell you that a particular call was made at 1:30 pm to a certain person (whose phone number will be included), and how long the conversation went on. All this information seems useful and simply great if you intentionally spy on somebody (although I was just fiddling around with the software!)

The wonders performed by this device do not end over here. It moves on and on, and I too kept playing around with all the wonders that the software allowed me to perform. It even tell you the geo location with the help of GPS, so in case you forget your phone in your office, and feel totally morose thinking that it has got lost forever, or it has perhaps been stolen, even then try checking out the case with your phone using the tool at least once, now if the product has not been stolen and it somehow remained in the office, you will surely come to know about it.

This is how the android mobile spy works. It spies simply the best. It takes really good care of all the activities happening around it.

Öredev 2010 - Some Thoughts

Öredev 2010 is over and it is time for me write some words about the conference. What I like about the conference is that has an interesting mix of tracks; Java, .NET, Agile, Web Development etc. It is always nice to broaden your views. New this year was the Xtra(ck). The Xtra(ck) contained sessions that had nothing to with software development, or at least very far from it. For example there was a session called "Understand Hypnosis". These session was definitely a way to broaden your mind. I liked the "Photographic Composition and Creativity" and the photo walk both with Amy Archer. Thanks for the tips during the photo walk!

Also new for this year was the Öredev puzzle application. The application was designed around the concept of being social. Each participant got a puzzle code within the application. By sharing your code you got a piece of the puzzle. As a bonus you got the contact information for the person whose code you entered. Each person to finish the puzzle got an Öredev t-shirt and was participating to win some great prizes. The application was available for Blackberry, Android, Windows Phone 7 and iPhone. The application also contained the schedule and speaker bios. A real nice application. Next year I hope to see an improved version. For example, integrating your own schedule would be great.

And here are some photos from the conference. Enjoy!

Öredev 2010 - Get Real


Speaker Dinner at Malmö City Hall


Developers Competing

Hard to Choose the Righr Track?

Even Doll showing of Some Nice Xcode Tricks

Coffe Lounge

Jack Nutting about Making Money in Appstore

John Seddon



Marcus Zarra on Core Graphics

The Audience

Library by Night

And that is the wrap. See you next year!

Host File - Windows

The hosts file is a computer file used in an operating system to map hostnames to IP addresses. The hosts file is a plain-text file and is traditionally named hosts.

The hosts file is one of several system facilities to assist in addressing network nodes in a computer network. It is a common part in a operating system's Internet Protocol (IP) implementation, and serves the function of translating human-friendly hostnames into numeric protocol addresses, called IP addresses, that identify and locate a host in an IP network.
In some operating systems, the host file content is used preferentially over other methods, such as the Domain Name System (DNS), but many systems implement name service switches (.e.g., nsswitch.conf) to provide customization. Unlike the DNS, the hosts file is under the direct control of the local computer's administrator.

#This is an example of the hosts file
127.0.0.1 localhost loopback
::1 localhost

path of host file is:

Windows 95/98/Me c:\windows\hosts

Windows NT/2000/XP Pro c:\winnt\system32\drivers\etc\hosts

Windows XP Home c:\windows\system32\drivers\etc\hosts

List of Running ApplciationS

From the below snippet we can check the list of running applications and check whether your application is in foreground or not.

ActivityManager actvityManager = (ActivityManager)
this.getSystemService( ACTIVITY_SERVICE );
List procInfos = actvityManager.getRunningAppProcesses();

boolean appFound = false;

for(int i = 0; i < procInfos.size(); i++)
{
if(procInfos.get(i).processName == "com.android.camera")
appFound = true;
}

if (appFound)
Toast.makeText(getApplicationContext(), "Camera App is running!!!!", Toast.LENGTH_LONG).show();
else
Toast.makeText(getApplicationContext(), "Camera App is not running!!!!", Toast.LENGTH_LONG).show();

the above snippet shows your camera application is running or not.

UI/Application Exerciser Monkey

Today i gone through this tutorial from developer site seems to be interesting for UI application performance ,adding basic information on my blog:

---Basically Monkey is a program that runs on you emulator or Device(Mobile) and generates pseudo-random streams of user events such as clicks, touches, or gestures, as well as a number of system-level events.

---You can use the Monkey to stress-test applications that you are developing, in a random yet repeatable manner.

Description of Monkey Tool:

--The Monkey is a command-line tool that that you can run on any emulator instance or on a device. It sends a pseudo-random stream of user events into the system, which acts as a stress test on the application software you are developing.

Categories:

The Monkey includes a number of options, but they break down into four primary categories:
1.Basic configuration options, such as setting the number of events to attempt.
2.Operational constraints, such as restricting the test to a single package.
3.Event types and frequencies.
4.Debugging options.

****When the Monkey runs, it generates events and sends them to the system. It also watches the system under test and looks for three conditions, which it treats specially:

1.If you have constrained the Monkey to run in one or more specific packages, it watches for attempts to navigate to any other packages, and blocks them.
2.If your application crashes or receives any sort of unhandled exception, the Monkey will stop and report the error.
3.If your application generates an application not responding error, the Monkey will stop and report the error.

Depending on the verbosity level you have selected, you will also see reports on the progress of the Monkey and the events being generated.

Basic Use Steps for Monkey:

****You can launch the Monkey using a command line on your development machine or from a script. Because the Monkey runs in the emulator/device environment, you must launch it from a shell in that environment. You can do this by prefacing adb shell to each command, or by entering the shell and entering Monkey commands directly.

The basic syntax is:

$ adb shell monkey [options]

With no options specified, the Monkey will launch in a quiet (non-verbose) mode, and will send events to any (and all) packages installed on your target. Here is a more typical command line, which will launch your application and send 500 pseudo-random events to it:

$ adb shell monkey -p your.package.name -v 500

Command Options Reference

The below lists all options you can include on the Monkey command line.

1. --help : Prints a simple usage guide.

2. -v : Each -v on the command line will increment the verbosity level. Level 0 (the default) provides little information beyond startup notification, test completion, and final results. Level 1 provides more details about the test as it runs, such as individual events being sent to your activities. Level 2 provides more detailed setup information such as activities selected or not selected for testing.

3. -s : Seed value for pseudo-random number generator. If you re-run the Monkey with the same seed value, it will generate the same sequence of events.

4. --throttle : Inserts a fixed delay between events. You can use this option to slow down the Monkey. If not specified, there is no delay and the events are generated as rapidly as possible.

5. --wait-dbg : Stops the Monkey from executing until a debugger is attached to it.

etc., command for debugging, constraints, events & general commands refer android developer site for more information.

Developing a Device Administration Application

System administrators can use the Device Administration API to write an application that enforces remote/local device security policy enforcement. This section summarizes the steps involved in creating a device administration application.

Creating the manifest:
To use the Device Administration API, the application's manifest must include the following:

A subclass of DeviceAdminReceiver that includes the following:
--The BIND_DEVICE_ADMIN permission.
--The ability to respond to the ACTION_DEVICE_ADMIN_ENABLED intent, expressed in the manifest as an intent filter.

A declaration of security policies used in metadata.

Here is an snippet for the Device Administration sample manifest:

android:label="@string/activity_sample_device_admin">






android:label="@string/sample_device_admin"
android:description="@string/device_admin_description"
android:permission="android.permission.BIND_DEVICE_ADMIN">
android:resource="@xml/device_admin_sample" />






Note that:

The activity in the sample application is an Activity subclass called Controller. The syntax ".app.DeviceAdminSample$Controller" indicates that Controller is an inner class that is nested inside the DeviceAdminSample class. Note that an Activity does not need to be an inner class; it just is in this example.

The following attributes refer to string resources that for the sample application reside in ApiDemos/res/values/strings.xml. For more information about resources, see Application Resources.

android:label="@string/activity_sample_device_admin" refers to the user-readable label for the activity.

android:label="@string/sample_device_admin" refers to the user-readable label for the permission.

android:description="@string/sample_device_admin_description" refers to the user-readable description of the permission. A descripton is typically longer and more informative than a label.

android:permission="android.permission.BIND_DEVICE_ADMIN" is a permission that a DeviceAdminReceiver subclass must have, to ensure that only the system can interact with the receiver (no application can be granted this permission). This prevents other applications from abusing your device admin app.

android.app.action.DEVICE_ADMIN_ENABLED is the the primary action that a DeviceAdminReceiver subclass must handle to be allowed to manage a device. This is set to the receiver when the user enables the device admin app. Your code typically handles this in onEnabled(). To be supported, the receiver must also require the BIND_DEVICE_ADMIN permission so that other applications cannot abuse it.

When a user enables the device admin application, that gives the receiver permission to perform actions in response to the broadcast of particular system events. When suitable event arises, the application can impose a policy. For example, if the user attempts to set a new password that doesn't meet the policy requirements, the application can prompt the user to pick a different password that does meet the requirements.

android:resource="@xml/device_admin_sample" declares the security policies used in metadata. The metadata provides additional information specific to the device administrator, as parsed by the DeviceAdminInfo class. Here are the contents of device_admin_sample.xml:











Implementing the code

The Device Administration API includes the following classes:

DeviceAdminReceiver

Base class for implementing a device administration component. This class provides a convenience for interpreting the raw intent actions that are sent by the system. Your Device Administration application must include a DeviceAdminReceiver subclass.
DevicePolicyManager

A class for managing policies enforced on a device. Most clients of this class must have published a DeviceAdminReceiver that the user has currently enabled. The DevicePolicyManager manages policies for one or more DeviceAdminReceiver instances
DeviceAdminInfo

This class is used to specify metadata for a device administrator component.
These classes provide the foundation for a fully functional device administration application. The rest of this section describes how you use the DeviceAdminReceiver and DevicePolicyManager APIs to write a device admin application.

Subclassing DeviceAdminReceiver

To create a device admin application, you must subclass DeviceAdminReceiver. The DeviceAdminReceiver class consists of a series of callbacks that are triggered when particular events occur.

In its DeviceAdminReceiver subclass, the sample application simply displays a Toast notification in response to particular events. For example:

public class DeviceAdminSample extends DeviceAdminReceiver {

...
@Override
public void onEnabled(Context context, Intent intent) {
showToast(context, "Sample Device Admin: enabled");
}

@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
return "This is an optional message to warn the user about disabling.";
}

@Override
public void onDisabled(Context context, Intent intent) {
showToast(context, "Sample Device Admin: disabled");
}

@Override
public void onPasswordChanged(Context context, Intent intent) {
showToast(context, "Sample Device Admin: pw changed");
}

void showToast(Context context, CharSequence msg) {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
...
}

Enabling the application

One of the major events a device admin application has to handle is the user enabling the application. The user must explicitly enable the application for the policies to be enforced. If the user chooses not to enable the application it will still be present on the device, but its policies will not be enforced, and the user will not get any of the application's benefits.

The process of enabling the application begins when the user performs an action that triggers the ACTION_ADD_DEVICE_ADMIN intent. In the sample application, this happens when the user clicks the Enable Admin button

for Reference's Android Device Administration code

Powered by Blogger