若使用的是vivo手机,Android系统是多个功能和服务的集合体,比如权限管理、蓝牙设置、电话服务、指纹与密码等常用功能有关的耗电会被计入Android系统,如果第三方软件使用到这些功能,电量也会被计入Android系统,所以我们看到Android系统程序耗电较高,实际和第三方软件的使用情况有关,您可以使用“一键加速”清理后台不必要的程序,适当调低屏幕亮度和音量;另外进入设置--电池,根据手机电量情况选择合适的省电模式,延长手机续航时间。
在芮城等地区,都构建了全面的区域性战略布局,加强发展的系统性、市场前瞻性、产品创新能力,以专注、极致的服务理念,为客户提供网站制作、网站建设 网站设计制作按需网站设计,公司网站建设,企业网站建设,成都品牌网站建设,全网营销推广,外贸网站建设,芮城网站建设费用合理。
一、前言
这系列文章是自己在平时开发过程中遇到的问题。之前只是记在云笔记上面,现在整理一下,发出来共享。
ps:像那些什么没有注册Activity呀,权限呀等最基本的就不再赘述。
二、ADB连接异常
有时我们发现,即使自己从任务管理器里面把adb.exe给干掉了,但还是不行,这时,你就可以尝试以下操作:
[2014-07-30 17:09:11 - QtActivity] The connection to adb is down, and a severe error has occured.
[2014-07-30 17:09:11 - QtActivity] You must restart adb and Eclipse.
[2014-07-30 17:09:11 - QtActivity] Please ensure that adb is correctly located at ‘D:\InstallFile\AndroidDevelop\ADT\sdk\platform-tools\adb.exe’ and can be executed.
adb起动失败:
1,杀掉其它的adb.exe看,如果不行,
2,看sdk\tools路径下面有没有
hprof-conv.exe
如果有,则把它复制到sdk\platform_tools下
3,如果没有,刚看sdk\platform_tools下有没有
hprof-conv.exe
如果有,刚复制到tools下。
4,如果两者都没有,刚下一个
hprof-conv.exe
三、java.lang.IllegalStateException: Activity has been destroyed
这个异常在切换Fragment中比较容易出现,稍不注意就会出现如下异常:
FATAL EXCEPTION: main12-0909:20:14.689: E/AndroidRuntime(31223): java.lang.IllegalStateException: Activity has been destroyed12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.enqueueAction(FragmentManager.java:1365)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.commitInternal(BackStackRecord.java:595)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.commit(BackStackRecord.java:574)12-0909:20:14.689: E/AndroidRuntime(31223): at cn.com.topsky.community.tfd.DongTaiFragment.init(DongTaiFragment.java:209)12-0909:20:14.689: E/AndroidRuntime(31223): at cn.com.topsky.community.tfd.DongTaiFragment.onCreateView(DongTaiFragment.java:68)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.Fragment.performCreateView(Fragment.java:1500)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:927)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1467)12-0909:20:14.689: E/AndroidRuntime(31223): at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:440)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Handler.handleCallback(Handler.java:605)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Handler.dispatchMessage(Handler.java:92)12-0909:20:14.689: E/AndroidRuntime(31223): at android.os.Looper.loop(Looper.java:154)12-0909:20:14.689: E/AndroidRuntime(31223): at android.app.ActivityThread.main(ActivityThread.java:4624)12-0909:20:14.689: E/AndroidRuntime(31223): at java.lang.reflect.Method.invokeNative(Native Method)12-0909:20:14.689: E/AndroidRuntime(31223): at java.lang.reflect.Method.invoke(Method.java:511)12-0909:20:14.689: E/AndroidRuntime(31223): atcom.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:809)12-0909:20:14.689: E/AndroidRuntime(31223): atcom.android.internal.os.ZygoteInit.main(ZygoteInit.java:576)12-0909:20:14.689: E/AndroidRuntime(31223): at dalvik.system.NativeStart.main(Native Method)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
经查,说这个是当前android-support-v4版本的一个bug,因为在当fragment进行到detached状态时,它会重置它的内部状态。
然而,它并没有重置mChildFragmentManager.这导致在Fragment重新attach时,它(fragment)没有重新attachm childFragmentManager,从而引发了上面的异常.
解决方案:
在每个调用getChildFragmentManager()的fragment中复写onDetach()方法:
@OverridepublicvoidonDetach() {super.onDetach();try{Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");childFragmentManager.setAccessible(true);childFragmentManager.set(this,null);}catch(NoSuchFieldException e) {thrownewRuntimeException(e);}catch(IllegalAccessException e) {thrownewRuntimeException(e);}}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
四、java.lang.IllegalArgumentException: Illegal character in query at index
这个异常,在我们拼接请求参数时,可能会碰到,原因是里面的特殊字符转换异常。解决办法如下:
url转换问题
String url = baseUrl + “?” + “name=” + name + “age=” + age;
url = url.replaceAll(“”, “%26”);
url = url.replaceAll(” “, “%20”);
解释如下:
特殊符号替换符号
?%3F
%26
|%124
=%3D
#%23
/%2F
+%2B
%%25
空格%20
五、eclipse连接小米2S调试程序的问题
虽然快2年没用过eclipse了,但这个问题还是贴出来,也许正好有正在用eclipse的同学遇到了此问题:
小米Mi2S连接到eclipse上无法识别。即使开启了调试模式,也无法识别.终于找到了一个可用的方法。
方法
用数据线连接手机和电脑。
打开手机拨号界面。
在拨号界面按 # #717717# # 自动就开启了。
在通知栏会出现一个 Diag USB port enable。
当然,应该是需要ROOT权限的。
这时候你的PC机会弹出安装设备驱动。
如果不成功,多插拔几次试试。
ok!安装完就搞定了!这时候打开eclipse就会在Driver里面看到你的手机了。
注意事项
在PC机上安装新硬件向导时候可能会遭遇到缺少dll文件,比如我就遇到缺少了WinUSBCoInstaller2.dll,这个问题。这时候就要去网上找找喽。这个东西分x64 和 x86的,注意不要搞错了!
如果先打开eclipse,再安装的话,可能导致eclipse挂掉,不明原因,可能是我机器配置不行。两次均有这种状况。所以建议先安装后再开eclipse。
蓝牙通信过程中异常很常见,大致有以下几种:
1,连接
2,发现服务
3,读写
4,通知
连接失败可能是设备端原因,也可能是手机端原因。不同的手机来自不同的厂家,用的不同的芯片和蓝牙协议栈都会导致蓝牙功能的表现不一致,这都会导致各式各样的兼容性问题,可能有的手机连接成功率高,有的成功率低。设备端原因可能有些时候出现异常导致死机无响应,或某些参数设置得有问题。但对于Android应用层开发来说,能做的很有限,蓝牙通信是在系统服务进程中处理的,我们无法跨进程改变系统的行为,如果是在一个进程我们还可能通过Hook等手段来调整其内在逻辑。另外应用层的接口只是将请求封装传递给系统服务进程,并未做一些实质性的通信,所以应用层虽然是同一个进程的,但是Hook意义也不大。所以我们能做的仅仅是看怎样调整接口的调用,使得整体稳定性更好一点而已。
连接失败分两种,一种是超时,一种是提前返回失败。
关于超时,一般是设备不在周围,或设备断电未发广播,或设备当前被其他人连接。系统默认超时为30s,通常返回133,我们也可以自己设置更短的超时时间,超时则closeGatt,然后重新连接。
关于提前返回失败,一般是有明确的异常,可能是手机蓝牙的异常或者设备异常。
这两种情况建议closeGatt,延时500ms,然后重试。如果重试三次仍然失败,则可以考虑提示用户重启手机蓝牙,或者检查设备是否正常工作。
还有一种情况,连接成功后没过多久连接又断开了,这有可能是设备主动断开,连接成功后有的设备会等待鉴权,如果一定时间内手机端还未发起鉴权则设备端主动断开。也可能连接信道不够稳定导致断开的,此时closeGatt并重新连接即可。
当连接断开时,会收到onConnectionStateChanged回调,这个回调可能会有一定延时,甚至有5s以上。解决的办法是轮询,如每隔1s发起一次读请求,如果连接断了会立即返回失败。
如果蓝牙连接不稳定,可以考虑关掉WIFI,因为WIFI通常和蓝牙共用一个天线。
有的手机上discoverService可能会回调不止一次onServiceDiscover,这个要注意防御。
当连接建立后,可以由设备端发起更改连接间隔,这样能加快后续发现服务以及数据读写的速度。有的手机discover service很慢,原因是connect interval太大了,有的手机会主动向设备发起更改connect interval,而有的手机却不会。这样的话connect interval相差就会很大,实践中发现有的手机是7ms,有的手机是默认的50ms,所以发现service都要8s,甚至20s的都很寻常,这对用户来说是无法忍受的。所以比较好的办法是设备主动发起更改connect interval,而Android系统是没有提供对应API的。
如果发现服务失败,通常来说不用closeGatt,重试一下就好了。如果重试三次还失败,建议清一下缓存,再closeGatt,重新连接。
读写失败要看失败的原因是什么,如果是权限问题,则需要和设备端确认是否开放了相应的读写权限。也可能是要读写的character不存在,可能是设备端修改了固件,手机端需要刷新一下蓝牙缓存,closeGatt再重新连接。如果是其它未知错误,则重试三次,仍然失败则closeGatt。不过通常来说如果是因为连接出了问题导致读写失败的,会收到onConnectionStateChanged回调,此时就不用再无谓的重试了,直接closeGatt,重新连接。
打开/关闭character的notify,必须等收到onDescriptorWrite回调之后才算结束,才能开始下一个任务。
如果打开notify失败,则可以改成周期性轮询的方式去查询character的值。
可参考该文章
Android-BLE-Issues
在实际编码中总是会遇到 空指针异常 ,本文总结了一些处理空指针的个人经验。
尽早的检查,尽早的失败。
比如: 通过intent传参到新的目标 activity,而且一定需要这个参数,那么在新的目标activity中 onCreate方法中 判断中这个参数,如果null,直接抛出空指针异常让程序崩溃。取代在使用该参数时进行检查,这样能更早的发现问题。或者在 一个普通的方法中,一个 参数必须不能为null ,那么我们在这个方法的第一行就做出判断,如果参数为null,抛出空指针异常。
1.不要在Set中使用null
2.不要把null作为map的键值。
3.尽可能的尽早检查,如果为 null 不执行或者 结束本方法
4.遇到必须的参数,比如通过intent传参到新的目标 activity,而且一定需要这个参数,那么在新的目标activity中判断是否有参数
5.判断字符串是否空
6.对字符串比较时,如果和常量进行比较,把常量放在前面,比如:
7.将某个对象 toString时,比如:
8.使用注解 @NonNull 和 @Nullable 配合AndroidStudio 帮你检查你是否没有检查可能为null的对象,或者你是否做了多余的检查。
9.我们引用Guava来帮忙检查 null 的情况,我们使用 checkNotNull 方法来替代写 if( obj == null) throw new NullPointExcetion(); ,示例:
Guava是什么: