android开发小tips

1、android.text.TextUtils这个类就能胜任绝任多数的工作,比如:

text.TextUtils.isEmpty这个方法判断字符串非null且非空,在对字符串进行判断时可以不必if(str!=null && str.length()>0)这样的判断。
public static CharSequence concat(CharSequence… text) 字符串连接。有很多字符串,你还在用+拼接或自己new 一个StringBuffer\StringBuilder么?其实这个方法已经帮我们做好了,用StringBuilder实现,进行字符串拼接时可以考虑使用这个方法。而且支持SpannableString。
public static boolean isDigitsOnly(CharSequence str)
public static boolean equals(CharSequence a, CharSequence b) 判断两个字符串对象的内容是否相等,内部进行了非null判断
public static String htmlEncode(String s) 将html代码中的特殊字符进行转码处理

2、Android.webkit.URLUtile这个工具类。

这里写图片描述

3、Android.text.format.DateUtils这个类是android提供的格式化日期的工具类。

相对于我们经常使用的SimpleDateFormat类来说,DateUtils已经处理好国际化相关的问题,而且还封装了一些很简便的方法。public static String formatDateTime(Context context, long millis, int flags); 这个方法可以格式化日期和时间,接收三个参数,其中第三个参数flags决定输出后的格式,如果只输出日期的话:
DateUtils.formatDateTime(context,millis,DateUtils.FORMAT_SHOW_DATE)
public static boolean isToday(long when) 判断日期是否是今天
public static CharSequence getRelativeTimeSpanString(long startTime) 返回与当前的相对时间的字符串。这样说有些抽象,比如微信的聊天列表上显示的上一条信息的时间,如果是今天就显示今天的时间,是昨天的就显示昨天,再久远一点的就显示日期(但是这个方法的最大只能精确到天,不能像微信那样显示到几秒前,几分钟前)。

4、在Android中引用四大组件和Fragment这些重量级对象的时候要用WeakReference,常用的场景是static Handler持有Activity。
5、、能用简单的布局就用简单的,特别是FrameLayout,它的layout_gravity属性非常好用。
6、BuildConfig.Debug可以判断是不是debug版本,可以通过它来控制一些调试代码,比如debug版本下打日志和测试服务器,release下不打日志,用正式服务器。
7、View可以getContext(),所以在设计方法的时候,参数中如果有View了就别搞Context这个参数了。View还可以post(),有view的时候就别new Handler().post()了。
8、在给Handler发送消息的时候没必要每次都new Message(),而是使用handler.obtainMessage(),它会先看看消息队列里面有没有没用的消息,如果有可以复用消息对象。
9、如果是在应用范围内的广播可以使用LocalBroadcastManager这个API(低版本用v4下的),更加安全高效,不必担心别的app伪造广播或收听你的广播做一些不好的事情。
10、善用Google和StackOverFlow,比百度和CSDN靠谱多了,比如想查下如何从代码中设置TextView的drawLeft属性,google搜索“android textview drawableLeft programmatically”即可,这是搜索到的第一条里面的内容:

这里写图片描述

