Android一些经验技巧

以下所有内容都是平时遇到过的问题和总结的经验,记录自己踩过的坑,以免再一次踩坑!

1、启动activity可以搜索ActivityManager: Start的log

2、输出某处的调用栈的log,log.e("csf info", "csf info", new Exception());

3、要查看安装在手机的apk用了什么分辨率的资源,连上adb后可在文件系统中看/system/priv-app,把相应的apk取出来,改后缀为.tar文件,解压出来基本就可以看到是什么分辨率的了。

4、adb reboot download进入download模式

5、FC问题在log中搜索fatal、err、error等关键字

6、安装apk失败后可以查看log的关键字PackageManager:result of install,-112表示前后安装apk的签名不同,具体的错误码可以查看安卓源代码packageManager.java文件,在里面搜索错误码就可以知道原因了,比如搜索-112。如果是版本低于原来的版本而导致安装失败,可搜索Downgrade detected关键字,查看当前的版本号

7、activity返回后回调到onActivityResult函数

8、改变屏幕方向、弹出软键盘和隐藏软键盘时,如果声明了activity的onConfigurationChanged函数,则执行该函数,否则执行onCreate函数。所以最好是需要声明onConfigurationChanged函数。

10、sharePreferences的本质是一个xml文件,存储key-value,sharePreferences对象本身只能获取数据而不支持存储和修改,存储修改是通过Editor对象实现。其存储位置在/data/data/<包名>/shared_prefs目录下

11、doInBackground、onPostExecute是调用AsyncTask.execute后的回调

12、如果有native crash, log文件夹里应该有dumpstate_native_xxx生成

13、一个java文件可以有多个类,但只能有一个public类,而且类名与文件名相同

14、如果一个类testClass是一个抽象类,现在不知道具体的实现类,可以这样获取:

Log.d("csf", testClass.getClass().toString());

或者

Log.d("csf", testClass.getClass().getName());

15、adb发送key事件adb shell input keyevent KEYCODE

16、webview

//打开本包内asset目录下的index.html文件

wView.loadUrl("file:///android_asset/index.html ");

//打开本地sd卡内的index.html文件

wView.loadUrl("content://com.android.htmlfileprovider/sdcard/index.html");

//打开指定URL的html文件

wView.loadUrl("OSCHINA - 中文开源技术交流社区");

17、查看进程使用内存的情况

①adb shell ps查出对应进程的pid

②adb shell dumpsys meminfo pid列出pid所占用的内存

18、实时打印某一进程的内存使用情况,这个技巧在分析内存泄露时十分有用

①adb shell

②while true;do dumpsys meminfo pid | grep TOTAL;sleep 1;done;

19、查看有哪些service

adb shell dumpsys | grep "DUMP OF SERVICE"

20、内存分析工具MAT

21、

运营商制式

 

CTC电信

CMCC移动

CU联通

2G

CDMA

GSM

GSM

3G

CMDA2000

TD-SCDMA

WCDMA

4G

FDD-LTE

TDD-LTE

FDD-LTE

双卡:两张卡

双模:CDMA与GSM

双待:一般指同一模式下的双待,如GSM网络双卡双待

双通:通话和数据网络同时可以进行

IMEI:一般分配给GSM、WCDMA制式的手机(移动、联通)

MEID:主要分配给CDMA制式的手机(电信)

22、APP使用什么分辨率的资源和屏幕像素密度有关,ldpi、mdpi、hdpi、xhdpi、xxhdpi对应到ppi分别是120ppi、160ppi、240ppi、320ppi、480ppi,如果不知道这台手机使用什么分辨率的资源,可以先查屏幕ppi,再对应到dpi

23、(和第三点相同)查app使用什么分辨率的资源,除了上面的方法,还可以解压/system/priv-app/路径下面的apk,解压出来后看里面的RES使用什么资源

24、安卓源码android\frameworks\base\core\java\android\provider这里保存了android系统的content-provider

25、发生ANR一般是因为下面两种情况

①界面操作按钮的点击等待响应时间超过5秒

②HandleMessage回调函数执行超过10秒,BroadcastReceiver里的onReceive()方法处理超过10秒

③service的生命周期函数超过20秒

