任務(wù)
- 解決加載WebView屏幕會閃動
- 解決ANR問題
- 提問需求優(yōu)化
解決加載WebView屏幕會閃動
出現(xiàn)場景: WebView嵌套在ScrollView中,當(dāng)WebView不可見的時候蛛砰,加載完url后娃肿,再設(shè)置可見咕缎,就可出現(xiàn)屏幕布局會閃動
解決
在需要顯示W(wǎng)ebView的地方,先把WebView顯示出來再加載url, 如果在webview不可見的時候加載url, 當(dāng)設(shè)置WebView可見的時候料扰,<u style="-webkit-tap-highlight-color: transparent; line-height: 22.4px; box-sizing: content-box;">它的高度會是一個很大的值,目前還不知道原因</u>...
解決ANR問題
- 距離傳感器引起的ANR
上個星期導(dǎo)出了測試小姐姐的手機凭豪,看了ANR日記,發(fā)現(xiàn)距離傳感器回調(diào)的時候會有ANR晒杈,但是那時候覺得是其它的問題導(dǎo)致的嫂伞,就沒有過多的關(guān)注,這個星期測試那邊又遇到ANR問題了拯钻,而且又是在監(jiān)聽傳感器界面帖努,所以和同事一起分析了一下這個問題
先看日記
"main" prio=5 tid=1 Native
| group="main" sCount=1 dsCount=0 flags=1 obj=0x752b5050 self=0xf0d44000
| sysTid=24817 nice=-10 cgrp=default sched=0/0 handle=0xf5572494
| state=S schedstat=( 13809870839 1897535961 16257 ) utm=1153 stm=227 core=3 HZ=100
| stack=0xff2f5000-0xff2f7000 stackSize=8MB
| held mutexes=
kernel: (couldn't read /proc/self/task/24817/stack stderr:Permission denied)
native: #00 pc 0005597c /system/lib/libc.so (__ioctl+8)
native: #01 pc 00022593 /system/lib/libc.so (ioctl+38)
native: #02 pc 0004c40b /system/lib/libbinder.so (android::IPCThreadState::talkWithDriver(bool)+206)
native: #03 pc 0004d223 /system/lib/libbinder.so (android::IPCThreadState::waitForResponse(android::Parcel*, int*)+26)
native: #04 pc 0004cf71 /system/lib/libbinder.so (android::IPCThreadState::transact(int, unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+164)
native: #05 pc 00045d21 /system/lib/libbinder.so (android::BpBinder::transact(unsigned int, android::Parcel const&, android::Parcel*, unsigned int)+36)
native: #06 pc 000cc48b /system/lib/libandroid_runtime.so (android_os_BinderProxy_transact(_JNIEnv*, _jobject*, int, _jobject*, _jobject*, int)+306)
at android.os.BinderProxy.transactNative(Native method)
at android.os.BinderProxy.transact(Binder.java:1149)
at android.media.IAudioService$Stub$Proxy.setMode(IAudioService.java:1445)
at android.media.AudioManager.setMode(AudioManager.java:1890)
at 公司包名.activities.ChatActivityV2.changeAudioType(ChatActivityV2.java:2848)
at 公司包名.activities.ChatActivityV2.access$3200(ChatActivityV2.java:179)
at 公司包名.activities.ChatActivityV2$42.onSensorChanged(ChatActivityV2.java:2826)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:862)
at android.os.MessageQueue.nativePollOnce(Native method)
at android.os.MessageQueue.next(MessageQueue.java:386)
at android.os.Looper.loop(Looper.java:175)
at android.app.ActivityThread.main(ActivityThread.java:7625)
at java.lang.reflect.Method.invoke(Native method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:524)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987)
這里的changeAudioType就是頻繁的調(diào)用AudioManager來切換聽筒和揚聲器
首先加這個傳感器是為了在視頻通話的時候,進(jìn)行聽筒和揚聲器切換的粪般,就是當(dāng)用戶把手機放在耳朵旁邊的時候切換為聽筒模式拼余,離開的時候又切換為揚聲器(微信也是有這個功能的)
但是我們項目這個功能只是實現(xiàn)了一半,只要有東西擋住手機就會回調(diào)亩歹,所以如果用戶平放匙监,然后點擊返回鍵的時候也是會觸發(fā)這個回調(diào), <u style="-webkit-tap-highlight-color: transparent; line-height: 22.4px; box-sizing: content-box;">很奇怪就是報這個ANR問題的都是華為的手機</u>
解決
加上旋轉(zhuǎn)傳感器來判斷當(dāng)前屏幕旋轉(zhuǎn)的方向,來判斷只有當(dāng)手機拿起小作,而且是東西靠近手機的時候才設(shè)置為聲筒模式亭姥,離開手機的時候就設(shè)置為揚聲器模式
代碼
private SensorEventListener sensorListener = new SensorEventListener() {
@Override
public void onSensorChanged(SensorEvent event) {
//如果用戶手機設(shè)置了聽筒模式,或者用戶當(dāng)前沒有在視頻 就不執(zhí)行
if (ImSpUtils.isHeadphoneMode() || !MeetingStateUtils.isOnMeeting()) return;
if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR){
float x = Math.abs(event.values[0]);
if (x >= Math.sin(Math.PI*minDegree/180)){
pickupPhone = true;
}else {
pickupPhone = false;
}
}else if (event.sensor.getType() == Sensor.TYPE_PROXIMITY){
float distance = event.values[0];
float maxRange = event.sensor.getMaximumRange();
float threshold = Math.min(maxRange, 3);
if (mAudioManager.isSpeakerphoneOn()){
if (pickupPhone && distance < threshold){
changeAudioType(true);
}
}else{
if (distance >= threshold){
changeAudioType(false);
}
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
};
//注冊兩個傳感器
mSensorManager.registerListener(sensorListener, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
mSensorManager.registerListener(sensorListener, mRotationSensor, SensorManager.SENSOR_DELAY_NORMAL);
- RecyclerView嵌套ScrollView引起的ANR
根據(jù)Bugly 出錯堆棧和跟蹤數(shù)據(jù)分析得到躲惰,項目里面某個功能模塊會引起ANR,看了一下布局發(fā)現(xiàn)是RecyclerView嵌套ScrollView引起的
RecyclerView如果是內(nèi)容少的話嵌套ScrollView也沒什么問題致份,問題是RecyclerView這里使用了分頁加載,數(shù)據(jù)量很大础拨,當(dāng)用戶頻繁在這個界面交互的時候就容易造成ANR
使用itemType來添加RecyclerView頭部氮块,達(dá)到整體滑動的效果
提問優(yōu)化
- 使用StaggeredGridLayoutManager實現(xiàn)瀑布流的效果
如果要讓某一個item點多列
StaggeredGridLayoutManager.LayoutParams layoutParams = (StaggeredGridLayoutManager.LayoutParams) viewHolder.itemView.getLayoutParams();
layoutParams.setFullSpan(true);
- 雙擊處理
使用時間差
private static long lastClickTime=0;
private static final int CLICK_TIME = 500; //快速點擊間隔時間
// 判斷按鈕是否快速點擊
public static boolean isFastClick() {
long time = System.currentTimeMillis();
if (time - lastClickTime < CLICK_TIME) {//判斷系統(tǒng)時間差是否小于點擊間隔時間
return true;
}
lastClickTime = time;
return false;
}
- 使用聲網(wǎng)SDK,來實現(xiàn)在線視頻聊天功能
小結(jié)
- 通過WebView回調(diào)java代碼獲取WebView高度
在onPageFinished方法中執(zhí)行js方法回調(diào)
class WebClient extends WebViewClient {
@Override
public void onPageFinished(WebView view, String url) {
view.loadUrl("javascript:AndroidFunction.resize(document.body.scrollHeight)");
}
}
}
- MeasureSpec的三個模式
MeasureSpec.EXACTLY - 精確模式 View的大小已經(jīng)確定,為SpecSize指定的值
MeasureSpec.AT_MOST - 表示子View的大小不確定诡宗,指定了該子View最大能為多少滔蝉,子View可以在指定的范圍內(nèi)設(shè)定自己的大小
MeasureSpec.UNSPECIFIED - 父容器不對子View有任何限制,子View要多大給多大,這樣一般我們不會碰到(ScrollView)。
使用傳感器可以實現(xiàn)全景效果
隱藏軟鍵盤
public static void hideKeyboard(View view){
InputMethodManager imm = (InputMethodManager) view.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(view.getWindowToken(),0);
}
}