11、setBackgroundResource(0) 可以移除 View 的背景色
12、Resources.getSystem().getDisplayMetrics().density 可以不用 Context 也能获取屏幕密度哦
13、通过重载 ViewGroup 的 dispatchDraw 可以实现一个简单的蒙版效果。 例如下拉刷新时,可以在 contentView 上加一层遮罩。 canvas.drawRect(0, mContentView.getTranslationY(), getWidth(), getHeight(), mMaskPaint);
14、new 出来的 View 可以用 View.generateViewId() (API 17 以上可用) 生成 id,系统保证唯一
15、在布局文件中,如果只是为了占位,可以用 Space 来取代 View。 最棒的一点是Space可以跳过 Draw 这个过程。
16、TypedValue.applyDimension(int unit, float value, DisplayMetrics metrics) 方便dp, px, sp 之间的转换。
17、TextView.setError() 设置文本框错误提醒
18、PhoneNumberUtils.convertKeypadLettersToDigits 这个方法简单粗暴,会将输入的字母根据键盘上的映射转换为数字
19、ArgbEvaluator ArgbEvaluator.evaluate(float fraction, Object startValue, Object endValue);根据一个起始颜色值和一个结束颜色值以及一个偏移量生成一个新的颜色,分分钟实现类似于微信底部栏滑动颜色渐变。
20、SparseArray 目前有很多地方从性能优化方说使用SparseArray来替换hashMap,来节省内存,提高性能。
21、android.media.ThumbnailUtils这个类主要是用来处理缩略图相关的工作,比如:用来获取媒体(图片、视频)的缩略图;
22、静态变量不要直接或者间接引用Activity、Service等。这会使用Activity以及它所引用的所有对象无法释放,然后,用户操作时间一长,内存就会狂升。
23、Handler机制有一个特点是不会随着Activity、Service的生命周期结束而结束。也就是说,如果你Post了一个Delay的Runnable,然后在Runnable执行之前退出了Activity,Runnable到时间之后还是要执行的。如果Runnable里面包含更新View的操作,程序崩溃了。
24、不少人在子线程中更新View时喜欢使用Context.runOnUiThread,这个方法有个缺点,就是一但Context生命周期结束,比如Activity已经销毁时,一调用就会崩溃。
25、PackageManager.getInstalledPackages这个方法经常使用,你可能不知道,当获取的结果数量比较多的时候,在某些机型上面调用它花费的时间可能秒级的,所以尽量在子线程中使用。另外,如果结果太多,超过系统设置的Binder数据最大传输量的上限,则会发生TransactionException,如果你使用这个方法获取机器上的己安装应用列表,最好做一下预防。
26、如果使用Context.startActivity启动外部应用,最好做一下异常预防,因为寻找不到对应的应用时,会抛出异常。如果你要打开的是应用内的Activity,不防使用显式Intent,这样能提高系统搜索目标Activity的效率。
27、Application的生命周期就是进程的生命周期。只有进程被干掉时,Application才会销毁。哪怕是没有Activity、Service在运行,Application也会存在。所以,为了减少内存压力,尽量不要在Application里面引用大对象、Context等。
28、getWindow().setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);设置全屏方法一定要在setContentView之后
29、判断手机是不是飞行模式

boolean isEnabled = Settings.System.getInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1;