26、ANR问题可以搜索log的一些关键字,如“ANR ”,带空格可过滤很多无用信息,“LAST ANR”,"Application is not responding",“ActivityManager: ANR”

27、log中搜索Dalvik Thread可以看虚拟机信息,每一段都是一个线程

28、log中搜索DUMP OF SERVICE cpuinfo:,可看到cpu的使用情况

29、log中搜索PACKAGE LIST,可看到手机上所有的包

30、开发一个app时,到底选择content-provider还是database存储数据,有这些标准

①希望向其他程序提供复杂的数据和文件,则用contentProvider

②希望用户从程序复制复杂数据到其他程序则用contentProvider

③希望提供用搜索引擎框架提供自定义搜索提示则用contentProvider

④如果数据完全只用于程序内部,用database比较合适

31、写代码时注意下面这点会引起的内存泄露

query数据库时,返回的cursor一定要及时close,一般用try catch finally这样的方式来query数据库,cursor的close放在finally执行,这样无论是否出现exception都可close掉cursor

32、查询数据库的时候,最好设定projection的参数,只查询所需要的数据,如果把所有的列都查询出来,会损耗较多的内存。

33、线程间的消息传递是通过handler进行的,handler把消息放入消息队列,looper去循环消息队列,只有UI线程才有looper,子线程没有looper,也就是说,只能在UI线程创建handler,不能在子线程创建handler,当然也可以通过这样的方式在子线程创建handler,new Handler(Looper.getMainLooper()),不过这样子线程使用的还是UI线程的looper,哈哈。至于子线程为什么没有looper,可查看Handler的源码,在子线程创建handler的时候,会catch到运行时错误"Can't create handler inside thread that has not called Looper.prepare()"

34、更正33点的说法,子线程想要拥有looper,可以通过Looper.prepare()创建looper对象和MeesageQueue对象,HandlerThread就是一个例子。

35、intent传送数据时,比如传送bitmap,数据不能超过40k,否则会出现JavaBinder: !!! FAILED BINDER TRANSACTION !!!的错误

36、source insight control --> 打开文件所在路径并选择该文件explorer /e,/select,%f

37、把view设ripple波纹效果,要把view的onClickable设为true,否则有时波纹效果不生效

38、xml的布局中不能直接使用ViewGroup标签,因为ViewGroup是抽象类,不能实例化

39、无论在代码还是xml中,listview都不能addView,因为listview继承了adapterView,这是个抽象类。比如在xml中,listview标签下面不能有child view,比如在listview的adpater中getview的时候,inflate出来的child不能这样写newView = Inflater.inflate(R.layout.xxxx, parent, true);//不能是true,只能是false
40、Android系统进行GC时,所有线程的任何操作都会暂停,等待GC完成后,再进行操作。当出现内存泄漏时,内存中可用的Heap size越来越少,GC操作就会越来越频繁,所以内存泄漏是会影响性能的。
41、测试app的启动时间adb shell am start -W packageName/activityName

42、layout_marginStart和layout_marginLeft的区别是:当布局为left-to-right时,两者无差别,当布局为right-to-left时,layout_marginStart就代表右边的margin了。开发者模式中可选择RTL layout,在某些open项目选择某些国家语言时也会切换到RTL layout
43、打开开发者模式的strict mode,当界面有可能出现ANR时,会闪红框,说明当前界面UI thread处理工作量较多。
44、操作SharePreference时如果无需返回值使用apply代替commit

45、改ANR问题时,可搜索trace文件wait,看是否有线程在等待,从而造成死锁。

46、看ANR的log,从LOG可以看出ANR的类型,CPU的使用情况,如果CPU使用量接近100%,说明当前设备很忙,有可能是CPU饥饿导致了ANR,如果CPU使用量很少,说明主线程被BLOCK了,如果IOwait很高,说明ANR有可能是主线程在进行I/O操作造成的

47、录像adb shell screenrecord /sdcard/test.mp4输入后开始录像,CTRL+C停止录像

48、手机连接eclipse,出现ADB server didn't ACK *fail to start daemon*或者DDMS显示不出进程列表的解决方案:任务管理器杀掉adb进程 -> adb start-server,或者杀掉adb进程后,在DDMS reset adb

