Android: Dealing with "IllegalStateException: Can not perform this action after onSaveInstanceState"

This one baffled me for a while. I've only noticed this recently on KitKat 4.4 while transitioning some old apps to use fragments and this exception was put onto the table, but it's definitely a good one to have around.

There are a lot of posts asking how to fix this online. One of them suggests filling Bundle outState with some data before calling super.onSaveInstanceState(). I'm not sure what the mentality behind that is, but it doesn't work (even though it's the selected solution). Heck, I'm not even sure if it was tested.

A few of them are even (ignorantly) suggesting you change your FragmentTransaction.commit() call to FragmentTransaction.commitAllowingStateLoss(), and this will only cause you and your users problems in the long run.

172214lzcc8fda3j4qjcj4

This is NOT an ideal solution. You are not fixing the problem, you are hiding it. Don't do it!

Personally, the only place I would only use it is after a bad APK has gone live and you need to get it fixed within the next half-hour. Once the temporary hot-fix is out, take the time to fix it properly and then remove commitAllowingStateLoss().

Why is it happening?

In essence, what happens is the timing of your FragmentActivity vs Fragment/DialogFragment code allows information to be lost because they all share a common onSaveInstanceState() .

There is a great post by Alex Lockwood titled "Fragment Transactions & Activity State Loss" which explains the whole thing a lot better than I ever could.

Fixing it

The exception is a tricky one to trace down, but at least the stack trace will give you an indication of where it was generated.

In my case, I had a "open file" activity which returned a result to the main activity. Within MainActivity.onActivityResult(), I validated the file type and then immediately displayed a DialogFragment if it was an unrecognised format.

The onSaveInstanceInstanceState() was called during the activity switching, and then sometime during the DialogFragment.show() process the exception was triggered.

Code before:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}

switch(requestCode) {
case ACTIVITY_CHOOSE_FILE: {
// ...

if (!checkOk(data)) {
// Calling this from onActivityResult() gives this exception
// Caused by: java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
// Because Activity result calls DialogFragment.show() from openFile().
openFile(data);
}
}
}
}

Rather than displaying the DialogFragment immediately, I put a slight delay in my onActivityResult() code using a thread in order to prevent the error.

Code after:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode != RESULT_OK) {
return;
}

switch(requestCode) {
case ACTIVITY_CHOOSE_FILE: {
// ...

if (!checkOk(data)) {
// Shift the call to a thread
new Thread(new Runnable() {
@Override
public void run() {
// Then bump it back onto the UI thread
runOnUiThread(new Runnable() {
@Override
public void run() {
openFile(data);
}
});
}
}).start();
}
}
}
}

In effect, the end result is the same and runs fine on all versions of Android without any noticeable delays.

Hate it when small things like this catch you out. These exceptions may be annoying, but they prevent you from randomly losing data by making it painfully obvious that you done goofed.

Sources

Frustration after reading many unhelpful (suggesting to use commitAllowingStateLoss) posts on StackOverflow. Here are some examples:

Canon: Installing PhotoStitch without the a CD

In the past year I've been doing just fine my new computer which doesn't have a CD drive.

Well, until today that is. Canon's PhotoStitch software is pretty good, but you can't actually get it without using the disc that came with the camera! This is a bit of a pain...

IMG_20140106_000711
Camera? Check. CD? Check. Camera case and box? Double check! I'm legit, don't taze me bro.

That was until I found a little registry hack which tricked it into thinking you had the software already installed!

Download Canon's PhotoStitch 3.1.23 Updater for Windows here.

Now you'll have time to create the registry file in order for the updater to work.

Creating the registry

  • Open up Notepad and paste in the following chunk of text. The text you paste depends on your version of Windows!

 

If you're using Windows 7 32bit (x86)...

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\EOS Utility]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\DPP]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\ZoomBrowser EX]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\PhotoStitch]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\EOS Capture]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\EOSViewerUtility]
[HKEY_LOCAL_MACHINE\SOFTWARE\Canon\ODSK]

If you're using Windows 7 64bit (x64)...

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\EOS Utility]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\DPP]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\ZoomBrowser EX]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\ZoomBrowser EX\Settings]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\ZoomBrowser EX\Install]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\PhotoStitch]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\EOS Capture]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\EOSViewerUtility]
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Canon\ODSK]

 

  • Now click File > Save to save the file to your desktop.
  • For the filename, save it as "canon.reg"
  • And for the "Save as file type", change it to "All files (*.*)"
  • Now to go your desktop, double click the file and apply it.
  • Extract and run the PhotoStitch updater
  • Enjoy!

3dtYJLd.gifPq1rhr4s0o1_400 
Boom! Now it "just works"!

Sources

Linux: Installing Peer Guardian 2; an IP blocker like PeerBlock for Windows

Peer Guardian 2, once called MoBlock, has taken the place of the original Peer Guardian which has been abandoned. This helps guard against nasty internet peers such as other users, honey pot type servers, ad servers or known malware hosts. Other uses can be to protect yourself against IP loggers such as copyright activists.

aeNQz7W_460sa
The internet. It's a dangerous world out there full of "WTFs"...

The installation process is now much easier than it was 2 years ago when I first posted about IP blocking, so fire up a terminal and let's get busy!

sudo add-apt-repository ppa:jre-phoenix/ppa
sudo apt-get update
sudo apt-get install pgld pglcmd pglgui gksu

Without gksu (or kdesu), you'll get errors such as this:

Could not use either kdesu(do) or gksu(do) to execute the command requested. You can set the path of the one you prefer in "Options - Settings - Sudo front-end"

Now run pglgui (either through command line or your system menu).

image

  • If the blocker is running, click "Stop"
  • Click on "Configure" tab
  • Update the lists weekly
  • Tick "bluetack/level-1"
  • Untick everything starting with "tbg/". These will render your internet useless unless you know exactly why you need it.
  • Everything else is optional and to your liking.
  • Click "Apply"
  • Switch back to the "Control" tab
  • Click "Update"
  • Once it's done, click "Reload"
  • Then click "Start" as soon as it's ready

In case you're unsure, the lists I kept are:

  • atma/atma
  • bluetack/bad-peers
  • bluetack/dshield
  • bluetack/level-1
  • bluetack/spyware

This ensures I'm blocked against the standard baddies, but at the same time still able to connect out to the big bad internet.

*update 19/12/14* Thanks to Anonymous for spotting out a typo!

Sources

VirtualBox: Fix for "Cannot access the kernel driver"

I ran into this when trying to upgrade my VirtualBox from 4.2.6 to 4.3.6. It was a really frustrating one to fix. There are a few suggested fixes floating around such as:

  • Manually installing both VBoxUSBMon.inf and VBoxDrv.inf drivers (didn't work for me)
  • Uninstall and reinstall (wasn't possible because the uninstaller kept rolling back)
  • Removing the network interfaces manually before installing (they weren't there)
  • Install over it (installer for new version kept rolling back)
  • Removing the files from user and program file folders, then manually searching/replacing all instances of VirtualBox in the registry (this is brute forcing it and I don't want to resort to this)

None of them worked for me.

What I ended up doing was:

  • Grab an old copy of your Virtualbox installer (make sure it's the same version!) from the VirtualBox wiki
  • Run the installer
  • Select "Repair" (on the old version)
  • Reboot
  • (optional) Uninstall the old version
  • Install the new version

This time it should work!

GfZf4F6
Simple, no?

Sources

 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog