1.setOnLongClickListener 返回false会继续触发相关onClick事件,返回true表示事件消费完毕不往下传递。(true if the callback consumed the long click, false otherwise.)
2.gravity
gravity 设置在LinearLayout中,则LinearLayout下所有子控件居住,表示控件内所有部件整体的位置,注意是相对于控件本身
layout_gravity 设置在子控件中,则子控件相对于父控件居中,表示自己在父控件中的位置,注意是相对于父控件
3.Activity生命周期
在调用PopupWindow、Dialog、Toast的时候Activity的生命周期无变化
onNewIntent,Activity设置为singleTask,在当前界面开启当前Activity,onPause->onNewIntent->onResume
4.布局优化
- <include> 布局重用
- <ViewStub />标签最大的优点是当你需要时才会加载,使用他并不会影响UI初始化时的性能。
- <merge/> 可以删减多余的层级,优化UI
merge优化自定义控件,如自定义控件继承Linearlayout,xml布局根布局也是LinearLayout,布局显示为Linearlayout套Linearlayout,可将根布局用merge替代
merge优化fragment根布局处理方案
1.merge替换掉fragment对应layout的根布局
2.onCreateView中View view = inflater.inflate(getViewID(), container, true);处理<merge /> can be used only with a valid ViewGroup root and attachToRoot=true
3.onCreateView返回值为null,处理报错The specified child already has a parent. You must call removeView() on the child's parent first.
include 使用
<include layout="@layout/view_vertical_line"/>
fragment->onCreateView
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
//处理多个fragment界面重叠
container.removeAllViews();
View view = inflater.inflate(getViewID(), container, true);
initFragment();
return null;
}
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/llMain"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/img_main_air_bg"
android:orientation="vertical">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="115px">
</RelativeLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
android:layout_width="212px"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>
<LinearLayout
android:id="@+id/llFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
</LinearLayout>
</LinearLayout>
</LinearLayout>
fragment_main.xml
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="866"
android:orientation="vertical">
<TextView
style="@style/TextTitleStyle"
android:layout_marginTop="@dimen/air_title_margin_top"
android:text="@string/air_title_room_in"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/air_temp_tank_margin_top"
android:layout_marginStart="@dimen/air_temp_tank_margin_left"
android:layout_marginEnd="@dimen/air_temp_tank_margin_left">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_main_show_temp_bg"/>
<TextView
style="@style/TextDescribeStyle"
android:layout_marginTop="@dimen/air_temp_title_margin_top"
android:text="@string/air_temp_in"/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_alignParentEnd="true">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/img_main_show_humidity_bg"/>
<TextView
style="@style/TextDescribeStyle"
android:layout_marginTop="@dimen/air_temp_title_margin_top"
android:text="@string/air_title_room_out"/>
</LinearLayout>
</RelativeLayout>
</LinearLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="842"
android:orientation="vertical">
</LinearLayout>
</merge>
//自定义控件根布局替换成merge,布局引入设置相关属性
View view = LayoutInflater.from(context).inflate(R.layout.layout_time_view, this,true);
setGravity(Gravity.CENTER);
setOrientation(LinearLayout.VERTICAL);
获得ViewStub组件。
<ViewStub
android:id="@+id/stub_import"
android:inflatedId="@+id/panel_import"
android:layout="@layout/progress_overlay"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom" />
跟其他组件一样通过findViewById(R.id.view_stub)获得mViewStub;
显示,有两种方式:
1.直接调用
mViewStub.setVisibility(View.VISIBLE);
2.通过inflate
mStubView = mViewStub.inflate();
两种方式的区别在于通过inflate可以返回引用的布局View,可以通过该引用获得布局View的其他组件。
设置某个布局模块为gone,但是系统在渲染该布局时还是会去计算这个布局模块的宽高等属性,还是会把它添加到布局树上。因此这个布局模块还是会占有渲染布局的部分时间。
而把该布局模块放在ViewStub,系统在渲染该布局时并不会去理ViewStub节点,因此可以节省渲染布局模块的时间。只有当需要展示时,才会去渲染。
ViewStub不支持merge标签,意味着你不能引入包含merge标签的布局到ViewStub中

5.ANR 时间
1:5s内无法响应用户输入事件(例如键盘输入, 触摸屏幕等)
2:BroadcastReceiver在10s内无法结束
3:ServiceTimeout(20s)小概率类型,Service在特定的时间内无法处理完成
6.内存泄漏(Memory Leak是指程序中己动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃(OOM)等严重后果)
举例,Activity回收时出现了比它生命周期长的变量引用了它,导致无法回收,如把Activity的conext传到单例,单例生命周期全局,如Handler中有未处理的消息,导致此刻Handler生命周期长于Activity
7.奇葩bug
后台监控到数据上传没了,第一想法是定时器是不是挂掉了,然后改AlarmManger,还是不行,然后监控发现是上传数据的线程堵住了,特别是短暂断网恢复...
处理方案
1.fixedThreadPool改为cachedThreadPool,新增数据读写超时时间
connector.getSessionConfig().setWriteTimeout(IDLE_TIME/10);
connector.getSessionConfig().setWriterIdleTime(IDLE_TIME/10);
2.mina数据发送添加等待超时时间或者直接注释掉“writeFuture.awaitUninterruptibly(); ”
writeFuture = ioSession.write(data);
//等待发送数据操作完成,可以堵塞线程达到同步的效果,如果不需要发送完成做什么操作就不需要加这行代码
writeFuture.awaitUninterruptibly(); ->writeFuture.awaitUninterruptibly(1000)
private static ThreadPoolExecutor fixedThreadPool;//定长线程池,可控制线程最大并发数,超出的线程会在队列中等待
private static ThreadPoolExecutor cachedThreadPool;//缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程
//创建默认线程池
fixedThreadPool = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>());
cachedThreadPool = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
//控制并发任务
public Future submitFixJob(Runnable r, String param, int priority) {
priorityThreadFactory.setName(r.getClass(), param);
priorityThreadFactory.setPriority(priority);
fixedThreadPool.setThreadFactory(priorityThreadFactory);
Log.d(TAG, "submitFixJob"+fixedThreadPool);
return fixedThreadPool.submit(r);
}
07-15 15:56:41.828 965-1007/com.landleaf.pro D/ThreadPoolManager: submitFixJobjava.util.concurrent.ThreadPoolExecutor@41fa50e0[Running, pool size = 3, active threads = 3, queued tasks = 47, completed tasks = 22]
07-15 15:56:44.108 965-1082/com.landleaf.pro D/ThreadPoolManager: submitFixJobjava.util.concurrent.ThreadPoolExecutor@41fa50e0[Running, pool size = 3, active threads = 3, queued tasks = 48, completed tasks = 22]
07-15 15:57:14.428 965-1082/com.landleaf.pro D/ThreadPoolManager: submitFixJobjava.util.concurrent.ThreadPoolExecutor@41fa50e0[Running, pool size = 3, active threads = 3, queued tasks = 49, completed tasks = 22]
8.bug-> error: failed linking file resources.
- 没有任何其他信息,最后发现是某个未使用的xml布局内部引用图片报错。总结如果有相关信息按照相关信息寻找问题,如果没有就翻看近期修改过的xml等资源文件是否存在报红。
9.DataBinding Kotlin 自定义控件设置某个String属性报错
Cannot find a setter for ..that accepts parameter type 'java.lang.String'
具体情况是没实现对应参数的set方法


详情参考https://blog.csdn.net/qq_43522147/article/details/108609491
10.使用自定义字体发现字体空隙特别大,文字占整体高度的一半左右,设置android:includeFontPadding="false"后恢复正常,该属性为去掉文字的padding

网友评论