根据前一篇文章《移植MonkeyRunner的图片对比和获取子图功能的实现-Appium篇》所述,因为Appium和MonkeyRunner有一个共同点--代码控制流程都是在客户端实现的。所以要把MonkeyRunner在PC端实现的图片比对和获取子图功能移植到同样是在PC端运行的Appium是很容易的事情,但是对于在服务器端运行的Robotium和UiAutomator就是另外一回事了。

因为在Android的sdk中,MonkeyRunner获取子图和图片比对需要用到的以下两个类是没有支持的,简单来说就是java.awt这个库是不支持的:

importjava.awt.p_w_picpath.BufferedImage;importjavax.p_w_picpathio.ImageIO;

但是在Android的sdk中有Bitmap这个类来帮助我们完成类似的功能,同时这个类还提供了一个sameAs的方法来比对两个Bitmap是否一致,但是遗憾的是它没有像MonkeyRunner一样提供一个百分比来指明两个图片的差异接受程度,所以为了兼容多种情况,我们需要对sameAs方法提供多个重载方法。

当然,这只是验证代码,有bug的话自己调吧。

1. 移植代码

注意一下代码只在UiAutomator上面测试通过,但是我相信Robotium是一样的,因为他们都是运行在目标安卓机器上面的,大家可以自行验证下。

packagelibs;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importandroid.graphics.Bitmap;importandroid.graphics.BitmapFactory;publicclassUtil{publicstaticbooleansameAs(Stringpath2,Stringpath3)throwsFileNotFoundException{booleanres=false;FileInputStreamfis1=newFileInputStream(path2);Bitmapbitmap1=BitmapFactory.decodeStream(fis1);FileInputStreamfis2=newFileInputStream(path3);Bitmapbitmap2=BitmapFactory.decodeStream(fis2);res=sameAs(bitmap1,bitmap2);returnres;}publicstaticbooleansameAs(Stringpath2,Stringpath3,doublepercent)throwsFileNotFoundException{FileInputStreamfis1=newFileInputStream(path2);Bitmapbitmap1=BitmapFactory.decodeStream(fis1);FileInputStreamfis2=newFileInputStream(path3);Bitmapbitmap2=BitmapFactory.decodeStream(fis2);returnsameAs(bitmap1,bitmap2,percent);}publicstaticbooleansameAs(Bitmapbitmap1,Bitmapbitmap2,doublepercent){if(bitmap1.getHeight()!=bitmap2.getHeight())returnfalse;if(bitmap1.getWidth()!=bitmap2.getWidth())returnfalse;if(bitmap1.getConfig()!=bitmap2.getConfig())returnfalse;intwidth=bitmap1.getWidth();intheight=bitmap2.getHeight();intnumDiffPixels=0;for(inty=0;y<height;y++){for(intx=0;x<width;x++){if(bitmap1.getPixel(x,y)!=bitmap2.getPixel(x,y)){numDiffPixels++;}}}doublenumberPixels=height*width;doublediffPercent=numDiffPixels/numberPixels;returnpercent<=1.0D-diffPercent;}publicstaticbooleansameAs(Bitmapbmp1,Bitmapbmp2)throwsFileNotFoundException{booleanres=false;res=bmp1.sameAs(bmp2);returnres;}publicstaticBitmapgetSubImage(Stringpath,intx,inty,intwidth,intheight)throwsFileNotFoundException{FileInputStreamfis=newFileInputStream(path);Bitmapbitmap=BitmapFactory.decodeStream(fis);Bitmapres=Bitmap.createBitmap(bitmap,x,y,width,height);returnres;}}2. 调用代码示例

以下是UiAutomator示例,Robotium的示例请大家自行实现.

packagesample.demo;importjava.io.File;importjava.io.IOException;importlibs.Util;importandroid.graphics.Bitmap;importcom.android.uiautomator.core.UiDevice;importcom.android.uiautomator.core.UiObject;importcom.android.uiautomator.core.UiObjectNotFoundException;importcom.android.uiautomator.core.UiSelector;importcom.android.uiautomator.testrunner.UiAutomatorTestCase;publicclassCompareScreenshotsextendsUiAutomatorTestCase{publicvoidtestCompareScreenshotsNSubScrenshots()throwsUiObjectNotFoundException,IOException,InterruptedException{UiDevicedevice=getUiDevice();//device.pressHome();UiObjectappNotes=newUiObject(newUiSelector().text("Notes"));appNotes.click();Thread.sleep(3000);Stringp1="/data/local/tmp/1.bmp";Stringp2="/data/local/tmp/2.bmp";Filef1=newFile(p1);if(f1.exists())f1.delete();Filef2=newFile(p2);if(f2.exists())f2.delete();device.takeScreenshot(f1);device.takeScreenshot(f2);Bitmapsub1=Util.getSubImage(p1,6,39,474,38);Bitmapsub2=Util.getSubImage(p2,6,39,474,38);booleansame=Util.sameAs(sub1,sub2,1.0);assertTrue(same);same=Util.sameAs(p1,p2,0.9);assertTrue(same);}}