30、遍历HashMap的最佳方法:
public static void printMap(Map mp) {
    Iterator it = mp.entrySet().iterator();
    while (it.hasNext()) {
        Map.Entry pair = (Map.Entry)it.next();
        System.out.println(pair.getKey() + " = " + pair.getValue());
        it.remove(); // avoids a ConcurrentModificationException
    }
}
31、使用Java在一个区间内产生随机整数数
public static int randInt(int min, int max) {
    Random rand = new Random();
    int randomNum = rand.nextInt((max - min) + 1) + min;
    return randomNum;
}
32、如果子类实现Serializable接口而父类未实现时,父类不会被序列化,但此时父类必须有个无参构造方法,否则会抛InvalidClassException异常。
33、transient关键字修饰变量可以限制序列化。
34、当使用JakeWharton的TabPageIndicator时,如果需要先做一些耗时的操作,然后再展示TabPageIndicator的话,需要先设置mIndirector.setVisibility(View.GONE);然后耗时任务结束以后再mIndirector.setVisibility(View.VISIBLE);否则会报错
35、类继承之间的调用顺序 父类static成员 -> 子类static成员 -> 父类普通成员初始化和初始化块 -> 父类构造方法 -> 子类普通成员初始化和初始化块 -> 子类构造方法
36、华为手机无法显示log解决方案,.拨号界面输入(##2846579##) Service menu will appear.Go to “ProjectMenu” -> “Background Setting” -> “Log Setting”Open “Log switch” and set it to ON.Open “Log level setting” and set the log level you wish.
37、后台service经常因为重启之类的出现onStartCommand()中的Intent传递的参数为null, 通过在onStartCommand()中的返回值改成return super.onStartCommand(intent, Service.START_REDELIVER_INTENT, startId); 可以解决问题。下面介绍几个flag的意思:

START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
START_STICKY_COMPATIBILITY START_STICKY:的兼容版本,但不保证服务被kill后一定能重启。

38、不能在Activity没有完全显示时显示PopupWindow和Dialog
39、在多进程之间不要用SharedPreferences共享数据,虽然可以(MODE_MULTI_PROCESS),但极不稳定
40、有些时候不能使用Application的Context,不然会报错(比如启动Activity,显示Dialog等)

这里写图片描述
备注:大家注意看到有一些NO上添加了一些数字,其实这些从能力上来说是YES,但是为什么说是NO呢?下面一个一个解释: 1. 数字1:启动Activity在这些类中是可以的,但是需要创建一个新的task,一般情况不推荐; 2. 数字2:在这些类中去layout inflate是合法的,但是会使用系统默认的主题样式,如果你自定义了某些样式可能不会被使用; 3. 数字3:在Receiver为null时允许,在4.2或以上的版本中,用于获取黏性广播的当前值。(可以无视); 4. ContentProvider、BroadcastReceiver之所以在上述表格中,是因为在其内部方法中都有一个context用于使用。

41、谨慎使用Android的透明主题,透明主题会导致很多问题,比如:如果新的Activity采用了透明主题,那么当前Activity的onStop方法不会被调用;在设置为透明主题的Activity界面按Home键时,可能会导致刷屏不干净的问题;进入主题为透明主题的界面会有明显的延时感
42、不要在非UI线程中初始化ViewStub,否则会返回null
43、尽量不要通过Application缓存数据,这不稳定
44、android listview中的消息被软键盘遮挡了,在设置listview的时候加上android:transcriptMode=”normal”就好了
45、在activity中调用 moveTaskToBack (boolean nonRoot)方法即可将activity 退到后台,注意不是finish()退出。
46、listview有个footerDividersEnabled和headerDividersEnabled方法可以设置listview的顶部和底部divide,但是必须保证你设置了headview和footview才会有效果
47、Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[];StackTraceElement类,其中四个方法getClassName(),getFileName(),getLineNumber(),getMethodName()在调试程序打印Log时非常有用;
48、UncaughtExceptionHandler接口,再好的代码异常难免,利用此接口可以对未捕获的异常善后
49、Resources类中的getIdentifier(name, defType, defPackage)方法,根据资源名称获取其ID,做UI时经常用到;
50、view的isShown方法,只有当view本身以及它的所有祖先们都是visible时,isShown()才返回TRUE。而平常我们调用if(view.getVisibility() == View.VISIBLE)只是对view本身而不对祖先的可见性进行判断
51、Arrays类中的一系列关于数组操作的工具方法:binarySearch(),asList(),equals(),sort(),toString(),copyOfRange()等;Collections类中的一系列关于集合操作的工具方法:sort(),reverse()等;
52、TextView类中的append(CharSequence)方法,添加文本。一些特殊文本直接用+连接会变成String;
53、System类中的arraycopy(src, srcPos, dest, destPos, length)方法,用来copy数组;
54、Fragment类中的onHiddenChanged(boolean)方法,使用FragmentTransaction中的hide(),show()时只会调用Fragment中的show和hidden状态,其他生命周期不会调用。
55、TextView类中的setTransformationMethod(TransformationMethod)方法,可用来实现“显示密码”功能
56、PageTransformer接口,用来自定义ViewPager页面切换动画,用setPageTransformer(boolean, PageTransformer)方法来进行设置;
57、apache提供的一系列jar包:commons-lang.jar,commons-collections.jar,commons-beanutils.jar等,里面很多方法可能是你曾经用几十几百行代码实现过的,但是执行效率或许要差很多,比如:ArrayUtils,StringUtils……;
58、ActivityLifecycleCallbacks接口,用于在Application类中监听各Activity的状态变化
59、SystemClock.sleep() 这个方法在保证一定时间的 sleep 时很方便,通常我用来进行 debug 和模拟网络延时。
60、UrlQuerySanitizer——使用这个工具可以方便对 URL 进行检查。(WebView也可以)
61、ActivityOptions ——方便的定义两个Activity切换的动画。 使用ActivityOptionsCompat 可以很好解决旧版本的兼容问题。
62、getParent().requestDisallowInterceptTouchEvent(true);剥夺父view对touch事件的处理权,谁用谁知道。
63、HandlerThread,代替不停new Thread开子线程的重复体力写法。
64、IntentService,一个可以干完活后自己去死且不需要我们去管理子线程的Service
65、Executors. newSingleThreadExecutor();这个是java的,之前不知道它,自己花很大功夫去研究了单线程顺序执行的任务队列
66、android:animateLayoutChanges=”true”,LinearLayout中添加View的动画的办法,支持通过setLayoutTransition()自定义动画。
67、AsyncQueryHandler,如果做系统工具类的开发,比如联系人短信辅助工具等,肯定免不了和ContentProvider打交道,如果数据量不是很大的情况下,随便搞,如果数据量大的情况下,了解下这个类是很有必要的,需要注意的是,这玩意儿吃异常.
68、android:descendantFocusability,ListView的item中CheckBox等元素抢焦点导致item点击事件无法响应时,除了给对应的元素设置 focusable,更简单的是在item根布局加上android:descendantFocusability=”blocksDescendants”
69、includeFontPadding=”false”,TextView默认上下是有一定的padding的,有时候我们可能不需要上下这部分留白,加上它即可。
70、EditTxt.setImeOptions, 使用EditText弹出软键盘时,修改回车键的显示内容(一直很讨厌用回车键来交互,所以之前一直不知道这玩意儿)
71、java8中新增的LocalDate和LocalTime接口,Date虽然是个万能接口,但是它真的不好用,有了这俩,终于可以愉快的处理日期时间了。
72、WeakHashMap,直接使用HashMap有时候会带来内存溢出的风险,使用WaekHashMap实例化Map。当使用者不再有对象引用的时候,WeakHashMap将自动被移除对应Key值的对象。
73、TouchDelegate可用于更改View的触摸区域。场景:比如在RecyclerView的ItemView里包含了CheckBox组件, 然后想实现点击ItemView的时候,也可以触发CheckBox,就可以使用此类
74、ArgbEvaluator可用于计算不同颜色值之间的插值,配合ValueAnimator.ofObject或者ViewPager.PageTransformer使用,可以实现不同颜色之间的平滑过渡。
75、Palette可用于提取一张图片的颜色。
76、ViewDragHelper,做过自定义ViewGroup的童鞋都应该知道这个东西吧,用来处理触摸事件的神器,妈妈再也不用担心我自定义控件了。
77、Activity.recreate重新创建Activity。有什么用呢?可以在程序更换主题后,立马刷新当前Activity,而不会有明显的重启Activity的动画。
78、View.getContext顾名思义,就不用解释了吧…以前在写RecyclerView的Adapter的时候,为了使用LayoutInflater,经常傻乎乎地在构造函数中传入一个外部的context….是不是只有我不知道而已
79、View.post方便在非UI线程对界面进行修改,与Handler的作用类似。并且由于post的Runnable会保证在该View绘制完成的前提下才调用,所以一般也可以用于获取View的宽高。
80、android:animateLayoutChanges 这是一个非常酷炫的属性。在父布局加上 android:animateLayoutChanges=”true” 后,如果触发了layout方法(比如它的子View设置为GONE),系统就会自动帮你加上布局改变时的动画特效!!
81、android:clipToPadding 设置父view是否允许其子view在它的padding(这里指的是父View的padding)中绘制。是不是有点绕?举个实际场景吧:假如有个ListView,我们想要在初始位置时,第一项Item离顶部有10dp的距离,就可以在ListView的布局中加入android:clipToPadding=”false” android:paddingTop=”10dp”即可。是不是很方便呢?
82、Canvas中clipRect、clipPath和clipRegion剪切区域的API。
83、GradientDrawable 有个阴影效果还不错,以为是切的图片
84、StateListDrawable,定义Selector通常的办法都是xml文件,但是有的时候我们的图片资源可能是从服务器动态获取的,比如很多app所谓的皮肤,这种时候就只能通StateListDrawable来完成了,各种addState即可。
85、android:duplicateParentState=”true”,让子View跟随其Parent的状态,如pressed等。常见的使用场景是某些时候一个按钮很小,我们想要扩大其点击区域的时候通常会再给其包裹一层布局,将点击事件写到Parent上,这时候如果希望被包裹按钮的点击效果对应的Selector继续生效的话,这时候duplicateParentState就派上用场了
86、ViewConfiguration.getScaledTouchSlop();触发移动事件的最小距离,自定义View处理touch事件的时候,有的时候需要判断用户是否真的存在movie,系统提供了这样的方法。
87、onTrimMemory,在Activity中重写此方法,会在内存紧张的时候回调(支持多个级别),便于我们主动的进行资源释放,避免OOM。
88、TextView.setCompoundDrawablePadding,代码设置TextView的drawable padding。
89、ImageSwitcher,可以用来做图片切换的一个类,类似于幻灯片。
90、在自定义控件的时候,能用drawable来绘制圆,或者其他样式的时候,尽量用drawable,因为drawable的效果要远胜于canvas.drawXXX().
91、如果想要自定义View支持SwipeRefreshLayout,只需要声明并实现ScrollingView接口即可,RecyclerView和NestedScrollView已经实现此接口。
92、DatabaseUtils——一个包含各种数据库操作的使用工具。
93、Activity.isChangingConfigurations ()——如果在 Activity 中 configuration 会经常改变的话,使用这个方法就可以不用手动做保存状态的工作了。
94、SearchRecentSuggestionsProvider——可以创建最近提示效果的 provider,是一个简单快速的方法。
95、android:fillViewport (ScrollView)——在这片文章中有详细介绍文章链接,可以解决在 ScrollView 中当内容不足的时候填不满屏幕的问题。
96、android:tileMode (BitmapDrawable)——可以指定图片使用重复填充的模式。
97、android:enterFadeDuration/android:exitFadeDuration (Drawables)——此属性在 Drawable 具有多种状态的时候,可以定义它展示前的淡入淡出效果。
98、使用RenderScript虚化图片效果。如果你的app的minSDK为16或者更低,你需要使用support模式,因为很多方法都是在API 17之后添加的。renderscriptTargetApi最高到23,但是你应该把它设置到能保持脚本中使用到的功能完整的最低API。如果你想在support模式下target API 21+你必须使用gradle-plugin 2.1.0 和 buildToolsVersion “23.0.3” 或者以上。需要在gradle中添加renderscriptTargetApi 18,renderscriptSupportModeEnabled true 这两句话:
public static Bitmap blurBitmap(Context context, Bitmap src, int radius) {
        Bitmap dest = src.copy(src.getConfig(), true);
        RenderScript rs = RenderScript.create(context);
        Allocation allocation = Allocation.createFromBitmap(rs, src);
        Type t = allocation.getType();
        Allocation blurredAllocation = Allocation.createTyped(rs, t);
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        blurScript.setRadius(radius);
        blurScript.setInput(allocation);
        blurScript.forEach(blurredAllocation);
        blurredAllocation.copyTo(dest);
        allocation.destroy();
        blurredAllocation.destroy();
        blurScript.destroy();
        t.destroy();
        rs.destroy();
        return dest;
    }
99、如果想把一个view保存为Bitmap,正常情况下用第一种方法就可以了,但是如果是ScrollView,则必须采用第二种方法。

这里写图片描述
这里写图片描述

100、当Activity LauncherMode 为singleTask singleInstance时,使用startActivityForResult会立马返回,不能正常调用
101、当PopupWindow中有EditText控件时,因为Popupwindow 默认没有获取到焦点,需要手动设置焦点,这样子view才能获取到事件的监听。所以你需要在创建完popwindow后设置他的焦点,popupWindow.setFocusable(true);就可以让EditText获取焦点。
102、PopupWindow默认点击外部的时候不消失,需要对PopupWindow 设置一个背景图popWindow.setBackgroundDrawable(new BitmapDrawable());要创建一个空对象,设置为null是不行的,或者就创建一个全透明的背景图。
103、android中的序列化官方推荐Parceble,其实Parceble最好用于内存之间数据的交换,如果要把数据写入硬盘的话,推荐实现Serializable

tools标签可以很好的帮助开发者实时预览xml的效果,并且运行以后tools标签的内容不会展示出来.例如:

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:text="这段话只在预览时能看到,运行以后就看不到了" />
104、图片的资源文件官方推荐只把launcher放在mipmap文件夹下面,而app用到的资源文件建议放在drawable下面。
105、如果你在 manifest 中把一个 activity 设置成 android:windowSoftInputMode=”adjustResize”,那么 ScrollView(或者其它可伸缩的 ViewGroups)会缩小,从而为软键盘腾出空间。但是,如果你在 activity 的主题中设置了 android:windowFullscreen=”true”,那么 ScrollView 不会缩小。这是因为该属性强制 ScrollView 全屏显示。然而在主题中设置 android:fitsSystemWindows=”false” 也会导致 adjustResize 不起作用
106、Activity的onDestory方法调用时机是不确定的(有时候离开界面很久之后才会调用onDestory方法),应该避免指望通过onDestory方法去释放与Activity相关的资源,否则会导致一些随机bug
107、时间戳请使用long或者String类型接收,遇到的坑,由于项目中的model好多都是通过GsonFormat生成的,服务器给的json中的时间戳都是10位的,导致了GsonFormat自动解析成了int, 当测试人员选择时间为2100年的时候时间戳是4开头的十位 用int类型接收越界了,导致报错
108、为你的app添加默认布局样式,比如:每一个控件都需要写width和height属性,然而很多的控件的宽高属性都是wrap_content,那么我们可以通过在style文件添加如下样式:
<style name="Theme.YourApp" parent="android:style/Theme.Light">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
</style>

这样,控件的宽高默认都是wrap_content样式啦。

109、View类中的getLocationInWindow(int[])方法和getLocationOnScreen(int[])方法,获取View在窗口/屏幕中的位置;
110、Context.getCacheDir() - 可以获取到app默认的缓存路径。
111、StaticLayout 在自定义控件绘制文本的时候很有用。
112、Android中的四大组件千万不要通过new的方式创建出来。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值