Im trying to use monkeyrunner to configure multiple tablets attached to the same pc. The code works ok for 1 tablet but the moment I try to run it on multiple tablets it all blows up.
Here is the code which invokes the monkeyrunner python file. mr1.py is the monkeyrunner file I am trying to run.
import sys
import util
import threading
import commands
class myThread (threading.Thread):
def __init__(self, threadID, deviceId,env_path):
self.threadID = threadID
self.deviceId = deviceId
self.path = env_path
threading.Thread.__init__(self)
def run(self):
print "Starting " + self.deviceId
ret = commands.getstatusoutput(self.path+"monkeyrunner mr1.py "+self.deviceId)
print ret
print "Exiting " + self.deviceId
def main():
connected_devices = util.get_connected_devices()
count = 0
path = "/Users/ad/Desktop/android-sdk-macosx/tools/"
for device in connected_devices:
thread = myThread(count,device[0],path)
thread.start()
count = count + 1
if __name__ == "__main__":
main()
I came across this blogpost which describes about a race condition in monkeyrunner. I am not sure if thats what is causing the problem.
http://distributedreasoner.blogspot.com/2011/06/android-monkeyrunner-and-google-adb.html
I also tried using the MAML library mentioned in the above blog post, but I still havent been able to get monkeyrunner to execute simulatenously on multiple devices. Here is the actual monkeyrunner code.
import sys
import maml
from com.android.monkeyrunner import MonkeyRunner, MonkeyDevice
deviceId = sys.argv[1]
# Connects to the current device, returning a MonkeyDevice object
device = MonkeyRunner.waitForConnection(10.0,deviceId)
packagename = "com.android.settings"
classname = "com.android.settings.DisplaySettings" #SecuritySettings" #".DisplaySettings"
componentname = packagename + "/" + classname
device.startActivity(component=componentname)
maml.click(device,1088,300)
MonkeyRunner.sleep(0.4)
maml.click(device,864,361)
MonkeyRunner.sleep(0.4)
maml.click(device,612,621)
MonkeyRunner.sleep(0.5)
device.press ('KEYCODE_HOME', 'DOWN_AND_UP')
print "Exiting for device !" + deviceId
Based on Commonsware's question, I replaced the threading code with the following sequential code and it seems to work ok, but obviously this is not the most ideal situation.
for device in connected_devices:
print device[0]
ret = commands.getstatusoutput(path+"monkeyrunner mr1.py "+device[0])
print ret
Because Android doesnt allow you to modify location / language settings etc programatically, and I need to configure many tablets to change settings, the immediate option was to use MonkeyRunner. A couple of notes, I am open to other tools that I could use other than monkeyrunner to solve this problem. Any help on this problem would be greatly appreciated.
What settings are you trying to change? language can be sort of done within your application if that is the only one.
public void setLocale(Locale locale, Instrumentation inst){
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
inst.getTargetContext().getResources().updateConfiguration(config, inst.getTargetContext().getResources().getDisplayMetrics());
}
Are all your tablets api level 16+ (jely bean?) if so you might want to look at http://developer.android.com/tools/testing/testing_ui.html
Finally if you still want to do it with monkey runner I would recommend getting hold of all your devices in one thread and then passing in each device to each thread separately.
Python is not my specialty and i do not have access/knowledge fo all the libraries you are using (i could do it in java for you maybe?) but what i think might work better is something like:
class myThread (threading.Thread):
def __init__(self, device):
self.device = device
threading.Thread.__init__(self)
def run(self):
packagename = "com.android.settings"
classname = "com.android.settings.DisplaySettings"
componentname = packagename + "/" + classname
self.device.startActivity(component=componentname)
maml.click(self.device, 1088, 300)
MonkeyRunner.sleep(0.4)
maml.click(self.device, 864, 361)
MonkeyRunner.sleep(0.4)
maml.click(self.device, 612, 621)
MonkeyRunner.sleep(0.5)
self.device.press('KEYCODE_HOME', 'DOWN_AND_UP')
def main():
connected_devices = util.get_connected_devices()
count = 0
devices = []
for deviceId in connected_devices:
devices[count] = MonkeyRunner.waitForConnection(10.0, deviceId[0])
count = count + 1
for device in devices:
thread = myThread(device)
thread.start()
if __name__ == "__main__":
main()
basically the difference is as i said above, you get all the devices in sequence and then call each thread with the device you got sequentially. Does that make sense?