1月 042017
 

  Android提供一个命令行工具monkey可以对安卓程序进行测试,monkey会对应用生成随机的动作流,包括点击、触摸、手势、文字录入等,模拟人工操作应用,并在发生错误后发送报告给用户。使用方法:首先在avd manager中打开一个模拟器或者使用USB线连上真机,打开命令行窗口,输入下面的命令:

  其中com.bcoder.testapp是你的包的名字,5000代表要测试的次数

  如果你的命令行中不能执行adb命令,请找度娘给你配置一下adb

  monkey支持很多参数,下面是一个详细的参数列表:

类别 参数 描述
常规 --help 打印一个简单的使用向导(确实很简单!)。
-v

每增加一个-v就会增加输出的测试信息的详细度,共分为级别0、1、2,也就是最多输入两个-v

事件 -s <seed>

此参数后边可以跟随一个数字值,这个值用于生成随机操作的种子,当你下一次再用这个种子值操作时,会重复上一次一样的操作。

比如:你执行 adb shell monkey -p com.bcoder.testapp -s 10 1000后发现了程序的一个报错

可以在修复问题后重新执行上面的命令,monkey还会按和上次一样的顺序生成随机事件

作者注:貌似不是每次的操作完全一样

--throttle <milliseconds> 为每次的事件增加一个延时,用于放慢monkey的执行速度,单位毫秒
--pct-touch <percent> 设置触屏操作所占的百分比
--pct-motion <percent> 设置划屏操作所占的百分比
--pct-trackball <percent> 设置轨迹球操作所占的百分比
--pct-nav <percent>

设置方向键操作所占的百分比

Adjust percentage of “basic” navigation events. (Navigation events consist of up/down/left/right, as input from a directional input device.)

--pct-majornav <percent>

设置back键、menu键所占的百分比

Adjust percentage of “major” navigation events. (These are navigation events that will typically cause actions within your UI, such as the center button in a 5-way pad, the back key, or the menu key.)

--pct-syskeys <percent>

设置系统键所占的百分比

Adjust percentage of “system” key events. (These are keys that are generally reserved for use by the system, such as Home, Back, Start Call, End Call, or Volume controls.)

--pct-appswitch <percent>

Adjust percentage of activity launches. At random intervals, the Monkey will issue a startActivity() call, as a way of maximizing coverage of all activities within your package.

--pct-anyevent <percent> Adjust percentage of other types of events. This is a catch-all for all other types of events such as keypresses, other less-used buttons on the device, and so forth.
约束 -p <allowed-package-name>

指定一个或者多个包进行测试,比如-p com.bcoder.testapp,如果要指定多个包进行测试就要使用多个-p参数,比如adb shell monkey -p com.bcoder.testapp -p com.bcoder.testapp2 1000

If you specify one or more packages this way, the Monkey will only allow the system to visit activities within those packages. If your application requires access to activities in other packages (e.g. to select a contact) you’ll need to specify those packages as well. If you don’t specify any packages, the Monkey will allow the system to launch activities in all packages. To specify multiple packages, use the -p option multiple times — one -p option per package.

-c <main-category> If you specify one or more categories this way, the Monkey will only allow the system to visit activities that are listed with one of the specified categories. If you don’t specify any categories, the Monkey will select activities listed with the category Intent.CATEGORY_LAUNCHER or Intent.CATEGORY_MONKEY. To specify multiple categories, use the -c option multiple times — one -c option per category.
调试 --dbg-no-events When specified, the Monkey will perform the initial launch into a test activity, but will not generate any further events. For best results, combine with -v, one or more package constraints, and a non-zero throttle to keep the Monkey running for 30 seconds or more. This provides an environment in which you can monitor package transitions invoked by your application.
--hprof If set, this option will generate profiling reports immediately before and after the Monkey event sequence. This will generate large (~5Mb) files in data/misc, so use with care. See Traceview for more information on trace files.
--ignore-crashes

正常情况下,当测试遇到应用崩溃时,monkey就停止测试,如果使用了此参数,monkey将继续给系统发送事件直到运行完count所设定的值。

Normally, the Monkey will stop when the application crashes or experiences any type of unhandled exception. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.

--ignore-timeouts

正常情况下,当遇到ANR错误时,monkey就会停止测试,加上此参数后,monkey将会继续进行测试直到运行完所设定的count值。

Normally, the Monkey will stop when the application experiences any type of timeout error such as a “Application Not Responding” dialog. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.

-f

指定测试脚本文件,示例文件见文末尾

如:adb shell monkey -v -v -f /mnt/sdcard/monkey_click.txt 1000

--ignore-security-exceptions

同上,忽略安全性异常错误。

Normally, the Monkey will stop when the application experiences any type of permissions error, for example if it attempts to launch an activity that requires certain permissions. If you specify this option, the Monkey will continue to send events to the system, until the count is completed.

