Reputation: 5842
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.
Upvotes: 0
Views: 2336
Reputation: 5819
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?
Upvotes: 1