(Appium-Android) .DispatchActivity never started and app is crashing on launch

error : Exception in thread “main” org.openqa.selenium.SessionNotCreatedException: A new session could not be created. (Original error: com.xxx.psxandroid/.DispatchActivity never started. Current: com.xxx.psxandroid/.activity.WebviewActivity)

File app = new File("…");

		  DesiredCapabilities capabilities = new DesiredCapabilities();
		  capabilities.setCapability(CapabilityType.BROWSER_NAME,"" );
		  capabilities.setCapability("deviceName","BH90S0CL1L");
		  capabilities.setCapability("platformVersion","5.1.1");
		  capabilities.setCapability("platformName","Android");
		  
		  capabilities.setCapability("app",app.getAbsolutePath());
		  //capabilities.setCapability("appWaitActivity",".StartActivity");
		  //capabilities.setCapability("appWaitActivity",".DispatchActivity");
		  //capabilities.setCapability("app-Activity","./MainActivity");
		  
		  capabilities.setCapability("app-Activity","MainActivity");
		  
		  //capabilities.setCapability(CapabilityConstants.APP_ACTIVITY, "MainActivity");
		  
		  
		  capabilities.setCapability(MobileCapabilityType.APP_WAIT_ACTIVITY, ".DispatchActivity");
		  
		  driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
		  driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Is DispatchActivity the first activity your application starts? It seems that your application starts DispatchActivity, and then this activity will launch a different activity. In this case, you should wait for the activity your user will see rather than the activity the Android system will launch first.

wait for the activity your user will see:
how do I do that?

You have a few options.

  1. Ask your developers.
  2. Launch the application manually, but watch the logcat output for log messages like “am start…”. The activity you want to wait on will be in one of the “am start …” messages.
  3. Look through the application source code.
  4. If you don’t have access to the application source code, unpack the APK and convert AndroidManifest.xml back to a human-readable format (Search for a tool called apktool to do this). Look at the activities available, and try waiting on each one until you find the one that works.
  5. Use the Android shell’s “dumpsys” command (use adb shell to enter the shell). Use dumpsys window windows to see what the visible windows are on the screen. One of those windows will be your app’s windows, which includes the information about the current activity on the screen.

Options 1 and 2 are the easiest options. Option 5 is the next easiest option (interestingly, this is also the same option that Appium uses itself to check for which activity is on the screen), followed by option 4, and finally option 3. Option 3 might actually be easier than option 5 if you’re familiar with Android application development.

I tried no2 but I don’t see any messages like “am start…”
No 5 is showing me this :