49、快速搜索email进程的虚拟机信息Cmd line: com.samsung.android.email.provider

50、arrayList遍历remove时,注意每次remove一个,arraylist的size都会发生变化,所以不能简单的用position来遍历。

51、当在一个线程对hashMap或者list这样的结构进行iterator操作时,不允许在另外的线程对这个结构进行修改操作,否则会出现ConcurrentModificationException的异常

52、有时在gradle中需要加入support的包,想要查看support包中控件有哪些版本,比如查看CardView的版本,可在SDK_PATH\extras\android\m2repository\com\android\support\cardview-v7这个路径查看

53、xml里面的配置如android:color,这个color的名字的定义可在\android\frameworks\base\core\res\res\values\attrs.xml中找到,实际上就是一个自定义的属性,只不过通过android这个命名空间找到,xml里面的配置是初始化view时通过构造函数的AttributeSet传进去的

54、对于一些渐变色的图片作为背景时要注意大小,如果控件比图片的size要大,图片就会被拉伸,这种情况往往在界面上会显示奇怪意想不到的效果,还以为代码写得有问题呢。本人在功能机和android上都踩过这个坑了。

55、adb shell后查看开机动画setprop ctl.start bootanim,关闭动画setprop ctl.stop bootanim

56、adb截图命令/system/bin/screencap -p /sdcard/screenshot.png

57、AS加入so库的方法是在src/main中新建jniLibs目录,把so拷贝到这个目录

58、sw360 sw411这个smallWidth值的计算:

smallWidth表示最小宽度,是屏幕宽和高的较小值,一般宽比高小,所以这个值一般是 = 屏幕宽度(px) / 屏幕密度

屏幕宽度和屏幕密度这两个值在DEV Tools -> Configuration 这个app可以查看到,比如C5,当显示比例是Larger的时候,

从Dev Tools -> Configuration 可以看到屏幕宽度是1080,屏幕密度density = 3, 1080 / 3 = 360,所以引用的资源是sw360dp-***dpi。

当显示比例是smaller的时候,从Dev Tools -> Configuration 可以看到屏幕宽度是1080,屏幕密度density = 2.625, 1080 / 2.625 = 411,

所以引用的资源是sw411dp-***dpi

59. Binder是一种架构,提供了服务端、Binder驱动、客户端接口三个模块。一个Binder服务端实际上就是一个Binder类的对象,

该对象一旦创建,内部就启动一个隐藏线程。该线程会接收Binder驱动发送的消息,收到消息后,会执行Binder对象中的onTransact()函数,

并按照该函数的参数执行不同的代码。因此,要实现一个binder服务,就必须重载onTransact()方法。onTransact()函数的主要内容是

把onTransact()函数的参数转换为服务函数的参数,而onTransact()函数的参数是客户端调用transact()函数时输入的。

任意一个服务端Binder对象被创建时,同时会在Binder驱动中创建一个mRemote对象,

客户端要访问远程服务时,都是通过mRemote对象。binder驱动中transact()的具体实现:

①向服务端线程发送调用消息

②挂起当前线程,等待服务端执行完毕后的通知

③接到通知,继续客户端线程,并返回执行结果。

60. 启动activity的过程中如果调用者被意外杀掉,则startActivity也会不成功。

61. Android studio已下载gradle版本\Android\Android Studio\gradle\m2repository\com\android\tools\build\gradle

62. adb shell getprop dalvik.vm.heapgrowthlimit可以查看系统为每个java进程分配多少heap

63. 这样可检测数据库泄露

StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()

                .detectLeakedSqlLiteObjects()

                .detectLeakedClosableObjects()

                .penaltyLog()

                .penaltyDeath()

                .build());

64. keytool -list -printcert -jarfile xxxx.apk查看apk签名

65. 加密的作用是防止被查看数据,签名的作用是防止被篡改数据

66. 即使申请了静态和动态权限,dirFile.mkdirs()依然返回False,可以在AndroidManifest的Application下添加

android:requestLegacyExternalStorage="true"

67. 有些Android版本的文件名不支持冒号“:”,如果文件命名有冒号,打开文件会提示FileNotFoundException

68. 过滤log

^(?!.*(AAA|BBB)).*$ 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值