--kill-process-after-error Normally, when the Monkey stops due to an error, the application that failed will be left running. When this option is set, it will signal the system to stop the process in which the error occurred. Note, under a normal (successful) completion, the launched process(es) are not stopped, and the device is simply left in the last state after the final event.
--monitor-native-crashes Watches for and reports crashes occurring in the Android system native code. If –kill-process-after-error is set, the system will stop.
--wait-dbg Stops the Monkey from executing until a debugger is attached to it.

 

-f参数脚本示例

注意事项:

  1. count参数一定要放到最后面
12月 272016
 

  Zxing是一个可以实现条形码和二维码扫描的开源代码,现在利用Android Studio可以很方便的集成该代码库。下面是详细的使用步骤:

一、通过Gradle将Zxing集成到你的项目中

  打开项目中的主build.gradle文件,将以下代码添加到dependencies节点中,然后点击编辑器右上角的Sync Now按钮

  效果如下图所示

 

二、为执行代码添加按钮

  在你的Activity设计窗体中放置两个按钮,分别对应条码和二维码的操作,设置它们的onClick事件分别为onScanBarcode和onScanQrCode,代码如下:

三、扫描代码的实现

  调用Zxing很简单,创建一个IntentIntegrator对象并设置相应的属性,然后调用该实例的initiateScan方法即可打开手机摄像头开始扫描。示例代码如下

  如果调用相机不成功,可以尝试在AndroidManifest.xml中添加相机的使用权限:

四、获取扫码结果

  我们可以在onActivityResult中获得扫码的结果,通过IntentResult实例来接收扫描结果,代码如下:

五、该例的java全部java代码

  执行结果的截屏如下图:

六、其他注意事项

IntentIntegrator有两个方法是forFragment和forSupportFragment应该是用于支持Fragment和支持库版本的Fragment,如果需要在Fragment中使用Zxing可以研究一下。

12月 182016
 

  为TextView设置高度为wrap_content后,TextView中的内容很多时,就会自动往下占用空间,但是设置Maxheight属性后,又不能查看全部的文字内容,这时候就需要使用TextView可滚动,下面就是设置MaxHeight并设置可滚动的代码。

 

 Posted by on 2016-12-18
11月 202016
 

1.必须设置setLayoutManager

2.在onCreateViewHolder方法中填充布局的时候,inflate的最后一参数必须为false

3.Adapter类的getItemCount方法返回的数量必须是大于0的数量

 Posted by on 2016-11-20
10月 272016
 

使用gson进行数据解析后,必须在混淆脚本中添加如下代码,如果不加的话json解析就会失败。

其中-keep class com.bcoder.test.datatypes.** { *; }这一行class和.**之间改成你的Bean类所在的包名

10月 272016
 

  我们知道,当app的屏幕进行旋转或者其他的配置变化的时候,Fragment会执行它的周期变化,重新创建Fragment并加载(除非设置了setRetainInstance(true)),那么在重建的时候Fragment中的变量就会被重新初始化,运行中的状态将无法保留。

  setArgument中的Bundle可以用来存放各种需要保持的数据,即使Fragment由于配置改变而重建,这些保存的数据也不会被清除。

  下面我们将通过一个实例来测试一下,在实例的Fragment中共有3个TextView和一个Button,为了使测试的内容更清晰,下面把三个TextView对应的字符串列表如下:

textview1->banana,   textview2->apple,   textview3->pear

  对应的三个字符串:

  • mParam1: 在Fragment.newInstance中传入,并保存在setArgument中,但是在点击按钮时未更新到Argument中
  • mParam2: Fragment中的私有变量,和Argument无任何交互
  • mParam3: 在Fragment.newInstance中传入,并保存在setArgument中,并且在点击按钮时更新到了Argument中

  测试程序的布局代码和java代码如下:

  Fragment部局文件的代码

  Fragment的Java代码

  主Activity的代码

  主Activity的布局文件代码

  程序启动时显示默认如下内容:

  textview1和textview3的值取自getArgument并显示在了屏幕上,当点击按钮时会重新给三个String变量赋值,并显示到textview中,如下图:

  这时三个字符串变量都有了新的值,那么当我们把屏幕进行一下旋转操作后,看结果如何呢?

  由图可知,字符串1回到了最初的状态(创建Fragment时传入的值),而字符串2被清除了。

  字符串3因为在点击按钮的时候重新被保存在getArgument中,而没有任何的变化的被保留下来了。

  因此大家在给Fragment传入参数的时候最好通过setArgument进行保存,而不是简单的通过一个变量进行保存。

注意:

  1. setArgument只能在Fragment中创建后(MyFragment fragment = new MyFragment())立即调用,如果在Fragment被附加到Activity中后再调用就会报错,可以在按钮的点击事件中添加一下setArgument的调用进行一下试验,应用将被异常终止。
8月 292016
 

直接上代码

Calendar calendar = Calendar.getInstance();

//显示当前时间
System.out.println(calendar.getTime());

//各种日期格式化
SimpleDateFormat format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);

