shouldOverrideUrlLoading在次回调函数里判断getHitTestResult是不是为空来过滤自动跳转url,因为用户点击跳转的url获取的WebHitTestResult对象是不为空的。实例代码:
<pre name="code" class="java">/** * 左上角和回退按键的点击:true为退出应用,false为回退到上一页 */ private boolean setBackFinish = true; private String lastRedirectUrl; private long lastRedirectTime = 0; private Map<String, Long> redirectUrls = new HashMap<>();
</pre><pre name="code" class="java">//被点击的是链接或者自动跳转时,此方法被调用 @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { AppLog.d("WebViewClient shouldOverrideUrlLoading " + url); if (url == null) { AppLog.i("override url is null"); return true; } WebView.HitTestResult hitTestResult = wView.getHitTestResult(); if (hitTestResult != null) { AppLog.e("shouldOverrideUrlLoading has a hittest: " + hitTestResult.getExtra() + " " + hitTestResult.getType()); } else { //没有点击说明是跳转url WebActivity.this.redirectUrls.put(WebActivity.this.lastRedirectUrl, WebActivity.this.lastRedirectTime); } //记录跳转网页url和时间 WebActivity.this.lastRedirectUrl = url; WebActivity.this.lastRedirectTime = SystemClock.currentThreadTimeMillis(); if (URLUtil.isNetworkUrl(url)) { view.loadUrl(url);// 在当前的webview中跳转到新的url return false; } }
回退处理:
@Override public void onBackPressed() { if (willFinish()) super.onBackPressed(); } @Override protected boolean willFinish() { if (!wView.canGoBack() || setBackFinish) { return true; } //wifi网速优时,根据页面停留时间长短过滤中间页 WebBackForwardList list = wView.copyBackForwardList(); int i = list.getCurrentIndex(); for (; i > 0; i--) { String url = list.getItemAtIndex(i).getUrl(); if (!redirectUrls.containsKey(url) && !url.equals(wView.getUrl())) { //找到一个非跳转url,回退到此 wView.goBackOrForward(-(list.getCurrentIndex() - i)); return false; } else if (i == 1) { //没找到合适的非跳转url,直接跳转到首页 wView.goBackOrForward(-list.getCurrentIndex()); return false; } } return true; }
2,android studio混淆
1),在build.grandle添加,其中规则写在proguard-rules.pro中,也可以自定义一个文件,将其代替,比如eclipse常用的 proguard-project.txt
2),在proguard-rules.pro中加入以下代码,基本可以涵盖所有buildTypes { release { signingConfig signingConfigs.release minifyEnabled true proguardFiles getDefaultProguardFile(‘proguard-android.txt‘), ‘proguard-rules.pro‘ } }
3),通过 Android Studio进行 混淆代码时,默认已经将 lib目录中的 jar 都已经添加到打包脚本中,所以不需要再次手动添加,否则会出现“ java.io.IOException: The same input jar is specified twice” 错误。-optimizationpasses 5 # 指定代码的压缩级别 -dontusemixedcaseclassnames # 是否使用大小写混合 -dontpreverify # 混淆时是否做预校验 -verbose # 混淆时是否记录日志 -optimizations !code/simplification/arithmetic,!field/*,!class/merging/* # 混淆时所采用的算法 -keep public class * extends android.app.Activity # 保持哪些类不被混淆 -keep public class * extends android.app.Application # 保持哪些类不被混淆 -keep public class * extends android.app.Service # 保持哪些类不被混淆 -keep public class * extends android.content.BroadcastReceiver # 保持哪些类不被混淆 -keep public class * extends android.content.ContentProvider # 保持哪些类不被混淆 -keep public class * extends android.app.backup.BackupAgentHelper # 保持哪些类不被混淆 -keep public class * extends android.preference.Preference # 保持哪些类不被混淆 -keep public class com.android.vending.licensing.ILicensingService # 保持哪些类不被混淆 -keepclasseswithmembernames class * { # 保持 native 方法不被混淆 native <methods>; } -keepclasseswithmembers class * { # 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet); } -keepclasseswithmembers class * {# 保持自定义控件类不被混淆 public <init>(android.content.Context, android.util.AttributeSet, int); } -keepclassmembers class * extends android.app.Activity { # 保持自定义控件类不被混淆 public void *(android.view.View); } -keepclassmembers enum * { # 保持枚举 enum 类不被混淆 public static **[] values(); public static ** valueOf(java.lang.String); } -keep class * implements android.os.Parcelable { # 保持 Parcelable 不被混淆 public static final android.os.Parcelable$Creator *; }
3,比较完整的Activity和Fragment生命周期图(非官方):
原图参照:https://github.com/xxv/android-lifecycle
4,scrollview(listview...)的overscrollmode属性: always(默认值,总是允许过滚动)、never(只有当视图可以滚动时,才可以设置视图的过滚动模式)、if_content_scrolls(视图内容大于容器时允许过滚动)。这个属性主要设置的是当滚动条滑动到边界的时候,如果再滑动,就会有一个边界就会有一个发光效果,即边界回弹。
5,android配置中的category讲解
CATEGORY_ALTERNATIVE
设置这个activity是否可以被认为是用户正在浏览的数据的一个可选择的action
CATEGORY_APP_BROWSER
和ACTION_MAIN一起使用,用来启动浏览器应用程序
CATEGORY_APP_CALCULATOR
和ACTION_MAIN一起使用,用来启动计算器应用程序
CATEGORY_APP_CALENDAR
和ACTION_MAIN一起使用,用来启动日历应用程序
CATEGORY_APP_CONTACTS
和ACTION_MAIN一起使用,用来启动联系人应用程序
CATEGORY_APP_EMAIL
和ACTION_MAIN一起使用,用来启动邮件应用程序
CATEGORY_APP_GALLERY
和ACTION_MAIN一起使用,用来启动图库应用程序
CATEGORY_APP_MAPS
和ACTION_MAIN一起使用,用来启动地图应用程序
CATEGORY_APP_MARKET
这个activity允许用户浏览和下载新的应用程序
CATEGORY_APP_MESSAGING
和ACTION_MAIN一起使用,用来启动短信应用程序
CATEGORY_APP_MUSIC
和ACTION_MAIN一起使用,用来启动音乐应用程序
CATEGORY_BROWSABLE
能够被浏览器安全调用的activity必须支持这个category
CATEGORY_DEFAULT
设置这个activity对于默认的action是否是一个可选的
CATEGORY_EMBED
可以运行在父activity容器内
CATEGORY_HOME
主activity,当应用程序启动时,它是第一个显示的activity
CATEGORY_LAUNCHER
应该在上层的启动列表里显示
CATEGORY_MONKEY
这个activity可能被monkey或者其他的自动测试工具执行
CATEGORY_OPENABLE
用来指示一个GET_CONTENT意图只希望ContentResolver.openInputStream能够打开URI
CATEGORY_PREFERENCE
这个activity是一个选项卡
CATEGORY_SAMPLE_CODE
作为一个简单的代码示例使用(一般情况下不使用)
CATEGORY_SELECTED_ALTERNATIVE
设置这个activity是否可以被认为是用户当前选择的数据的一个可选择的action
CATEGORY_TAB
想要在已有的TabActivity内部作为一个Tab使用
CATEGORY_TEST
供测试使用(一般情况不使用)
CATEGORY_UNIT_TEST
联合测试使用
6,使用Message.obtain(Handler h, int what,int arg1, int arg2, Object obj)比Handler实例创建Message方便
7,计算两个颜色的中间色方法
/**
* Blend {@code color1} and {@code color2} using the given ratio.
*
* @param ratio of which to blend. 1.0 will return {@code color1}, 0.5 will give an even blend,
* 0.0 will return {@code color2}.
*/
private static int blendColors(int color1, int color2, float ratio) {
final float inverseRation = 1f - ratio;
float r = (Color.red(color1) * ratio) + (Color.red(color2) * inverseRation);
float g = (Color.green(color1) * ratio) + (Color.green(color2) * inverseRation);
float b = (Color.blue(color1) * ratio) + (Color.blue(color2) * inverseRation);
return Color.rgb((int) r, (int) g, (int) b);
}
8,类成员变量访问权限表
成员权限 | public | protected | private | 默认(包访问) |
---|---|---|---|---|
本类 | √ | √ | √ | √ |
子类 | √ | √ | ||
包内 | √ | √ | √ | |
外部 | √ |
默认亦为friendly
9,android多国语言文件夹文件汇总如下:
中文(中国):values-zh-rCN
中文(台湾):values-zh-rTW
中文(香港):values-zh-rHK
英语(美国):values-en-rUS
英语(英国):values-en-rGB
英文(澳大利亚):values-en-rAU
英文(加拿大):values-en-rCA
英文(爱尔兰):values-en-rIE
英文(印度):values-en-rIN
英文(新西兰):values-en-rNZ
英文(新加坡):values-en-rSG
英文(南非):values-en-rZA
阿拉伯文(埃及):values-ar-rEG
阿拉伯文(以色列):values-ar-rIL
保加利亚文: values-bg-rBG
加泰罗尼亚文:values-ca-rES
捷克文:values-cs-rCZ
丹麦文:values-da-rDK
德文(奥地利):values-de-rAT
德文(瑞士):values-de-rCH
德文(德国):values-de-rDE
德文(列支敦士登):values-de-rLI
希腊文:values-el-rGR
西班牙文(西班牙):values-es-rES
西班牙文(美国):values-es-rUS
芬兰文(芬兰):values-fi-rFI
法文(比利时):values-fr-rBE
法文(加拿大):values-fr-rCA
法文(瑞士):values-fr-rCH
法文(法国):values-fr-rFR
希伯来文:values-iw-rIL
印地文:values-hi-rIN
克罗里亚文:values-hr-rHR
匈牙利文:values-hu-rHU
印度尼西亚文:values-in-rID
意大利文(瑞士):values-it-rCH
意大利文(意大利):values-it-rIT
日文:values-ja-rJP
韩文:values-ko-rKR
立陶宛文:valueslt-rLT
拉脱维亚文:values-lv-rLV
挪威博克马尔文:values-nb-rNO
荷兰文(比利时):values-nl-BE
荷兰文(荷兰):values-nl-rNL
波兰文:values-pl-rPL
葡萄牙文(巴西):values-pt-rBR
葡萄牙文(葡萄牙):values-pt-rPT
罗马尼亚文:values-ro-rRO
俄文:values-ru-rRU
斯洛伐克文:values-sk-rSK
斯洛文尼亚文:values-sl-rSI
塞尔维亚文:values-sr-rRS
瑞典文:values-sv-rSE
泰文:values-th-rTH
塔加洛语:values-tl-rPH
土耳其文:values--r-rTR
乌克兰文:values-uk-rUA
越南文:values-vi-rVN
10,如果你要进行一个获取两者中最大值的操作,使用if else比较后再赋值的方法不如 result=a & b 方便,这也是java官方推荐的一种方式。