● ListView几个有用的属性:
android:divider="@color/transparent" //设置Listview的各个item之间的分割线颜色为透明,也就是不显示分割线
android:listSelector="@android:color/transparent" //设置各个item被点击时的颜色变化,透明则为无变化
android:overScrollMode="never" //设置Listview下拉时顶部不出现半月形的阴影
● 调用下面的代码可收起虚拟键盘:
InputMethodManager im = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (null != im) {
im.hideSoftInputFromWindow(getCurrentFocus().getApplicationWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
● 当ScrollView里的元素想填满ScrollView时,使用”fill_parent”或者”match_parent”是不管用的,必需为ScrollView设置:android:fillViewport=”true”。
当ScrollView没有fillVeewport=“true”时, 里面的元素(比如LinearLayout)会按照wrap_content来计算(不论它是否设了”fill_parent”或者”match_parent”)。
● RadioButton在动态调用setChecked()的时候可能会不生效。具体表现为值已经改过来了,但是选中状态并没有变。可以调用RadioGroup.clearCheck()后再调用RadioButton的setChecked()方法就好了。
但是更好的办法是用RadioGroup.check(RadioButton.getId())的方法设置选中的RadioButton。
● 项目中有次release版本解析json出错,原因如下:用Google的Gson库解析json字符串为指定的对象时,要在该对象的定义类的各个属性值前加上@SerializedName标注。不加可能出错。加上后的属性如下:
@SerializedName("day")
private int day;
● 限制屏幕方向时,android:screenOrientation属性不要写在自定义的style里,否则用android:theme给activity指定屏幕方向可能会失效(测试机型为android4.4)。在manifest文件具体的activity下配置此属性就正常了。
● 给TextView动态设置文本时,如果文本是int型的数字a,不能直接setText(a),因为这样a会被当作resourceId而报ResourceNotFoundException。
● IntentService是一个异步的Service,会在该Service里用Handler创建一个线程做处理,处理完成后
会停止该线程并终止该Service。
● 使用IntentService必须创建一个无参的构造方法,否则会报错。
无参构造方法示例如下:
public MyIntentService() {
super("MyIntentService");
}
● 创建IntentService的时候,不要重写onStartCommand()方法,重写可能导致出错。
要重写的是onHandleIntent()方法。
● 连续多次调用bindService()并不会多次创建和绑定Service,即不会多次调用该服务的onCreate()和onBind()方法。
● 如果Service已经取消了绑定,那么再次调用unBindService()时就会报错java.lang.IllegalArgumentException: Service not registered。因此调用unBindService()最好做判断,可以用一个flag做为绑定或者解绑定的标志。
● 连续多次调用startService()也不会多次调用该服务的onCreate()方法,但会连续调用多次该服务的onStartCommand()方法。
● ServiceConnection的onServiceDisconnected()方法正常情况下是不会被调用的。只有该Service被意外断开连接时会调用。
● BroadcaseReceiver的onReceive()方法里的处理不能时间太长,一般超过10s会发生ANR。
● 如果一个layout里包含了ImageButton, 在给这个layout设置点击事件时,如果ImageButton不同时设置点击事件,那么点击事件可能在ImageButton上失效。解决办法是给ImageButton设置属性android:clickable=”false”。这样点击事件就只由该layout处理了。
如果要给layout和ImageButton设置不同的点击事件,可以把ImageButton换成ImageView。
● 一般来说在工作线程中执行耗时任务,当任务完成时,会返回UI线程,一般是更新UI。这时有两种方法可以达到目的。
一种是handler.sendMessage。发一个消息,再根据消息,执行相关任务代码。
另一种是handler.post(r)。r是要执行的任务代码。意思就是说r的代码实际是在UI线程执行的。可以写更新UI的代码。(工作线程是不能更新UI的)
- 1 在子线程中利用post(Runnable r)更新UI,原理和sendMessage()类似.
- 2 所以“在子线程中利用post(Runnable r)更新UI”这个说法不是特别准确.
- 确切地说还是在子线程中发送了消息到主线程的消息队列从而更新了UI.
- 3 调用post(Runnable r)不会开启一个新的线程,UI的更新是在主线程中完成的!!!!!!!!!!
- 所以在post方法中勿做耗时操作.
● 如果在MainActivity中启动SecondActivity的同时,MainActivity通过调用finish()方法结束了自身,那么SecondActivity返回时就不会返回MainActivity了,而是直接退出应用。
● Activity的isFinishing()方法可以判断activity是不是正在结束,一般可以在onPause()中用,用来确定activity是被调用了finish()或者其它方法主动销毁而调用onPause(),还是返回后台而调用onPause()。
● 重写onKeyDown()方法时,可以返回true或者false。返回true表示“我已经处理完了,不再需要调用父类的onKeyDown()方法”,返回false表示“我还没处理完,会调用父类的onKeyDown()继续处理。”
● activity里弹出Dialog时,并不会调用onPause(),Dialog取消时也不会调用onResume()。只有activity被其它应用遮盖时才会调用onPause()。
● onUserLeaveHint() 用户手动离开当前activity,会调用该方法,比如用户主动切换任务,按back键,短按home进入桌面等。启动本应用的其它activity时也会调用此方法。
而系统自动切换应用时不会调用此方法,如来电,灭屏等。finish()方法运行后也不会调用此方法。
● 下面的代码可以实现布局延伸到statusBar和NevigationBar下面,比如在华为手机上,不管NevigationBar是显示还是隐藏,页面布局都不会变,会被statusBar和NevigationBar遮住。
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
● 沉浸式状态栏:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
}
● 使用onActivityResult(int requestCode, int resultCode, Intent data))时要注意,如果启动的activity返回时没有调用setResult(int resultCode), 则onActivityResult()里传入的resultCode为0。
● List的addAll()方法不能传入null,否则会报空指针异常。因此在传参之前要判断非空。
● 用循环给一个List添加元素时,像这样的添加是不对的:
List<Element> mList = new ArrayList<>();
Element tmpElement = new Element();
for(i = 0; i < 10; i++) {
tmpElement.setId(i);
mList.add(tmpElement);
}
这样添加之后,mList 会有10个Element 元素,但是其id全都是9。因为每一次循环都会更新已添加到mList中的tmpElement的Id值。正确的做法可以在每次循环都new一个tmpElement然后添加。
● 项目中用到了android-async-http库,原本是以http的方式访问服务器,现在要支持https,做修改的时候,把代码做如下修改即可:
// private static AsyncHttpClient client = new AsyncHttpClient();
private static AsyncHttpClient client = new AsyncHttpClient(true, 80, 443);
这样修改表示客户端会信任所有的证书(不止是信任自己的服务器)。
● 修改项目包名时有个注意点:在 Studio 里面我们的 getPackageName 对应的是 applicationId , 而manifest 的那个package,在这里的作用其实是为了引用内部资源文件,以及保证 Activity 等源文件的路径正确而已,所以,如果只是为了修改程序包名,则只需要在 build.gradle 文件中修改 applicationId 就可以了。但是要注意如果用到了第三方sdk,比如用高德地图的sdk时用的还是旧的包名,那么要重新接入新的包名。
● .9图可实现随内容自动拉伸的效果,制作时,可以把png图片放到drawable文件夹下,然后把后缀改为.9.png,然后用Android studio打开,即可进行编辑。
通过编辑其上、左边界,可定义图片进行拉伸的部分,编辑其右、下边界,可定义内容显示的部分。
● NotificationManager.notify()和Service的startForeground()方法都可以显示一个notification,但是startForeground方法的意义在于可以把service变成前台服务,提升服务优先级。
● 给Android布局或者文本通过SetBackgroundResource()设置背景图时,经常出现图片被拉伸的情况。可以通过下面的方法解决:
drawable文件夹下新建一个xml文件,比如命名为xml_layout_bg.xml,内容如下:
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:gravity="center"
android:src="@drawable/layout_bg"
android:tileMode="disabled">
</bitmap>
其中layout_bg.png为背景图。然后调用setBackgroundResource(R.drawable.xml_layout_bg)设置背景即可。
● 监听屏幕亮灭变化时,可以注册监听三个系统广播:
Intent.ACTION_SCREEN_ON
Intent.ACTION_SCREEN_OFF
Intent.ACTION_USER_PRESENT
其中前两个需要在代码中动态注册才能监听,而Intent.ACTION_USER_PRESENT静态注册或者动态注册都能监听到。如果同时进行了静态注册和动态注册,则广播接收器会收到两次。