String str = format.format(calendar.getTime());
System.out.println(str);

format = new SimpleDateFormat(“yyyyMMdd”);
str = format.format(calendar.getTime());
System.out.println(str);

format = new SimpleDateFormat(“yyyy/MM/dd”);
str = format.format(calendar.getTime());
System.out.println(str);

format = new SimpleDateFormat(“yyyy/M/d”);
str = format.format(calendar.getTime());
System.out.println(str);

//获取时间戳
str = String.valueOf(calendar.getTimeInMillis());
System.out.println(“时间戳: ” + str);

//减去一天
calendar.add(Calendar.DAY_OF_YEAR, -1);
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

//减去一个月
calendar = Calendar.getInstance();
calendar.add(Calendar.MONTH, -1);
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

//减去一年
calendar = Calendar.getInstance();
calendar.add(Calendar.YEAR, -1);
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

//只获取日期,不包含时间
calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 0);
calendar.set(Calendar.MINUTE, 0);
calendar.set(Calendar.SECOND, 0);
calendar.set(Calendar.MILLISECOND, 0);
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

//获取本月的第一天
calendar = Calendar.getInstance();
calendar.set(Calendar.DAY_OF_MONTH, 1);
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

//时间戳字符串转日期时间
calendar = Calendar.getInstance();
str = String.valueOf((calendar.getTimeInMillis() – 60 * 1000) ); //减去一分钟
calendar.setTimeInMillis(Long.parseLong(str));
format = new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.SSS”);
str = format.format(calendar.getTime());
System.out.println(str);

 Posted by on 2016-08-29
8月 162016
 

  要给app做一个定时提醒的功能,使用到了AlarmManager,因为涉及到很多天以后的提醒,所以不好测试,但是通过adb是可以查看系统已保存的AlarmManager 的,具体命令如下:

  如果我们只想看我们自己的应用的情况,则用linux的过滤器也可以(MAC下使用未在Windows下测试),命令如下:

 

8月 052016
 

1、运行时授权

  6.0以后用户可以运行时对应用进行授权管理,当你的应用需要使用某个权限时可以用checkSelfPermission()检查是否拥有某个权限,如果没有这个权限的话使用requestPermissions()来申请权限。

2、磕睡模式和应用空闲状态的优化

  此特性是为了更好的节省系统用电量。

3、除去Appche Http Client的支持

  如果你原来使用了这个Client,并且你的目标系统在Android2.3(Api Level9)以上,那么你现在可以使用HttpURLConnection代码Apache http client,这个api的流压缩和响应缓存可以提高网络访问的效率,并降低电量的耗损。如果你还想继续使用Apache http client,那么你可以在build.gradle中加入以下代码

4、BoringSSL

  使用BoringSSl代替原来的OpenSSL,使用NDK的需要注意,具体查一下官网的介绍。

5、硬件标识访问

  为了更好的保护用户的数据,此版本不再支持程序获取设备的本地Wifi和蓝牙的硬件标识,WifiInfo.getMACAddress()和BluetoothAdapter.getAddress()方法将始终返回值为02:00:00:00:00:00

如果要通过蓝牙或者Wifi扫描获取附近的外部设备的硬件标识,你的应用必须定义ACCESS_FINE_LOCATION和ACCESS_COARSE_LOCATION权限。

6、通知Notifications

  不在支持方法Notification.setLatestEventInfo(),使用Notification.Builder类代替来创建notifications。如果要多次更新notification,定义一个全局的Notification.Builder实例并在这个对象内更新,最后使用build()方法获取更新后的notification对象。

7、AudioManager的改变

  不再支持直接通过AudioManager类设置音量和静音指定的音频流。setStreamSolo()方法不再推荐使用,你可以通过requestAudioFocus()方法代替。setStreamMute()也不再推荐使用,你可以使用adjustStreamVolume()方法和参数ADJUST_MUTE or ADJUST_UNMUTE代替该方法。

8、文本的选择操作

  在此版本中,用户选择文本后,你可以顶部的ActionBar中显示对选择文本的复制、粘贴、剪切等按钮,具体的参考官网中提供的步骤。

9、浏览器书签的变化

  不在支持全局的书签,应用不再支持获取和保存浏览器中的书签。android.provider.Browser.getAllBookmarks()  和 android.provider.Browser.saveBookmark() 方法被移除,同样地,READ_HISTORY_BOOKMARKS和 WRITE_HISTORY_BOOKMARKS 权限被移除。

10、Android Keystore的变化

  Android Keystore Provider不再支持DSA,ECDSA还在支持,没用过此功能,不知道有什么影响。

11、WIFI和网络的变化

 

 Posted by on 2016-08-05
8月 022016
 

1.首先要有一个Long型的主键

2.该主键的初始值要赋值为null

 

如下:

原理是:

当id的初始值设为null时,执行insert into 语句时,id的值也为null,然后数据库系统会自己计算这个,如下这个sql语句