Window #4 Window{8184aef u0 com.xxx.psxandroid/com.scee.psxandroid.activity.WebviewActivity}:
mDisplayId=0 mSession=Session{13de6982 22504:u0a10293} mClient=android.os.BinderProxy@138d9bce
mOwnerUid=10293 mShowToOwnerOnly=true package=com.xxx.psxandroid appop=NONE
mAttrs=WM.LayoutParams{(0,0)(fillxfill) sim=#110 ty=1 fl=#1810100 wanim=0x1030001 surfaceInsets=Rect(0, 0 - 0, 0) needsMenuKey=2}
Requested w=1080 h=1776 mLayoutSeq=1139
mHasSurface=true mShownFrame=[0.0,0.0][1080.0,1776.0] isReadyForDisplay()=true
WindowStateAnimator{370ca6c7 com.xxx.psxandroid/com.xxx.psxandroid.activity.WebviewActivity}:
Surface: shown=true layer=21020 alpha=1.0 rect=(0.0,0.0) 1080.0 x 1776.0

I tried to execute the script again and ran adb logcat :

W/QueryController(23094): parent = android.view.accessibility.AccessibilityNodeInfo@80007c51; boundsInParent: Rect(0, 0 - 1080, 1776); boundsInScreen: Rect(0, 0 - 1080, 1776); packageName: com.scee.psxandroid; className: android.widget.FrameLayout; text: null; error: null; maxTextLength: -1; contentDescription: null; viewIdResName: null; checkable: false; checked: false; focusable: false; focused: false; selected: false; clickable: false; longClickable: false; enabled: true; password: false; scrollable: false; actions: [AccessibilityAction: ACTION_SELECT - null, AccessibilityAction: ACTION_CLEAR_SELECTION - null, AccessibilityAction: ACTION_ACCESSIBILITY_FOCUS - null]
E/UiDevice(23094): Exceuting watcher: ANR2
E/UiDevice(23094): java.lang.IllegalStateException: UiAutomation not connected!
E/UiDevice(23094): at android.app.UiAutomation.throwIfNotConnectedLocked(UiAutomation.java:914)
E/UiDevice(23094): at android.app.UiAutomation.waitForIdle(UiAutomation.java:576)
E/UiDevice(23094): at com.android.uiautomator.core.UiAutomatorBridge.waitForIdle(UiAutomatorBridge.java:96)
E/UiDevice(23094): at com.android.uiautomator.core.UiAutomatorBridge.waitForIdle(UiAutomatorBridge.java:91)
E/UiDevice(23094): at com.android.uiautomator.core.QueryController.findAccessibilityNodeInfo(QueryController.java:143)
E/UiDevice(23094): at com.android.uiautomator.core.QueryController.findAccessibilityNodeInfo(QueryController.java:138)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.findAccessibilityNodeInfo(UiObject.java:168)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.waitForExists(UiObject.java:848)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.exists(UiObject.java:899)
E/UiDevice(23094): at com.android.uiautomator.common.UiWatchers$2.checkForCondition(UiWatchers.java:67)
E/UiDevice(23094): at com.android.uiautomator.core.UiDevice.runWatchers(UiDevice.java:557)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.findAccessibilityNodeInfo(UiObject.java:173)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.waitForExists(UiObject.java:848)
E/UiDevice(23094): at com.android.uiautomator.core.UiObject.exists(UiObject.java:899)
E/UiDevice(23094): at io.appium.android.bootstrap.utils.TheWatchers.isDialogPresent(TheWatchers.java:35)
E/UiDevice(23094): at io.appium.android.bootstrap.utils.TheWatchers.check(TheWatchers.java:20)
E/UiDevice(23094): at io.appium.android.bootstrap.SocketServer$1.run(SocketServer.java:124)
E/UiDevice(23094): at java.util.Timer$TimerImpl.run(Timer.java:284)
E/UiDevice(23094): Exceuting watcher: ANR

You probably want to add the activity to wait for to be that WebviewActivity in your capabilities object.

I’ve never seen your second error before, but if it’s reproducible, you might want to start a separate thread for it.

I already have the capabilities object set for appWaitActivity.

Can you post your updated code?

		  DesiredCapabilities capabilities = new DesiredCapabilities();
		  capabilities.setCapability(CapabilityType.BROWSER_NAME,"" );
		  capabilities.setCapability("deviceName","BH90S0CL1L");
		  capabilities.setCapability("platformVersion","5.1.1");
		  capabilities.setCapability("platformName","Android");
		  
		  capabilities.setCapability("app",app.getAbsolutePath());
		  capabilities.setCapability("appWaitActivity",".StartActivity");
		  capabilities.setCapability("appWaitActivity",".DispatchActivity");
		  capabilities.setCapability("app-Activity","./MainActivity");
		  
		  //capabilities.setCapability("app-Activity","MainActivity");
		  
		  //capabilities.setCapability(CapabilityConstants.APP_ACTIVITY, "MainActivity");
		  
		  
		  capabilities.setCapability(MobileCapabilityType.APP_WAIT_ACTIVITY, ".DispatchActivity");
		  
		  driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
		  driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

Change this line:

to be

capabilities.setCapability(AndroidMobileCapabilityType.APP_WAIT_ACTIVITY, "com.scee.psxandroid.activity.WebviewActivity");

I would recommend cleaning up your code used to build the capabilities object. For example, I don’t think “app-Activity” will be recognized by Appium because it has a dash in the middle. Also ask yourself, “Do I really need to specify the launch activity?” The launch activity is different from the wait activity.

You should also take a look at removing the duplicate “appWaitActivity” capability settings. The last capability setting for appWaitActivity will overwrite the ones before it.

I have changed the capabilitiy for appWaitActivity to .activity.WebviewActivity. Now its working fine.

Thanks for your help again
Updated code :
DesiredCapabilities capabilities = new DesiredCapabilities();
capabilities.setCapability(CapabilityType.BROWSER_NAME,"" );
capabilities.setCapability(“deviceName”,“BH90S0CL1L”);
capabilities.setCapability(“platformVersion”,“5.1.1”);
capabilities.setCapability(“platformName”,“Android”);

		  capabilities.setCapability("app",app.getAbsolutePath());
		  **capabilities.setCapability("appWaitActivity",".activity.WebviewActivity");**
		  //capabilities.setCapability(MobileCapabilityType.APP_WAIT_ACTIVITY,".DispatchActivity");
		  capabilities.setCapability("app-Activity","./MainActivity");
		    
		//capabilities.setCapability(MobileCapabilityType.APP_WAIT_ACTIVITY, ".DispatchActivity");
		  
		  driver = new AndroidDriver(new URL("http://127.0.0.1:4723/wd/hub"),capabilities);
		  driver.manage().timeouts().implicitlyWait(60, TimeUnit.SECONDS);

is this any way I check if the activity is app or web and put the logic accordingly?

I think with Appium 1.5, you can tell Appium not to automatically launch your application after it’s installed. You can then programmatically launch your application (using an Intent specified through Appium) from your test code. You can then start performing checks to see which activity was started after your launch activity. I’m not too familiar with this new feature, so you’ll have to check the docs on your own.