I'm currently implementing a UI crawler for hybrid Android apps (i.e., Android apps implemented using PhoneGap), and the crawler requires periodic restarts to generate a model of the UI. Here, by "restart", I mean uninstall the app, do a fresh install of the same app, and resume execution of the crawler. (The idea is to get to the same initial state as before. One could argue that I can just reload the initial HTML page, but this would only work if the app does not save and reuse any data like login information, etc. The data needs to be fresh - i.e., what it was when the app was installed for the first time).
I'm quite new to Android app development, so I decided to test out what is perhaps the most naive method possible. The test code I've written is shown below. The method testReinstall() runs as an Android JUnit test, and I'm using Robotium 4.3 to execute clicks and other events on the app.
package com.example.googleauthenticator.test;
import java.io.IOException;
import android.test.ActivityInstrumentationTestCase2;
import com.example.googleauthenticator.MainActivity;
import com.jayway.android.robotium.solo.By;
import com.jayway.android.robotium.solo.Solo;
public class ReinstallTest extends ActivityInstrumentationTestCase2<MainActivity> {
private Solo solo;
public ReinstallTest() {
super(MainActivity.class);
}
@Override
protected void setUp() throws Exception {
super.setUp();
solo = new Solo(getInstrumentation(), getActivity());
}
public void testReinstall() {
//Reinstall app
Runtime rt = Runtime.getRuntime();
Process pr;
try {
pr = rt.exec("adb uninstall com.example.googleauthenticator"); //Uninstall
pr.waitFor();
pr = rt.exec("adb install GoogleAuthenticator.apk"); //Install
pr.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException ie) {
// TODO Auto-generated catch block
ie.printStackTrace();
}
System.out.println("Reinstall done!");
//Perform some action
if (solo.waitForWebElement(By.id("add"))) {
solo.clickOnWebElement(By.id("add"));
}
}
@Override
protected void tearDown() throws Exception{
solo.finishOpenedActivities();
super.tearDown();
}
}
I tried running the above code and it seems like it was able to successfully uninstall the app (or, at the very least, I know for a fact that the data/data/com.example.googleauthenticator folder was removed). However, the app does not get reinstalled (i.e., the data/data/com.example.googleauthenticator folder is still not there), and I presume this is related to the fact that by the time the first call to pr.waitFor() is reached, testReinstall() terminates due to a "Process crash", and the following message appears in the LogCat:
11-08 17:08:32.763: W/PluginManager(9285): Can't find plugin: com.example.googleauthenticator
What am I missing here? Is there a better/more correct way?
EDIT: To be clear, I'm also getting the following error message:
11-08 17:33:40.883: D/WebKit(14828): Unabled to create LocalStorage database path /data/data/com.example.googleauthenticator/app_database/localstorage